| | @@ -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 | | -** 555f31c64d3fcc55df2715a7c8c1cb28503b with changes in files: |
| 21 | +** 92709f54d4c58cf174f305b58971a01878af 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-08-27 10:58:16 555f31c64d3fcc55df2715a7c8c1cb28503b2c0eb21d950ccdcbf6f577593dd5" |
| 472 | +#define SQLITE_SOURCE_ID "2026-10-01 11:21:02 92709f54d4c58cf174f305b58971a01878af313157a11549b588a25216701f5c" |
| 473 | 473 | #define SQLITE_SCM_BRANCH "trunk" |
| 474 | 474 | #define SQLITE_SCM_TAGS "" |
| 475 | | -#define SQLITE_SCM_DATETIME "2026-08-27T10:58:16.680Z" |
| 475 | +#define SQLITE_SCM_DATETIME "2026-10-01T11:21:02.802Z" |
| 476 | 476 | |
| 477 | 477 | /* |
| 478 | 478 | ** CAPI3REF: Run-Time Library Version Numbers |
| 479 | 479 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 480 | 480 | ** |
| | @@ -3842,10 +3842,15 @@ |
| 3842 | 3842 | ** authorizer callback is the name of the database ("main", "temp", |
| 3843 | 3843 | ** etc.) if applicable.)^ ^The 6th parameter to the authorizer callback |
| 3844 | 3844 | ** is the name of the inner-most trigger or view that is responsible for |
| 3845 | 3845 | ** the access attempt or NULL if this access attempt is directly from |
| 3846 | 3846 | ** top-level SQL code. |
| 3847 | +** |
| 3848 | +** The case of strings in the 3rd through the 6th argument to the |
| 3849 | +** authorization callback is arbitrary. Authorization callbacks |
| 3850 | +** implementations should use [sqlite3_stricmp()] or similar when |
| 3851 | +** doing comparisons against those values. |
| 3847 | 3852 | */ |
| 3848 | 3853 | /******************************************* 3rd ************ 4th ***********/ |
| 3849 | 3854 | #define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */ |
| 3850 | 3855 | #define SQLITE_CREATE_TABLE 2 /* Table Name NULL */ |
| 3851 | 3856 | #define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */ |
| | @@ -17208,10 +17213,14 @@ |
| 17208 | 17213 | #endif |
| 17209 | 17214 | |
| 17210 | 17215 | #if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) |
| 17211 | 17216 | SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager*); |
| 17212 | 17217 | #endif |
| 17218 | + |
| 17219 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) |
| 17220 | +SQLITE_PRIVATE void sqlite3PagerWalStat(Pager*,sqlite3_str*); |
| 17221 | +#endif |
| 17213 | 17222 | |
| 17214 | 17223 | #endif /* SQLITE_PAGER_H */ |
| 17215 | 17224 | |
| 17216 | 17225 | /************** End of pager.h ***********************************************/ |
| 17217 | 17226 | /************** Continuing where we left off in sqliteInt.h ******************/ |
| | @@ -18590,11 +18599,11 @@ |
| 18590 | 18599 | */ |
| 18591 | 18600 | #if !SQLITE_THREADSAFE |
| 18592 | 18601 | # define SQLITE_MUTEX_OMIT |
| 18593 | 18602 | #endif |
| 18594 | 18603 | #if SQLITE_THREADSAFE && !defined(SQLITE_MUTEX_NOOP) |
| 18595 | | -# if SQLITE_OS_UNIX |
| 18604 | +# if SQLITE_OS_UNIX || defined(__CYGWIN__) |
| 18596 | 18605 | # define SQLITE_MUTEX_PTHREADS |
| 18597 | 18606 | # elif SQLITE_OS_WIN |
| 18598 | 18607 | # define SQLITE_MUTEX_W32 |
| 18599 | 18608 | # else |
| 18600 | 18609 | # define SQLITE_MUTEX_NOOP |
| | @@ -22645,11 +22654,20 @@ |
| 22645 | 22654 | #endif |
| 22646 | 22655 | |
| 22647 | 22656 | SQLITE_PRIVATE const char *sqlite3ErrStr(int); |
| 22648 | 22657 | SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); |
| 22649 | 22658 | SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); |
| 22659 | +SQLITE_PRIVATE int sqlite3BinaryCompare(void*,int,const void*,int,const void*); |
| 22660 | +#if SQLITE_USES_INLINE |
| 22661 | +static SQLITE_INLINE int sqlite3IsBinary(const CollSeq *p){ |
| 22662 | + assert( p==0 || p->xCmp!=sqlite3BinaryCompare |
| 22663 | + || strcmp(p->zName,"BINARY")==0 ); |
| 22664 | + return p==0 || p->xCmp==sqlite3BinaryCompare; |
| 22665 | +} |
| 22666 | +#else |
| 22650 | 22667 | SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq*); |
| 22668 | +#endif |
| 22651 | 22669 | SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); |
| 22652 | 22670 | SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8); |
| 22653 | 22671 | SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr); |
| 22654 | 22672 | SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr); |
| 22655 | 22673 | SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,const Expr*,const Expr*); |
| | @@ -25965,10 +25983,11 @@ |
| 25965 | 25983 | if( ms>0.999 ) ms = 0.999; |
| 25966 | 25984 | } |
| 25967 | 25985 | }else{ |
| 25968 | 25986 | s = 0; |
| 25969 | 25987 | } |
| 25988 | + if( h==24 && (m!=0 || s!=0 || ms!=0.0) ) return 1; |
| 25970 | 25989 | p->validJD = 0; |
| 25971 | 25990 | p->rawS = 0; |
| 25972 | 25991 | p->validHMS = 1; |
| 25973 | 25992 | p->h = h; |
| 25974 | 25993 | p->m = m; |
| | @@ -26001,10 +26020,14 @@ |
| 26001 | 26020 | D = p->D; |
| 26002 | 26021 | }else{ |
| 26003 | 26022 | Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */ |
| 26004 | 26023 | M = 1; |
| 26005 | 26024 | D = 1; |
| 26025 | + if( p->validHMS && p->h==24 ){ |
| 26026 | + p->h = 0; |
| 26027 | + D = 2; |
| 26028 | + } |
| 26006 | 26029 | } |
| 26007 | 26030 | if( Y<-4713 || Y>9999 || p->rawS ){ |
| 26008 | 26031 | datetimeError(p); |
| 26009 | 26032 | return; |
| 26010 | 26033 | } |
| | @@ -26039,10 +26062,14 @@ |
| 26039 | 26062 | */ |
| 26040 | 26063 | static void computeFloor(DateTime *p){ |
| 26041 | 26064 | assert( p->validYMD || p->isError ); |
| 26042 | 26065 | assert( p->D>=0 && p->D<=31 ); |
| 26043 | 26066 | assert( p->M>=0 && p->M<=12 ); |
| 26067 | + if( p->validHMS && p->h==24 ){ |
| 26068 | + p->h = 0; |
| 26069 | + p->D++; |
| 26070 | + } |
| 26044 | 26071 | if( p->D<=28 ){ |
| 26045 | 26072 | p->nFloor = 0; |
| 26046 | 26073 | }else if( (1<<p->M) & 0x15aa ){ |
| 26047 | 26074 | p->nFloor = 0; |
| 26048 | 26075 | }else if( p->M!=2 ){ |
| | @@ -31422,12 +31449,15 @@ |
| 31422 | 31449 | # define ALIGN128 __declspec(align(128)) |
| 31423 | 31450 | #else |
| 31424 | 31451 | # define ALIGN128 |
| 31425 | 31452 | #endif |
| 31426 | 31453 | |
| 31454 | +#ifdef _MSC_VER |
| 31427 | 31455 | #pragma warning(push) |
| 31428 | 31456 | #pragma warning(disable: 4324) |
| 31457 | +#endif /* _MSC_VER */ |
| 31458 | + |
| 31429 | 31459 | /* |
| 31430 | 31460 | ** Each SQLite mutex is an instance of the following structure. |
| 31431 | 31461 | ** |
| 31432 | 31462 | ** The ALIGN128 macro attempts to force 128-byte alignment on mutexes, |
| 31433 | 31463 | ** so that adjacent mutex objects are always on different cache lines |
| | @@ -31446,11 +31476,13 @@ |
| 31446 | 31476 | volatile int nRef; /* Number of entrances */ |
| 31447 | 31477 | volatile DWORD owner; /* Thread holding this mutex */ |
| 31448 | 31478 | volatile LONG trace; /* True to trace changes */ |
| 31449 | 31479 | #endif |
| 31450 | 31480 | }; |
| 31481 | +#ifdef _MSC_VER |
| 31451 | 31482 | #pragma warning(pop) |
| 31483 | +#endif /* _MSC_VER */ |
| 31452 | 31484 | |
| 31453 | 31485 | #ifdef SQLITE_DEBUG |
| 31454 | 31486 | /* |
| 31455 | 31487 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| 31456 | 31488 | ** intended for use only inside assert() statements. |
| | @@ -32860,13 +32892,20 @@ |
| 32860 | 32892 | # define SQLITE_PRINT_BUF_SIZE 70 |
| 32861 | 32893 | #endif |
| 32862 | 32894 | #define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */ |
| 32863 | 32895 | |
| 32864 | 32896 | /* |
| 32865 | | -** Hard limit on the precision of floating-point conversions. |
| 32897 | +** Hard limit on the precision of floating-point conversions to |
| 32898 | +** the minimum of SQLITE_PRINTF_PRECISION_LIMIT and 100 million. |
| 32866 | 32899 | */ |
| 32867 | | -#ifndef SQLITE_PRINTF_PRECISION_LIMIT |
| 32900 | +#ifdef SQLITE_PRINTF_PRECISION_LIMIT |
| 32901 | +# if SQLITE_PRINTF_PRECISION_LIMIT<100000000 |
| 32902 | +# define SQLITE_FP_PRECISION_LIMIT SQLITE_PRINTF_PRECISION_LIMIT |
| 32903 | +# else |
| 32904 | +# define SQLITE_FP_PRECISION_LIMIT 100000000 |
| 32905 | +# endif |
| 32906 | +#else |
| 32868 | 32907 | # define SQLITE_FP_PRECISION_LIMIT 100000000 |
| 32869 | 32908 | #endif |
| 32870 | 32909 | |
| 32871 | 32910 | /* Forward reference */ |
| 32872 | 32911 | static void sqlite3StrAppend64(sqlite3_str *p, const char *z, i64 N); |
| | @@ -33222,15 +33261,13 @@ |
| 33222 | 33261 | realvalue = getDoubleArg(pArgList); |
| 33223 | 33262 | }else{ |
| 33224 | 33263 | realvalue = va_arg(ap,double); |
| 33225 | 33264 | } |
| 33226 | 33265 | if( precision<0 ) precision = 6; /* Set default precision */ |
| 33227 | | -#ifdef SQLITE_FP_PRECISION_LIMIT |
| 33228 | 33266 | if( precision>SQLITE_FP_PRECISION_LIMIT ){ |
| 33229 | 33267 | precision = SQLITE_FP_PRECISION_LIMIT; |
| 33230 | 33268 | } |
| 33231 | | -#endif |
| 33232 | 33269 | if( xtype==etFLOAT ){ |
| 33233 | 33270 | iRound = -precision; |
| 33234 | 33271 | }else if( xtype==etGENERIC ){ |
| 33235 | 33272 | if( precision==0 ) precision = 1; |
| 33236 | 33273 | iRound = precision; |
| | @@ -33316,11 +33353,11 @@ |
| 33316 | 33353 | if( szBufNeeded + pAccum->nChar >= pAccum->nAlloc ){ |
| 33317 | 33354 | if( pAccum->mxAlloc==0 && pAccum->accError==0 ){ |
| 33318 | 33355 | /* Unable to allocate space in pAccum, perhaps because it |
| 33319 | 33356 | ** is coming from sqlite3_snprintf() or similar. We'll have |
| 33320 | 33357 | ** to render into temporary space and the memcpy() it over. */ |
| 33321 | | - bufpt = sqlite3_malloc(szBufNeeded); |
| 33358 | + bufpt = sqlite3_malloc64(szBufNeeded); |
| 33322 | 33359 | if( bufpt==0 ){ |
| 33323 | 33360 | sqlite3StrAccumSetError(pAccum, SQLITE_NOMEM); |
| 33324 | 33361 | return; |
| 33325 | 33362 | } |
| 33326 | 33363 | zExtra = bufpt; |
| | @@ -36345,13 +36382,11 @@ |
| 36345 | 36382 | if( c>=0xc0 ){ \ |
| 36346 | 36383 | c = sqlite3Utf8Trans1[c-0xc0]; \ |
| 36347 | 36384 | while( zIn<zTerm && (*zIn & 0xc0)==0x80 ){ \ |
| 36348 | 36385 | c = (c<<6) + (0x3f & *(zIn++)); \ |
| 36349 | 36386 | } \ |
| 36350 | | - if( c<0x80 \ |
| 36351 | | - || (c&0xFFFFF800)==0xD800 \ |
| 36352 | | - || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ |
| 36387 | + if( c<0x80 || (c&0xFFFFF800)==0xD800 ){ c = 0xFFFD; } \ |
| 36353 | 36388 | } |
| 36354 | 36389 | SQLITE_PRIVATE u32 sqlite3Utf8Read( |
| 36355 | 36390 | const unsigned char **pz /* Pointer to string from which to read char */ |
| 36356 | 36391 | ){ |
| 36357 | 36392 | unsigned int c; |
| | @@ -36363,13 +36398,11 @@ |
| 36363 | 36398 | if( c>=0xc0 ){ |
| 36364 | 36399 | c = sqlite3Utf8Trans1[c-0xc0]; |
| 36365 | 36400 | while( (*(*pz) & 0xc0)==0x80 ){ |
| 36366 | 36401 | c = (c<<6) + (0x3f & *((*pz)++)); |
| 36367 | 36402 | } |
| 36368 | | - if( c<0x80 |
| 36369 | | - || (c&0xFFFFF800)==0xD800 |
| 36370 | | - || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } |
| 36403 | + if( c<0x80 || (c&0xFFFFF800)==0xD800 ){ c = 0xFFFD; } |
| 36371 | 36404 | } |
| 36372 | 36405 | return c; |
| 36373 | 36406 | } |
| 36374 | 36407 | |
| 36375 | 36408 | /* |
| | @@ -36765,11 +36798,10 @@ |
| 36765 | 36798 | z[0] = 0; |
| 36766 | 36799 | z = zBuf; |
| 36767 | 36800 | c = sqlite3Utf8Read((const u8**)&z); |
| 36768 | 36801 | t = i; |
| 36769 | 36802 | if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD; |
| 36770 | | - if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD; |
| 36771 | 36803 | assert( c==t ); |
| 36772 | 36804 | assert( (z-zBuf)==n ); |
| 36773 | 36805 | } |
| 36774 | 36806 | } |
| 36775 | 36807 | #endif /* SQLITE_TEST */ |
| | @@ -38324,11 +38356,11 @@ |
| 38324 | 38356 | SQLITE_PRIVATE int sqlite3GetUInt32(const char *z, u32 *pI){ |
| 38325 | 38357 | u64 v = 0; |
| 38326 | 38358 | int i; |
| 38327 | 38359 | for(i=0; sqlite3Isdigit(z[i]); i++){ |
| 38328 | 38360 | v = v*10 + z[i] - '0'; |
| 38329 | | - if( v>4294967296LL ){ *pI = 0; return 0; } |
| 38361 | + if( v>4294967295LL ){ *pI = 0; return 0; } |
| 38330 | 38362 | } |
| 38331 | 38363 | if( i==0 || z[i]!=0 ){ *pI = 0; return 0; } |
| 38332 | 38364 | *pI = (u32)v; |
| 38333 | 38365 | return 1; |
| 38334 | 38366 | } |
| | @@ -49206,11 +49238,10 @@ |
| 49206 | 49238 | |
| 49207 | 49239 | /* |
| 49208 | 49240 | ** Include the header file for the Windows VFS. |
| 49209 | 49241 | */ |
| 49210 | 49242 | /* #include "os_win.h" */ |
| 49211 | | -#define SQLITE_WIN32_HAS_WIDE 1 |
| 49212 | 49243 | |
| 49213 | 49244 | /* |
| 49214 | 49245 | ** This constant should already be defined (in the "WinDef.h" SDK file). |
| 49215 | 49246 | */ |
| 49216 | 49247 | #ifndef MAX_PATH |
| | @@ -49521,28 +49552,10 @@ |
| 49521 | 49552 | static void winMemShutdown(void *pAppData); |
| 49522 | 49553 | |
| 49523 | 49554 | SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void); |
| 49524 | 49555 | #endif /* SQLITE_WIN32_MALLOC */ |
| 49525 | 49556 | |
| 49526 | | -/* |
| 49527 | | -** The following variable is (normally) set once and never changes |
| 49528 | | -** thereafter. It records whether the operating system is Win9x |
| 49529 | | -** or WinNT. |
| 49530 | | -** |
| 49531 | | -** 0: Operating system unknown. |
| 49532 | | -** 1: Operating system is Win9x. |
| 49533 | | -** 2: Operating system is WinNT. |
| 49534 | | -** |
| 49535 | | -** In order to facilitate testing on a WinNT system, the test fixture |
| 49536 | | -** can manually set this value to 1 to emulate Win98 behavior. |
| 49537 | | -*/ |
| 49538 | | -#ifdef SQLITE_TEST |
| 49539 | | -SQLITE_API LONG volatile sqlite3_os_type = 0; |
| 49540 | | -#else |
| 49541 | | -static LONG volatile sqlite3_os_type = 0; |
| 49542 | | -#endif |
| 49543 | | - |
| 49544 | 49557 | #ifndef SYSCALL |
| 49545 | 49558 | # define SYSCALL sqlite3_syscall_ptr |
| 49546 | 49559 | #endif |
| 49547 | 49560 | |
| 49548 | 49561 | /* |
| | @@ -49890,10 +49903,13 @@ |
| 49890 | 49903 | { "cygwin_conv_path", (SYSCALL)0, 0 }, |
| 49891 | 49904 | #endif |
| 49892 | 49905 | #define osCygwin_conv_path ((size_t(*)(unsigned int, \ |
| 49893 | 49906 | const void *, void *, size_t))aSyscall[58].pCurrent) |
| 49894 | 49907 | |
| 49908 | + { "GetDriveTypeW", (SYSCALL)GetDriveTypeW, 0 }, |
| 49909 | +#define osGetDriveTypeW ((UINT(WINAPI*)(LPCWSTR))aSyscall[59].pCurrent) |
| 49910 | + |
| 49895 | 49911 | }; /* End of the overrideable system calls */ |
| 49896 | 49912 | |
| 49897 | 49913 | /* |
| 49898 | 49914 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| 49899 | 49915 | ** "win32" VFSes. Return SQLITE_OK upon successfully updating the |
| | @@ -50060,10 +50076,11 @@ |
| 50060 | 50076 | sqlite3_mutex_leave(pMainMtx); |
| 50061 | 50077 | return rc; |
| 50062 | 50078 | } |
| 50063 | 50079 | #endif /* SQLITE_WIN32_MALLOC */ |
| 50064 | 50080 | |
| 50081 | +#ifdef _WIN32 |
| 50065 | 50082 | /* |
| 50066 | 50083 | ** This function outputs the specified (ANSI) string to the Win32 debugger |
| 50067 | 50084 | ** (if available). Undocumented. Might go away at any moment. |
| 50068 | 50085 | */ |
| 50069 | 50086 | SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ |
| | @@ -50096,10 +50113,11 @@ |
| 50096 | 50113 | while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, |
| 50097 | 50114 | TRUE))==WAIT_IO_COMPLETION ){} |
| 50098 | 50115 | return rc; |
| 50099 | 50116 | } |
| 50100 | 50117 | #endif |
| 50118 | +#endif /* _WIN32 */ |
| 50101 | 50119 | |
| 50102 | 50120 | #ifdef SQLITE_WIN32_MALLOC |
| 50103 | 50121 | /* |
| 50104 | 50122 | ** Allocate nBytes of memory. |
| 50105 | 50123 | */ |
| | @@ -50356,10 +50374,11 @@ |
| 50356 | 50374 | zText = 0; |
| 50357 | 50375 | } |
| 50358 | 50376 | return zText; |
| 50359 | 50377 | } |
| 50360 | 50378 | |
| 50379 | +#ifdef _WIN32 |
| 50361 | 50380 | /* |
| 50362 | 50381 | ** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM |
| 50363 | 50382 | ** code page. |
| 50364 | 50383 | ** |
| 50365 | 50384 | ** Space to hold the returned string is obtained from sqlite3_malloc(). |
| | @@ -50385,11 +50404,10 @@ |
| 50385 | 50404 | zMbcsText = 0; |
| 50386 | 50405 | } |
| 50387 | 50406 | return zMbcsText; |
| 50388 | 50407 | } |
| 50389 | 50408 | |
| 50390 | | -#ifdef _WIN32 |
| 50391 | 50409 | /* |
| 50392 | 50410 | ** Convert a Microsoft Unicode string to a multi-byte character string, |
| 50393 | 50411 | ** using the ANSI or OEM code page. |
| 50394 | 50412 | ** |
| 50395 | 50413 | ** Space to hold the returned string is obtained from sqlite3_malloc(). |
| | @@ -50413,11 +50431,10 @@ |
| 50413 | 50431 | sqlite3_free(zText); |
| 50414 | 50432 | zText = 0; |
| 50415 | 50433 | } |
| 50416 | 50434 | return zText; |
| 50417 | 50435 | } |
| 50418 | | -#endif /* _WIN32 */ |
| 50419 | 50436 | |
| 50420 | 50437 | /* |
| 50421 | 50438 | ** Convert a multi-byte character string to UTF-8. |
| 50422 | 50439 | ** |
| 50423 | 50440 | ** Space to hold the returned string is obtained from sqlite3_malloc(). |
| | @@ -50433,11 +50450,10 @@ |
| 50433 | 50450 | zTextUtf8 = winUnicodeToUtf8(zTmpWide); |
| 50434 | 50451 | sqlite3_free(zTmpWide); |
| 50435 | 50452 | return zTextUtf8; |
| 50436 | 50453 | } |
| 50437 | 50454 | |
| 50438 | | -#ifdef _WIN32 |
| 50439 | 50455 | /* |
| 50440 | 50456 | ** Convert a UTF-8 string to a multi-byte character string. |
| 50441 | 50457 | ** |
| 50442 | 50458 | ** Space to hold the returned string is obtained from sqlite3_malloc(). |
| 50443 | 50459 | */ |
| | @@ -50483,11 +50499,10 @@ |
| 50483 | 50499 | #ifndef SQLITE_OMIT_AUTOINIT |
| 50484 | 50500 | if( sqlite3_initialize() ) return 0; |
| 50485 | 50501 | #endif |
| 50486 | 50502 | return winUnicodeToUtf8(zWideText); |
| 50487 | 50503 | } |
| 50488 | | -#endif /* _WIN32 */ |
| 50489 | 50504 | |
| 50490 | 50505 | /* |
| 50491 | 50506 | ** This is a public wrapper for the winMbcsToUtf8() function. |
| 50492 | 50507 | */ |
| 50493 | 50508 | SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){ |
| | @@ -50501,11 +50516,10 @@ |
| 50501 | 50516 | if( sqlite3_initialize() ) return 0; |
| 50502 | 50517 | #endif |
| 50503 | 50518 | return winMbcsToUtf8(zText, osAreFileApisANSI()); |
| 50504 | 50519 | } |
| 50505 | 50520 | |
| 50506 | | -#ifdef _WIN32 |
| 50507 | 50521 | /* |
| 50508 | 50522 | ** This is a public wrapper for the winMbcsToUtf8() function. |
| 50509 | 50523 | */ |
| 50510 | 50524 | SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){ |
| 50511 | 50525 | #ifdef SQLITE_ENABLE_API_ARMOR |
| | @@ -50764,17 +50778,17 @@ |
| 50764 | 50778 | *pError = e; |
| 50765 | 50779 | } |
| 50766 | 50780 | return 0; |
| 50767 | 50781 | } |
| 50768 | 50782 | if( winIoerrCanRetry1(e) ){ |
| 50769 | | - sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); |
| 50783 | + osSleep(winIoerrRetryDelay*(1+*pnRetry)); |
| 50770 | 50784 | ++*pnRetry; |
| 50771 | 50785 | return 1; |
| 50772 | 50786 | } |
| 50773 | 50787 | #if defined(winIoerrCanRetry2) |
| 50774 | 50788 | else if( winIoerrCanRetry2(e) ){ |
| 50775 | | - sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); |
| 50789 | + osSleep(winIoerrRetryDelay*(1+*pnRetry)); |
| 50776 | 50790 | ++*pnRetry; |
| 50777 | 50791 | return 1; |
| 50778 | 50792 | } |
| 50779 | 50793 | #endif |
| 50780 | 50794 | if( pError ){ |
| | @@ -51000,11 +51014,11 @@ |
| 51000 | 51014 | #endif |
| 51001 | 51015 | |
| 51002 | 51016 | do{ |
| 51003 | 51017 | rc = osCloseHandle(pFile->h); |
| 51004 | 51018 | /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ |
| 51005 | | - }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); |
| 51019 | + }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (osSleep(100), 1) ); |
| 51006 | 51020 | if( rc ){ |
| 51007 | 51021 | pFile->h = NULL; |
| 51008 | 51022 | } |
| 51009 | 51023 | OpenCounter(-1); |
| 51010 | 51024 | OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n", |
| | @@ -51614,11 +51628,11 @@ |
| 51614 | 51628 | )); |
| 51615 | 51629 | return rc; |
| 51616 | 51630 | } |
| 51617 | 51631 | |
| 51618 | 51632 | cnt--; |
| 51619 | | - if( cnt>0 ) sqlite3_win32_sleep(1); |
| 51633 | + if( cnt>0 ) osSleep(1); |
| 51620 | 51634 | } |
| 51621 | 51635 | gotPendingLock = res; |
| 51622 | 51636 | } |
| 51623 | 51637 | |
| 51624 | 51638 | /* Acquire a shared lock |
| | @@ -51823,11 +51837,11 @@ |
| 51823 | 51837 | } |
| 51824 | 51838 | } |
| 51825 | 51839 | |
| 51826 | 51840 | /* Forward references to VFS helper methods used for temporary files */ |
| 51827 | 51841 | static int winGetTempname(sqlite3_vfs *, char **); |
| 51828 | | -static int winIsDir(const void *); |
| 51842 | +static int winIsDir(LPCWSTR); |
| 51829 | 51843 | static BOOL winIsLongPathPrefix(const char *); |
| 51830 | 51844 | static BOOL winIsDriveLetterAndColon(const char *); |
| 51831 | 51845 | |
| 51832 | 51846 | /* |
| 51833 | 51847 | ** Control and query of the open file handle. |
| | @@ -52055,15 +52069,14 @@ |
| 52055 | 52069 | ** Note: If the function cygwin_conv_path() fails, only |
| 52056 | 52070 | ** UTF-8 -> UTF-16 conversion will be done. This can only |
| 52057 | 52071 | ** happen when the file path >32k, in which case winUtf8ToUnicode() |
| 52058 | 52072 | ** will fail too. |
| 52059 | 52073 | */ |
| 52060 | | -static void *winConvertFromUtf8Filename(const char *zFilename){ |
| 52061 | | - void *zConverted = 0; |
| 52074 | +static LPWSTR winConvertFromUtf8Filename(const char *zFilename){ |
| 52075 | + LPWSTR zConverted = 0; |
| 52062 | 52076 | #ifdef __CYGWIN__ |
| 52063 | 52077 | int nChar; |
| 52064 | | - LPWSTR zWideFilename; |
| 52065 | 52078 | |
| 52066 | 52079 | if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename) |
| 52067 | 52080 | && winIsDirSep(zFilename[2])) ){ |
| 52068 | 52081 | i64 nByte; |
| 52069 | 52082 | int convertflag = CCP_POSIX_TO_WIN_W; |
| | @@ -52073,24 +52086,23 @@ |
| 52073 | 52086 | if( nByte>0 ){ |
| 52074 | 52087 | zConverted = sqlite3MallocZero(12+(u64)nByte); |
| 52075 | 52088 | if ( zConverted==0 ){ |
| 52076 | 52089 | return zConverted; |
| 52077 | 52090 | } |
| 52078 | | - zWideFilename = zConverted; |
| 52079 | 52091 | /* Filenames should be prefixed, except when converted |
| 52080 | 52092 | * full path already starts with "\\?\". */ |
| 52081 | 52093 | if( osCygwin_conv_path(convertflag, zFilename, |
| 52082 | | - zWideFilename+4, nByte)==0 ){ |
| 52094 | + zConverted+4, nByte)==0 ){ |
| 52083 | 52095 | if( (convertflag&CCP_RELATIVE) ){ |
| 52084 | | - memmove(zWideFilename, zWideFilename+4, nByte); |
| 52085 | | - }else if( memcmp(zWideFilename+4, L"\\\\", 4) ){ |
| 52086 | | - memcpy(zWideFilename, L"\\\\?\\", 8); |
| 52087 | | - }else if( zWideFilename[6]!='?' ){ |
| 52088 | | - memmove(zWideFilename+6, zWideFilename+4, nByte); |
| 52089 | | - memcpy(zWideFilename, L"\\\\?\\UNC", 14); |
| 52096 | + memmove(zConverted, zConverted+4, nByte); |
| 52097 | + }else if( memcmp(zConverted+4, L"\\\\", 4) ){ |
| 52098 | + memcpy(zConverted, L"\\\\?\\", 8); |
| 52099 | + }else if( zConverted[6]!='?' ){ |
| 52100 | + memmove(zConverted+6, zConverted+4, nByte); |
| 52101 | + memcpy(zConverted, L"\\\\?\\UNC", 14); |
| 52090 | 52102 | }else{ |
| 52091 | | - memmove(zWideFilename, zWideFilename+4, nByte); |
| 52103 | + memmove(zConverted, zConverted+4, nByte); |
| 52092 | 52104 | } |
| 52093 | 52105 | return zConverted; |
| 52094 | 52106 | } |
| 52095 | 52107 | sqlite3_free(zConverted); |
| 52096 | 52108 | } |
| | @@ -52097,32 +52109,31 @@ |
| 52097 | 52109 | } |
| 52098 | 52110 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 52099 | 52111 | if( nChar==0 ){ |
| 52100 | 52112 | return 0; |
| 52101 | 52113 | } |
| 52102 | | - zWideFilename = sqlite3MallocZero( nChar*sizeof(WCHAR)+12 ); |
| 52103 | | - if( zWideFilename==0 ){ |
| 52114 | + zConverted = sqlite3MallocZero( ((u64)nChar+6)*sizeof(WCHAR) ); |
| 52115 | + if( zConverted==0 ){ |
| 52104 | 52116 | return 0; |
| 52105 | 52117 | } |
| 52106 | 52118 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, |
| 52107 | | - zWideFilename, nChar); |
| 52119 | + zConverted, nChar); |
| 52108 | 52120 | if( nChar==0 ){ |
| 52109 | | - sqlite3_free(zWideFilename); |
| 52110 | | - zWideFilename = 0; |
| 52121 | + sqlite3_free(zConverted); |
| 52122 | + zConverted = 0; |
| 52111 | 52123 | }else if( nChar>MAX_PATH |
| 52112 | 52124 | && winIsDriveLetterAndColon(zFilename) |
| 52113 | 52125 | && winIsDirSep(zFilename[2]) ){ |
| 52114 | | - memmove(zWideFilename+4, zWideFilename, nChar*sizeof(WCHAR)); |
| 52115 | | - zWideFilename[2] = '\\'; |
| 52116 | | - memcpy(zWideFilename, L"\\\\?\\", 8); |
| 52126 | + memmove(zConverted+4, zConverted, nChar*sizeof(WCHAR)); |
| 52127 | + zConverted[2] = '\\'; |
| 52128 | + memcpy(zConverted, L"\\\\?\\", 8); |
| 52117 | 52129 | }else if( nChar>MAX_PATH |
| 52118 | 52130 | && winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) |
| 52119 | 52131 | && zFilename[2] != '?' ){ |
| 52120 | | - memmove(zWideFilename+6, zWideFilename, nChar*sizeof(WCHAR)); |
| 52121 | | - memcpy(zWideFilename, L"\\\\?\\UNC", 14); |
| 52132 | + memmove(zConverted+6, zConverted, nChar*sizeof(WCHAR)); |
| 52133 | + memcpy(zConverted, L"\\\\?\\UNC", 14); |
| 52122 | 52134 | } |
| 52123 | | - zConverted = zWideFilename; |
| 52124 | 52135 | #else /* if !defined(__CYGWIN__) */ |
| 52125 | 52136 | zConverted = winUtf8ToUnicode(zFilename); |
| 52126 | 52137 | #endif /* __CYGWIN__ */ |
| 52127 | 52138 | /* caller will handle out of memory */ |
| 52128 | 52139 | return zConverted; |
| | @@ -52340,11 +52351,11 @@ |
| 52340 | 52351 | const char *zUtf8, /* File to open */ |
| 52341 | 52352 | int *pbReadonly, /* IN/OUT: True for readonly handle */ |
| 52342 | 52353 | HANDLE *ph /* OUT: New HANDLE for file */ |
| 52343 | 52354 | ){ |
| 52344 | 52355 | int rc = SQLITE_OK; |
| 52345 | | - void *zConverted = 0; |
| 52356 | + LPWSTR zConverted = 0; |
| 52346 | 52357 | int bReadonly = *pbReadonly; |
| 52347 | 52358 | HANDLE h = INVALID_HANDLE_VALUE; |
| 52348 | 52359 | |
| 52349 | 52360 | #ifdef SQLITE_ENABLE_SETLK_TIMEOUT |
| 52350 | 52361 | const DWORD flag_overlapped = FILE_FLAG_OVERLAPPED; |
| | @@ -52368,11 +52379,11 @@ |
| 52368 | 52379 | } |
| 52369 | 52380 | |
| 52370 | 52381 | /* TODO: platforms. |
| 52371 | 52382 | ** TODO: retry-on-ioerr. |
| 52372 | 52383 | */ |
| 52373 | | - h = osCreateFileW((LPCWSTR)zConverted, /* lpFileName */ |
| 52384 | + h = osCreateFileW(zConverted, /* lpFileName */ |
| 52374 | 52385 | (GENERIC_READ | (bReadonly ? 0 : GENERIC_WRITE)), /* dwDesiredAccess */ |
| 52375 | 52386 | FILE_SHARE_READ | FILE_SHARE_WRITE, /* dwShareMode */ |
| 52376 | 52387 | NULL, /* lpSecurityAttributes */ |
| 52377 | 52388 | OPEN_ALWAYS, /* dwCreationDisposition */ |
| 52378 | 52389 | FILE_ATTRIBUTE_NORMAL|flag_overlapped, |
| | @@ -52465,10 +52476,27 @@ |
| 52465 | 52476 | return 1; |
| 52466 | 52477 | } |
| 52467 | 52478 | } |
| 52468 | 52479 | return sqlite3_win_test_unc_locking; |
| 52469 | 52480 | } |
| 52481 | + |
| 52482 | +/* |
| 52483 | +** Return true if the string passed in is the name of a file on a |
| 52484 | +** remote (network-mounted) volume. |
| 52485 | +*/ |
| 52486 | +static int winIsRemoteVolume(const char *zFile){ |
| 52487 | + WCHAR zRoot[4]; |
| 52488 | + if( strncmp(zFile, "\\\\?\\",4)==0 ) zFile += 4; |
| 52489 | + if( !sqlite3Isalpha(zFile[0]) ) return 0; |
| 52490 | + if( zFile[1]!=':' ) return 0; |
| 52491 | + if( !winIsDirSep(zFile[2]) ) return 0; |
| 52492 | + zRoot[0] = (WCHAR)zFile[0]; |
| 52493 | + zRoot[1] = ':'; |
| 52494 | + zRoot[2] = '\\'; |
| 52495 | + zRoot[3] = 0; |
| 52496 | + return osGetDriveTypeW(zRoot)==DRIVE_REMOTE; |
| 52497 | +} |
| 52470 | 52498 | |
| 52471 | 52499 | /* |
| 52472 | 52500 | ** Open the shared-memory area associated with database file pDbFd. |
| 52473 | 52501 | */ |
| 52474 | 52502 | static int winOpenSharedMemory(winFile *pDbFd){ |
| | @@ -52491,11 +52519,15 @@ |
| 52491 | 52519 | return SQLITE_IOERR_NOMEM_BKPT; |
| 52492 | 52520 | } |
| 52493 | 52521 | pNew->zFilename = (char*)&pNew[1]; |
| 52494 | 52522 | pNew->hSharedShm = INVALID_HANDLE_VALUE; |
| 52495 | 52523 | pNew->isUnlocked = 1; |
| 52496 | | - pNew->bUseSharedLockHandle = winIsUNCPath(pDbFd->zPath); |
| 52524 | + if( winIsUNCPath(pDbFd->zPath) || winIsRemoteVolume(pDbFd->zPath) ){ |
| 52525 | + pNew->bUseSharedLockHandle = 1; |
| 52526 | + }else{ |
| 52527 | + pNew->bUseSharedLockHandle = 0; |
| 52528 | + } |
| 52497 | 52529 | sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); |
| 52498 | 52530 | sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); |
| 52499 | 52531 | |
| 52500 | 52532 | /* Look to see if there is an existing winShmNode that can be used. |
| 52501 | 52533 | ** If no matching winShmNode currently exists, then create a new one. */ |
| | @@ -53331,11 +53363,11 @@ |
| 53331 | 53363 | if( !azDirs[1] ) azDirs[1] = osGetenv("TMPDIR"); |
| 53332 | 53364 | if( !azDirs[2] ) azDirs[2] = osGetenv("TMP"); |
| 53333 | 53365 | if( !azDirs[3] ) azDirs[3] = osGetenv("TEMP"); |
| 53334 | 53366 | if( !azDirs[4] ) azDirs[4] = osGetenv("USERPROFILE"); |
| 53335 | 53367 | for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ |
| 53336 | | - void *zConverted; |
| 53368 | + LPWSTR zConverted; |
| 53337 | 53369 | if( zDir==0 ) continue; |
| 53338 | 53370 | /* If the path starts with a drive letter followed by the colon |
| 53339 | 53371 | ** character, assume it is already a native Win32 path; otherwise, |
| 53340 | 53372 | ** it must be converted to a native Win32 path via the Cygwin API |
| 53341 | 53373 | ** prior to using it. |
| | @@ -53372,16 +53404,15 @@ |
| 53372 | 53404 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 53373 | 53405 | return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), |
| 53374 | 53406 | "winGetTempname2", 0); |
| 53375 | 53407 | } |
| 53376 | 53408 | zMulti = winUnicodeToUtf8(zWidePath); |
| 53409 | + sqlite3_free(zWidePath); |
| 53377 | 53410 | if( zMulti ){ |
| 53378 | 53411 | sqlite3_snprintf(nMax, zBuf, "%s", zMulti); |
| 53379 | 53412 | sqlite3_free(zMulti); |
| 53380 | | - sqlite3_free(zWidePath); |
| 53381 | 53413 | }else{ |
| 53382 | | - sqlite3_free(zWidePath); |
| 53383 | 53414 | sqlite3_free(zBuf); |
| 53384 | 53415 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 53385 | 53416 | return SQLITE_IOERR_NOMEM_BKPT; |
| 53386 | 53417 | } |
| 53387 | 53418 | } |
| | @@ -53436,18 +53467,18 @@ |
| 53436 | 53467 | /* |
| 53437 | 53468 | ** Return TRUE if the named file is really a directory. Return false if |
| 53438 | 53469 | ** it is something other than a directory, or if there is any kind of memory |
| 53439 | 53470 | ** allocation failure. |
| 53440 | 53471 | */ |
| 53441 | | -static int winIsDir(const void *zConverted){ |
| 53472 | +static int winIsDir(LPCWSTR zConverted){ |
| 53442 | 53473 | DWORD attr; |
| 53443 | 53474 | int rc = 0; |
| 53444 | 53475 | DWORD lastErrno; |
| 53445 | 53476 | int cnt = 0; |
| 53446 | 53477 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 53447 | 53478 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 53448 | | - while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 53479 | + while( !(rc = osGetFileAttributesExW(zConverted, |
| 53449 | 53480 | GetFileExInfoStandard, |
| 53450 | 53481 | &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} |
| 53451 | 53482 | if( !rc ){ |
| 53452 | 53483 | return 0; /* Invalid name? */ |
| 53453 | 53484 | } |
| | @@ -53485,11 +53516,11 @@ |
| 53485 | 53516 | DWORD dwShareMode; |
| 53486 | 53517 | DWORD dwCreationDisposition; |
| 53487 | 53518 | DWORD dwFlagsAndAttributes = 0; |
| 53488 | 53519 | winVfsAppData *pAppData; |
| 53489 | 53520 | winFile *pFile = (winFile*)id; |
| 53490 | | - void *zConverted; /* Filename in OS encoding */ |
| 53521 | + LPWSTR zConverted; /* Filename in OS encoding */ |
| 53491 | 53522 | const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ |
| 53492 | 53523 | int cnt = 0; |
| 53493 | 53524 | int isRO = 0; /* file is known to be accessible readonly */ |
| 53494 | 53525 | |
| 53495 | 53526 | /* If argument zPath is a NULL pointer, this function is required to open |
| | @@ -53618,11 +53649,11 @@ |
| 53618 | 53649 | | FILE_FLAG_DELETE_ON_CLOSE; |
| 53619 | 53650 | }else{ |
| 53620 | 53651 | dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL; |
| 53621 | 53652 | } |
| 53622 | 53653 | do{ |
| 53623 | | - h = osCreateFileW((LPCWSTR)zConverted, |
| 53654 | + h = osCreateFileW(zConverted, |
| 53624 | 53655 | dwDesiredAccess, |
| 53625 | 53656 | dwShareMode, NULL, |
| 53626 | 53657 | dwCreationDisposition, |
| 53627 | 53658 | dwFlagsAndAttributes, |
| 53628 | 53659 | NULL); |
| | @@ -53714,11 +53745,11 @@ |
| 53714 | 53745 | ){ |
| 53715 | 53746 | int cnt = 0; |
| 53716 | 53747 | int rc; |
| 53717 | 53748 | DWORD attr; |
| 53718 | 53749 | DWORD lastErrno = 0; |
| 53719 | | - void *zConverted; |
| 53750 | + LPWSTR zConverted; |
| 53720 | 53751 | UNUSED_PARAMETER(pVfs); |
| 53721 | 53752 | UNUSED_PARAMETER(syncDir); |
| 53722 | 53753 | |
| 53723 | 53754 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 53724 | 53755 | OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); |
| | @@ -53774,11 +53805,11 @@ |
| 53774 | 53805 | ){ |
| 53775 | 53806 | DWORD attr; |
| 53776 | 53807 | int rc = 0; |
| 53777 | 53808 | int cnt = 0; |
| 53778 | 53809 | DWORD lastErrno = 0; |
| 53779 | | - void *zConverted; |
| 53810 | + LPWSTR zConverted; |
| 53780 | 53811 | int noRetry = 0; /* Do not use winRetryIoerr() */ |
| 53781 | 53812 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 53782 | 53813 | UNUSED_PARAMETER(pVfs); |
| 53783 | 53814 | |
| 53784 | 53815 | if( (flags & NORETRY)!=0 ){ |
| | @@ -53801,11 +53832,11 @@ |
| 53801 | 53832 | if( zConverted==0 ){ |
| 53802 | 53833 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 53803 | 53834 | return SQLITE_IOERR_NOMEM_BKPT; |
| 53804 | 53835 | } |
| 53805 | 53836 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 53806 | | - while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 53837 | + while( !(rc = osGetFileAttributesExW(zConverted, |
| 53807 | 53838 | GetFileExInfoStandard, |
| 53808 | 53839 | &sAttrData)) |
| 53809 | 53840 | && !noRetry |
| 53810 | 53841 | && winRetryIoerr(&cnt, &lastErrno) |
| 53811 | 53842 | ){ /* Loop until true */} |
| | @@ -53983,11 +54014,11 @@ |
| 53983 | 54014 | const char *zRelative, /* Possibly relative input path */ |
| 53984 | 54015 | int nFull, /* Size of output buffer in bytes */ |
| 53985 | 54016 | char *zFull /* Output buffer */ |
| 53986 | 54017 | ){ |
| 53987 | 54018 | int nByte; |
| 53988 | | - void *zConverted; |
| 54019 | + LPWSTR zConverted; |
| 53989 | 54020 | char *zOut; |
| 53990 | 54021 | |
| 53991 | 54022 | /* If this path name begins with "/X:" or "\\?\", where "X" is any |
| 53992 | 54023 | ** alphabetic character, discard the initial "/" from the pathname. |
| 53993 | 54024 | */ |
| | @@ -54096,23 +54127,23 @@ |
| 54096 | 54127 | if( zConverted==0 ){ |
| 54097 | 54128 | return SQLITE_IOERR_NOMEM_BKPT; |
| 54098 | 54129 | } |
| 54099 | 54130 | { |
| 54100 | 54131 | LPWSTR zTemp; |
| 54101 | | - nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 54132 | + nByte = osGetFullPathNameW(zConverted, 0, 0, 0); |
| 54102 | 54133 | if( nByte==0 ){ |
| 54103 | 54134 | sqlite3_free(zConverted); |
| 54104 | 54135 | return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), |
| 54105 | 54136 | "winFullPathname1", zRelative); |
| 54106 | 54137 | } |
| 54107 | 54138 | nByte += 3; |
| 54108 | | - zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); |
| 54139 | + zTemp = sqlite3MallocZero( (u64)nByte*sizeof(WCHAR) ); |
| 54109 | 54140 | if( zTemp==0 ){ |
| 54110 | 54141 | sqlite3_free(zConverted); |
| 54111 | 54142 | return SQLITE_IOERR_NOMEM_BKPT; |
| 54112 | 54143 | } |
| 54113 | | - nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); |
| 54144 | + nByte = osGetFullPathNameW(zConverted, nByte, zTemp, 0); |
| 54114 | 54145 | if( nByte==0 ){ |
| 54115 | 54146 | sqlite3_free(zConverted); |
| 54116 | 54147 | sqlite3_free(zTemp); |
| 54117 | 54148 | return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), |
| 54118 | 54149 | "winFullPathname2", zRelative); |
| | @@ -54168,17 +54199,17 @@ |
| 54168 | 54199 | ** Interfaces for opening a shared library, finding entry points |
| 54169 | 54200 | ** within the shared library, and closing the shared library. |
| 54170 | 54201 | */ |
| 54171 | 54202 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 54172 | 54203 | HANDLE h = 0; |
| 54173 | | - void *zConverted = winConvertFromUtf8Filename(zFilename); |
| 54204 | + LPWSTR zConverted = winConvertFromUtf8Filename(zFilename); |
| 54174 | 54205 | UNUSED_PARAMETER(pVfs); |
| 54175 | 54206 | if( zConverted==0 ){ |
| 54176 | 54207 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); |
| 54177 | 54208 | return 0; |
| 54178 | 54209 | } |
| 54179 | | - h = osLoadLibraryW ? osLoadLibraryW((LPCWSTR)zConverted) : 0; |
| 54210 | + h = osLoadLibraryW ? osLoadLibraryW(zConverted) : 0; |
| 54180 | 54211 | OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h)); |
| 54181 | 54212 | sqlite3_free(zConverted); |
| 54182 | 54213 | return (void*)h; |
| 54183 | 54214 | } |
| 54184 | 54215 | static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ |
| | @@ -54282,11 +54313,11 @@ |
| 54282 | 54313 | |
| 54283 | 54314 | /* |
| 54284 | 54315 | ** Sleep for a little while. Return the amount of time slept. |
| 54285 | 54316 | */ |
| 54286 | 54317 | static int winSleep(sqlite3_vfs *pVfs, int microsec){ |
| 54287 | | - sqlite3_win32_sleep((microsec+999)/1000); |
| 54318 | + osSleep((microsec+999)/1000); |
| 54288 | 54319 | UNUSED_PARAMETER(pVfs); |
| 54289 | 54320 | return ((microsec+999)/1000)*1000; |
| 54290 | 54321 | } |
| 54291 | 54322 | |
| 54292 | 54323 | /* |
| | @@ -54489,11 +54520,11 @@ |
| 54489 | 54520 | winNextSystemCall, /* xNextSystemCall */ |
| 54490 | 54521 | }; |
| 54491 | 54522 | |
| 54492 | 54523 | /* Double-check that the aSyscall[] array has been constructed |
| 54493 | 54524 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 54494 | | - assert( ArraySize(aSyscall)==59 ); |
| 54525 | + assert( ArraySize(aSyscall)==60 ); |
| 54495 | 54526 | assert( strcmp(aSyscall[0].zName,"AreFileApisANSI")==0 ); |
| 54496 | 54527 | assert( strcmp(aSyscall[8].zName,"FreeLibrary")==0 ); |
| 54497 | 54528 | assert( strcmp(aSyscall[16].zName,"GetSystemInfo")==0 ); |
| 54498 | 54529 | assert( strcmp(aSyscall[24].zName,"HeapReAlloc")==0 ); |
| 54499 | 54530 | assert( strcmp(aSyscall[32].zName,"MapViewOfFileFromApp")==0 ); |
| | @@ -58880,10 +58911,14 @@ |
| 58880 | 58911 | #endif |
| 58881 | 58912 | |
| 58882 | 58913 | #ifdef SQLITE_USE_SEH |
| 58883 | 58914 | SQLITE_PRIVATE int sqlite3WalSystemErrno(Wal*); |
| 58884 | 58915 | #endif |
| 58916 | + |
| 58917 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) |
| 58918 | +SQLITE_PRIVATE void sqlite3WalStat(Wal*,sqlite3_str*); |
| 58919 | +#endif |
| 58885 | 58920 | |
| 58886 | 58921 | #endif /* ifndef SQLITE_OMIT_WAL */ |
| 58887 | 58922 | #endif /* SQLITE_WAL_H */ |
| 58888 | 58923 | |
| 58889 | 58924 | /************** End of wal.h *************************************************/ |
| | @@ -65755,10 +65790,24 @@ |
| 65755 | 65790 | SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){ |
| 65756 | 65791 | return sqlite3PcacheRefCount(pPager->pPCache); |
| 65757 | 65792 | } |
| 65758 | 65793 | #endif |
| 65759 | 65794 | |
| 65795 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) |
| 65796 | +/* |
| 65797 | +** Append JSON structure elements describing the current state of |
| 65798 | +** the write-ahead log to pStr. |
| 65799 | +*/ |
| 65800 | +SQLITE_PRIVATE void sqlite3PagerWalStat(Pager *pPager, sqlite3_str *pStr){ |
| 65801 | +#ifndef SQLITE_OMIT_WAL |
| 65802 | + if( pPager->pWal ){ |
| 65803 | + sqlite3WalStat(pPager->pWal, pStr); |
| 65804 | + } |
| 65805 | +#endif |
| 65806 | +} |
| 65807 | +#endif |
| 65808 | + |
| 65760 | 65809 | /* |
| 65761 | 65810 | ** Return the approximate number of bytes of memory currently |
| 65762 | 65811 | ** used by the pager and its associated cache. |
| 65763 | 65812 | */ |
| 65764 | 65813 | SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){ |
| | @@ -67351,14 +67400,45 @@ |
| 67351 | 67400 | ** walIteratorInit() - Create a new iterator, |
| 67352 | 67401 | ** walIteratorNext() - Step an iterator, |
| 67353 | 67402 | ** walIteratorFree() - Free an iterator. |
| 67354 | 67403 | ** |
| 67355 | 67404 | ** This functionality is used by the checkpoint code (see walCheckpoint()). |
| 67405 | +** |
| 67406 | +** There are two possible algorithms: |
| 67407 | +** |
| 67408 | +** WALITER-1 Load all pages mentioned in the WAL file and sort them, |
| 67409 | +** then hand them back out in sorted order as requested by |
| 67410 | +** walIteratorNext(). nPagemap==0 for this algorithm. |
| 67411 | +** |
| 67412 | +** WALITER-2 Create a map of all database file pages and record the |
| 67413 | +** last WAL file frame that updates that page. Then walk |
| 67414 | +** through the map in acsending order and return all |
| 67415 | +** non-zero entries. nPagemap is positive for this algorithm. |
| 67416 | +** |
| 67417 | +** Either algorithm should work for any database and WAL file, however |
| 67418 | +** algorithm WALITER-1 is faster and uses less memory when the database is |
| 67419 | +** larger than the WAL file and algorithm WALITER-2 is faster and uses |
| 67420 | +** less memory when the WAL file is larger than the database, modulo a |
| 67421 | +** constant of proportionality. The walIteratorInit() routine selects |
| 67422 | +** the best algorithm for each situation. WALITER-2 was added for |
| 67423 | +** SQLite 3.54.0. Prior to that, WALITER-1 was used always. |
| 67424 | +** |
| 67425 | +** For algorithm WALITER-2, nPagemap stores the number of pages in the |
| 67426 | +** database file, nSegment==1, and aSegment[0].aPgno[] is the page map array |
| 67427 | +** that is nPagemap+1 entries in length. The value of aSegment[0].aPgno[PGNO] |
| 67428 | +** is the frame number of the last (newest) entry for page PGNO in the WAL |
| 67429 | +** file, or 0 if PGNO is not in the WAL file. (Aside: There is no page |
| 67430 | +** number 0 in a well-formed database, so the memory allocation is arranged |
| 67431 | +** such that aSegment[0].aPgno[0] and aSegment[0].iZero are aliases for the |
| 67432 | +** same four bits of memory. This saves us from having to use -1 and +1 |
| 67433 | +** offsets to translate between 1-based SQLite page numbers and 0-based |
| 67434 | +** C-language index numbers. tag-20260903-1) |
| 67356 | 67435 | */ |
| 67357 | 67436 | struct WalIterator { |
| 67358 | 67437 | u32 iPrior; /* Last result returned from the iterator */ |
| 67359 | 67438 | int nSegment; /* Number of entries in aSegment[] */ |
| 67439 | + u32 nPagemap; /* Non-zero in "page-map" mode */ |
| 67360 | 67440 | struct WalSegment { |
| 67361 | 67441 | int iNext; /* Next slot in aIndex[] not yet returned */ |
| 67362 | 67442 | ht_slot *aIndex; /* i0, i1, i2... such that aPgno[iN] ascend */ |
| 67363 | 67443 | u32 *aPgno; /* Array of page numbers. */ |
| 67364 | 67444 | int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */ |
| | @@ -67367,10 +67447,11 @@ |
| 67367 | 67447 | }; |
| 67368 | 67448 | |
| 67369 | 67449 | /* Size (in bytes) of a WalIterator object suitable for N or fewer segments */ |
| 67370 | 67450 | #define SZ_WALITERATOR(N) \ |
| 67371 | 67451 | (offsetof(WalIterator,aSegment)+(N)*sizeof(struct WalSegment)) |
| 67452 | + |
| 67372 | 67453 | |
| 67373 | 67454 | /* |
| 67374 | 67455 | ** Define the parameters of the hash tables in the wal-index file. There |
| 67375 | 67456 | ** is a hash-table following every HASHTABLE_NPAGE page numbers in the |
| 67376 | 67457 | ** wal-index. |
| | @@ -68530,28 +68611,42 @@ |
| 68530 | 68611 | static int walIteratorNext( |
| 68531 | 68612 | WalIterator *p, /* Iterator */ |
| 68532 | 68613 | u32 *piPage, /* OUT: The page number of the next page */ |
| 68533 | 68614 | u32 *piFrame /* OUT: Wal frame index of next page */ |
| 68534 | 68615 | ){ |
| 68535 | | - u32 iMin; /* Result pgno must be greater than iMin */ |
| 68536 | 68616 | u32 iRet = 0xFFFFFFFF; /* 0xffffffff is never a valid page number */ |
| 68537 | | - int i; /* For looping through segments */ |
| 68538 | | - |
| 68539 | | - iMin = p->iPrior; |
| 68540 | | - assert( iMin<0xffffffff ); |
| 68541 | | - for(i=p->nSegment-1; i>=0; i--){ |
| 68542 | | - struct WalSegment *pSegment = &p->aSegment[i]; |
| 68543 | | - while( pSegment->iNext<pSegment->nEntry ){ |
| 68544 | | - u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]]; |
| 68545 | | - if( iPg>iMin ){ |
| 68546 | | - if( iPg<iRet ){ |
| 68547 | | - iRet = iPg; |
| 68548 | | - *piFrame = pSegment->iZero + pSegment->aIndex[pSegment->iNext]; |
| 68549 | | - } |
| 68617 | + |
| 68618 | + if( p->nPagemap ){ |
| 68619 | + /* Algorithm WALITER-2 */ |
| 68620 | + while( p->iPrior<p->nPagemap ){ |
| 68621 | + p->iPrior++; |
| 68622 | + if( p->aSegment[0].aPgno[p->iPrior] ){ |
| 68623 | + iRet = p->iPrior; |
| 68624 | + *piFrame = p->aSegment[0].aPgno[p->iPrior]; |
| 68550 | 68625 | break; |
| 68551 | 68626 | } |
| 68552 | | - pSegment->iNext++; |
| 68627 | + } |
| 68628 | + }else{ |
| 68629 | + /* Algorithm WALITER-1 */ |
| 68630 | + u32 iMin; /* Result pgno must be greater than iMin */ |
| 68631 | + int i; /* For looping through segments */ |
| 68632 | + |
| 68633 | + iMin = p->iPrior; |
| 68634 | + assert( iMin<0xffffffff ); |
| 68635 | + for(i=p->nSegment-1; i>=0; i--){ |
| 68636 | + struct WalSegment *pSegment = &p->aSegment[i]; |
| 68637 | + while( pSegment->iNext<pSegment->nEntry ){ |
| 68638 | + u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]]; |
| 68639 | + if( iPg>iMin ){ |
| 68640 | + if( iPg<iRet ){ |
| 68641 | + iRet = iPg; |
| 68642 | + *piFrame = pSegment->iZero + pSegment->aIndex[pSegment->iNext]; |
| 68643 | + } |
| 68644 | + break; |
| 68645 | + } |
| 68646 | + pSegment->iNext++; |
| 68647 | + } |
| 68553 | 68648 | } |
| 68554 | 68649 | } |
| 68555 | 68650 | |
| 68556 | 68651 | *piPage = p->iPrior = iRet; |
| 68557 | 68652 | return (iRet==0xFFFFFFFF); |
| | @@ -68716,63 +68811,99 @@ |
| 68716 | 68811 | ** |
| 68717 | 68812 | ** The calling routine should invoke walIteratorFree() to destroy the |
| 68718 | 68813 | ** WalIterator object when it has finished with it. |
| 68719 | 68814 | */ |
| 68720 | 68815 | static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ |
| 68816 | + int iFirstPage; /* First 32KB *-shm page to visit */ |
| 68817 | + int iLastPage; /* Last 32KB *-shm page to visit */ |
| 68818 | + u32 iZero; /* Frame before first frame to visit */ |
| 68721 | 68819 | WalIterator *p; /* Return value */ |
| 68722 | 68820 | int nSegment; /* Number of segments to merge */ |
| 68723 | 68821 | u32 iLast; /* Last frame in log */ |
| 68724 | 68822 | sqlite3_int64 nByte; /* Number of bytes to allocate */ |
| 68823 | + sqlite3_int64 nExtra; /* Number of bytes to allocate */ |
| 68725 | 68824 | int i; /* Iterator variable */ |
| 68726 | | - ht_slot *aTmp; /* Temp space used by merge-sort */ |
| 68825 | + ht_slot *aTmp = 0; /* Temp space used by merge-sort */ |
| 68727 | 68826 | int rc = SQLITE_OK; /* Return Code */ |
| 68827 | + int eAlg; /* Which algorithm to use. 1 or 2 */ |
| 68728 | 68828 | |
| 68729 | 68829 | /* This routine only runs while holding the checkpoint lock. And |
| 68730 | | - ** it only runs if there is actually content in the log (mxFrame>0). |
| 68731 | | - */ |
| 68830 | + ** it only runs if there is actually content in the log (mxFrame>0). */ |
| 68732 | 68831 | assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); |
| 68832 | + |
| 68733 | 68833 | iLast = pWal->hdr.mxFrame; |
| 68834 | + iFirstPage = walFramePage(nBackfill+1); |
| 68835 | + iLastPage = walFramePage(iLast); |
| 68836 | + iZero = iFirstPage ? (HASHTABLE_NPAGE_ONE+(iFirstPage-1)*HASHTABLE_NPAGE) : 0; |
| 68837 | + |
| 68838 | + if( (iLast-iZero)*sizeof(ht_slot)>pWal->hdr.nPage*sizeof(u32) ){ |
| 68839 | + /* Algorithm WALITER-2 */ |
| 68840 | + nSegment = 1; |
| 68841 | + eAlg = 2; |
| 68842 | + nByte = SZ_WALITERATOR(nSegment) + pWal->hdr.nPage * sizeof(u32); |
| 68843 | + nExtra = 0; |
| 68844 | + }else{ |
| 68845 | + /* Algorithm WALITER-1 */ |
| 68846 | + nSegment = iLastPage - iFirstPage + 1; |
| 68847 | + eAlg = 1; |
| 68848 | + nByte = SZ_WALITERATOR(nSegment) + (iLast-iZero)*sizeof(ht_slot); |
| 68849 | + nExtra = sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast); |
| 68850 | + } |
| 68734 | 68851 | |
| 68735 | 68852 | /* Allocate space for the WalIterator object. */ |
| 68736 | | - nSegment = walFramePage(iLast) + 1; |
| 68737 | | - nByte = SZ_WALITERATOR(nSegment) |
| 68738 | | - + iLast*sizeof(ht_slot); |
| 68739 | | - p = (WalIterator *)sqlite3_malloc64(nByte |
| 68740 | | - + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) |
| 68741 | | - ); |
| 68853 | + p = (WalIterator *)sqlite3_malloc64(nByte + nExtra); |
| 68742 | 68854 | if( !p ){ |
| 68743 | 68855 | return SQLITE_NOMEM_BKPT; |
| 68744 | 68856 | } |
| 68745 | 68857 | memset(p, 0, nByte); |
| 68746 | 68858 | p->nSegment = nSegment; |
| 68747 | | - aTmp = (ht_slot*)&(((u8*)p)[nByte]); |
| 68859 | + if( eAlg==2 ){ |
| 68860 | + p->nPagemap = pWal->hdr.nPage; |
| 68861 | + p->aSegment[0].aPgno = ((u32*)&p->aSegment[1]) - 1; |
| 68862 | + assert( (u8*)&(p->aSegment[0].aPgno[0]) == (u8*)&(p->aSegment[0].iZero) ); |
| 68863 | + /* ^-- verifies tag-20260903-1 */ |
| 68864 | + }else{ |
| 68865 | + aTmp = (ht_slot*)&(((u8*)p)[nByte]); |
| 68866 | + } |
| 68748 | 68867 | SEH_FREE_ON_ERROR(0, p); |
| 68749 | | - for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){ |
| 68868 | + for(i=iFirstPage; rc==SQLITE_OK && i<=iLastPage; i++){ |
| 68750 | 68869 | WalHashLoc sLoc; |
| 68751 | 68870 | |
| 68752 | 68871 | rc = walHashGet(pWal, i, &sLoc); |
| 68753 | 68872 | if( rc==SQLITE_OK ){ |
| 68754 | 68873 | int j; /* Counter variable */ |
| 68755 | 68874 | int nEntry; /* Number of entries in this segment */ |
| 68756 | 68875 | ht_slot *aIndex; /* Sorted index for this segment */ |
| 68757 | 68876 | |
| 68758 | | - if( (i+1)==nSegment ){ |
| 68877 | + if( i==iLastPage ){ |
| 68759 | 68878 | nEntry = (int)(iLast - sLoc.iZero); |
| 68760 | 68879 | }else{ |
| 68761 | 68880 | nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno); |
| 68762 | 68881 | } |
| 68763 | | - aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[sLoc.iZero]; |
| 68764 | | - sLoc.iZero++; |
| 68765 | | - |
| 68766 | | - for(j=0; j<nEntry; j++){ |
| 68767 | | - aIndex[j] = (ht_slot)j; |
| 68768 | | - } |
| 68769 | | - walMergesort((u32 *)sLoc.aPgno, aTmp, aIndex, &nEntry); |
| 68770 | | - p->aSegment[i].iZero = sLoc.iZero; |
| 68771 | | - p->aSegment[i].nEntry = nEntry; |
| 68772 | | - p->aSegment[i].aIndex = aIndex; |
| 68773 | | - p->aSegment[i].aPgno = (u32 *)sLoc.aPgno; |
| 68882 | + |
| 68883 | + if( eAlg==2 ){ |
| 68884 | + u32 *aPagemap = p->aSegment[0].aPgno; |
| 68885 | + for(j=0; j<nEntry; j++){ |
| 68886 | + u32 pgno = sLoc.aPgno[ j ]; |
| 68887 | + if( pgno<=p->nPagemap ){ |
| 68888 | + aPagemap[pgno] = sLoc.iZero + j + 1; |
| 68889 | + } |
| 68890 | + } |
| 68891 | + }else{ |
| 68892 | + assert( i!=iFirstPage || iZero==sLoc.iZero ); |
| 68893 | + aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[sLoc.iZero - iZero]; |
| 68894 | + sLoc.iZero++; |
| 68895 | + |
| 68896 | + for(j=0; j<nEntry; j++){ |
| 68897 | + aIndex[j] = (ht_slot)j; |
| 68898 | + } |
| 68899 | + walMergesort((u32 *)sLoc.aPgno, aTmp, aIndex, &nEntry); |
| 68900 | + p->aSegment[i-iFirstPage].iZero = sLoc.iZero; |
| 68901 | + p->aSegment[i-iFirstPage].nEntry = nEntry; |
| 68902 | + p->aSegment[i-iFirstPage].aIndex = aIndex; |
| 68903 | + p->aSegment[i-iFirstPage].aPgno = (u32 *)sLoc.aPgno; |
| 68904 | + } |
| 68774 | 68905 | } |
| 68775 | 68906 | } |
| 68776 | 68907 | if( rc!=SQLITE_OK ){ |
| 68777 | 68908 | SEH_FREE_ON_ERROR(p, 0); |
| 68778 | 68909 | walIteratorFree(p); |
| | @@ -71409,10 +71540,68 @@ |
| 71409 | 71540 | /* Return the sqlite3_file object for the WAL file |
| 71410 | 71541 | */ |
| 71411 | 71542 | SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ |
| 71412 | 71543 | return pWal->pWalFd; |
| 71413 | 71544 | } |
| 71545 | + |
| 71546 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) |
| 71547 | +/* |
| 71548 | +** Helper function to sqlite3WalStat(). |
| 71549 | +** |
| 71550 | +** Append JSON-5 structure elements onto describing the current state |
| 71551 | +** of pWal onto the end of pStr. This function is for debugging and |
| 71552 | +** analysis only and is not included in production builds. |
| 71553 | +*/ |
| 71554 | +static void walIndexHdrStat(volatile WalIndexHdr *pHdr, sqlite3_str *pStr){ |
| 71555 | + sqlite3_str_appendf(pStr, "iVersion:%u",pHdr->iVersion); |
| 71556 | + sqlite3_str_appendf(pStr, ",iChange:%u",pHdr->iChange); |
| 71557 | + sqlite3_str_appendf(pStr, ",isInit:%u",pHdr->isInit); |
| 71558 | + sqlite3_str_appendf(pStr, ",bigEndCksum:%u",pHdr->bigEndCksum); |
| 71559 | + sqlite3_str_appendf(pStr, ",szPage:%u",pHdr->szPage); |
| 71560 | + sqlite3_str_appendf(pStr, ",mxFrame:%u",pHdr->mxFrame); |
| 71561 | + sqlite3_str_appendf(pStr, ",nPage:%u",pHdr->nPage); |
| 71562 | +#if 0 /* Not often needed. Declutter. */ |
| 71563 | + sqlite3_str_appendf(pStr, ",aFrameCksum:[0x%08x,0x%08x]", |
| 71564 | + pHdr->aFrameCksum[0], pHdr->aFrameCksum[1]); |
| 71565 | + sqlite3_str_appendf(pStr, ",aSalt:[0x%08x,0x%08x]", |
| 71566 | + pHdr->aSalt[0], pHdr->aSalt[1]); |
| 71567 | + sqlite3_str_appendf(pStr, ",aCksum:[0x%08x,0x%08x]", |
| 71568 | + pHdr->aCksum[0], pHdr->aCksum[1]); |
| 71569 | +#endif |
| 71570 | +} |
| 71571 | +#endif /* SQLITE_DEBUG || SQLITE_ENABLE_WALSTAT */ |
| 71572 | + |
| 71573 | + |
| 71574 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) |
| 71575 | +/* |
| 71576 | +** Append JSON-5 structure elements onto describing the current state |
| 71577 | +** of pWal onto the end of pStr. This function is for debugging and |
| 71578 | +** analysis only and is not included in production builds. |
| 71579 | +*/ |
| 71580 | +SQLITE_PRIVATE void sqlite3WalStat(Wal *pWal, sqlite3_str *pStr){ |
| 71581 | + SEH_TRY { |
| 71582 | + int i; |
| 71583 | + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); |
| 71584 | + volatile WalIndexHdr *pHdr = walIndexHdr(pWal); |
| 71585 | + sqlite3_str_appendf(pStr, "hdr0:{"); |
| 71586 | + walIndexHdrStat(pHdr,pStr); |
| 71587 | + sqlite3_str_appendf(pStr, "},ckpt:{"); |
| 71588 | + sqlite3_str_appendf(pStr, "nBackfill:%u",pInfo->nBackfill); |
| 71589 | + sqlite3_str_appendf(pStr, ",aReadMark:[%u", pInfo->aReadMark[0]); |
| 71590 | + for(i=1; i<WAL_NREADER; i++){ |
| 71591 | + sqlite3_str_appendf(pStr, ",%u", pInfo->aReadMark[i]); |
| 71592 | + } |
| 71593 | + sqlite3_str_appendf(pStr, "],nBackfillAttempted:%u}", |
| 71594 | + pInfo->nBackfillAttempted); |
| 71595 | + |
| 71596 | + sqlite3_str_appendf(pStr, ",nWiData:%d", pWal->nWiData); |
| 71597 | + sqlite3_str_appendf(pStr, ",readLock:%d", pWal->readLock); |
| 71598 | + sqlite3_str_appendf(pStr, ",minFrame:%u", pWal->minFrame); |
| 71599 | + } |
| 71600 | + SEH_EXCEPT( ; ) |
| 71601 | +} |
| 71602 | +#endif /* SQLITE_DEBUG || SQLITE_ENABLE_WALSTAT */ |
| 71414 | 71603 | |
| 71415 | 71604 | #endif /* #ifndef SQLITE_OMIT_WAL */ |
| 71416 | 71605 | |
| 71417 | 71606 | /************** End of wal.c *************************************************/ |
| 71418 | 71607 | /************** Begin file btmutex.c *****************************************/ |
| | @@ -74646,11 +74835,11 @@ |
| 74646 | 74835 | } |
| 74647 | 74836 | next = get2byte(&data[pc]); |
| 74648 | 74837 | size = get2byte(&data[pc+2]); |
| 74649 | 74838 | if( size<4 && sqlite3FaultSim(422)==SQLITE_OK ){ |
| 74650 | 74839 | /* Minimum freeblock size is 4. Enable fault-sim 422 to disable this |
| 74651 | | - ** check to reach interesting error stats. However, disabling this |
| 74840 | + ** check to reach interesting error states. However, disabling this |
| 74652 | 74841 | ** check can cause assertion faults due to min-heap overflow. All |
| 74653 | 74842 | ** fault-sims are for testing use only, but this one especially so. */ |
| 74654 | 74843 | return SQLITE_CORRUPT_PAGE(pPage); |
| 74655 | 74844 | } |
| 74656 | 74845 | nFree = nFree + size; |
| | @@ -82907,10 +83096,13 @@ |
| 82907 | 83096 | if( rc!=SQLITE_OK ){ |
| 82908 | 83097 | return rc; |
| 82909 | 83098 | } |
| 82910 | 83099 | pMove = 0; |
| 82911 | 83100 | rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); |
| 83101 | + if( rc==SQLITE_OK ){ |
| 83102 | + rc = sqlite3PagerWrite(pMove->pDbPage); |
| 83103 | + } |
| 82912 | 83104 | freePage(pMove, &rc); |
| 82913 | 83105 | releasePage(pMove); |
| 82914 | 83106 | if( rc!=SQLITE_OK ){ |
| 82915 | 83107 | return rc; |
| 82916 | 83108 | } |
| | @@ -83727,13 +83919,13 @@ |
| 83727 | 83919 | sCheck.aPgRef = sqlite3MallocZero((sCheck.nCkPage / 8)+ 1); |
| 83728 | 83920 | if( !sCheck.aPgRef ){ |
| 83729 | 83921 | checkOom(&sCheck); |
| 83730 | 83922 | goto integrity_ck_cleanup; |
| 83731 | 83923 | } |
| 83732 | | - sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); |
| 83924 | + sCheck.heap = (u32*)sqlite3Malloc( pBt->pageSize*2 ); |
| 83733 | 83925 | #ifdef SQLITE_DEBUG |
| 83734 | | - sCheck.mxHeap = pBt->pageSize/4 - 1; |
| 83926 | + sCheck.mxHeap = pBt->pageSize/2 - 1; |
| 83735 | 83927 | #endif |
| 83736 | 83928 | if( sCheck.heap==0 ){ |
| 83737 | 83929 | checkOom(&sCheck); |
| 83738 | 83930 | goto integrity_ck_cleanup; |
| 83739 | 83931 | } |
| | @@ -83817,11 +84009,11 @@ |
| 83817 | 84009 | } |
| 83818 | 84010 | |
| 83819 | 84011 | /* Clean up and report errors. |
| 83820 | 84012 | */ |
| 83821 | 84013 | integrity_ck_cleanup: |
| 83822 | | - sqlite3PageFree(sCheck.heap); |
| 84014 | + sqlite3_free(sCheck.heap); |
| 83823 | 84015 | sqlite3_free(sCheck.aPgRef); |
| 83824 | 84016 | *pnErr = sCheck.nErr; |
| 83825 | 84017 | if( sCheck.nErr==0 ){ |
| 83826 | 84018 | sqlite3_str_reset(&sCheck.errMsg); |
| 83827 | 84019 | *pzOut = 0; |
| | @@ -86925,11 +87117,11 @@ |
| 86925 | 87117 | if( pExpr ){ |
| 86926 | 87118 | rc = valueFromExpr(db, pExpr, enc, affinity, &pVal, 0); |
| 86927 | 87119 | if( rc==SQLITE_OK && pVal |
| 86928 | 87120 | && affinity==SQLITE_AFF_REAL |
| 86929 | 87121 | && (pVal->flags & MEM_Int) |
| 86930 | | - && (u64)(pVal->u.i<0 ? pVal->u.i : pVal->u.i)>140737488355327LL |
| 87122 | + && (pVal->u.i<-140737488355328LL || pVal->u.i>140737488355327LL) |
| 86931 | 87123 | ){ |
| 86932 | 87124 | /* If the integer value is too large to fit in a 6-byte integer and |
| 86933 | 87125 | ** the affinity is REAL, convert it to a real value now. In most |
| 86934 | 87126 | ** cases an OP_RealAffinity opcode will be used to convert the |
| 86935 | 87127 | ** value to an actual real, but this opcode is omitted if the values |
| | @@ -92336,11 +92528,11 @@ |
| 92336 | 92528 | } |
| 92337 | 92529 | testcase( flags & MEM_Real ); |
| 92338 | 92530 | testcase( flags & MEM_Null ); |
| 92339 | 92531 | testcase( flags & MEM_Blob ); |
| 92340 | 92532 | if( (flags & (MEM_Real|MEM_IntReal|MEM_Null|MEM_Blob))==0 |
| 92341 | | - && p->pKeyInfo->aColl[0]==0 |
| 92533 | + && sqlite3IsBinary(p->pKeyInfo->aColl[0]) |
| 92342 | 92534 | ){ |
| 92343 | 92535 | assert( flags & MEM_Str ); |
| 92344 | 92536 | p->u.z = p->aMem[0].z; |
| 92345 | 92537 | p->n = p->aMem[0].n; |
| 92346 | 92538 | return vdbeRecordCompareString; |
| | @@ -101668,11 +101860,13 @@ |
| 101668 | 101860 | if( x.flags & MEM_Int ){ |
| 101669 | 101861 | iKey = x.u.i; |
| 101670 | 101862 | }else |
| 101671 | 101863 | if( (x.flags & MEM_Real)==0 |
| 101672 | 101864 | || x.u.r < -9223372036854775808.0 |
| 101673 | | - || x.u.r > 9223372036854775807.0 |
| 101865 | + || x.u.r > 9223372036854774784.0 |
| 101866 | + /* ^^^^^^^^^^^^^^^^^^^^^-- same value as every other double |
| 101867 | + ** between 9223372036854774263.0 and 923372036854775295.0 */ |
| 101674 | 101868 | || (double)(iKey = sqlite3RealToI64(x.u.r))!=x.u.r |
| 101675 | 101869 | ){ |
| 101676 | 101870 | goto jump_to_p2; |
| 101677 | 101871 | } |
| 101678 | 101872 | goto notExistsWithKey; |
| | @@ -102352,18 +102546,21 @@ |
| 102352 | 102546 | } |
| 102353 | 102547 | pOut->u.i = v; |
| 102354 | 102548 | break; |
| 102355 | 102549 | } |
| 102356 | 102550 | |
| 102357 | | -/* Opcode: NullRow P1 * * * * |
| 102551 | +/* Opcode: NullRow P1 P2 * * * |
| 102358 | 102552 | ** |
| 102359 | | -** Move the cursor P1 to a null row. Any OP_Column operations |
| 102553 | +** Move the cursor P1 to a null row if P2 is 0. Any OP_Column operations |
| 102360 | 102554 | ** that occur while the cursor is on the null row will always |
| 102361 | 102555 | ** write a NULL. |
| 102362 | 102556 | ** |
| 102363 | 102557 | ** If cursor P1 is not previously opened, open it now to a special |
| 102364 | 102558 | ** pseudo-cursor that always returns NULL for every column. |
| 102559 | +** |
| 102560 | +** If P2 is not 0, then the nullRow flag on the pseudo-cursor is |
| 102561 | +** turned off. |
| 102365 | 102562 | */ |
| 102366 | 102563 | case OP_NullRow: { |
| 102367 | 102564 | VdbeCursor *pC; |
| 102368 | 102565 | |
| 102369 | 102566 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| | @@ -102376,11 +102573,11 @@ |
| 102376 | 102573 | pC->seekResult = 0; |
| 102377 | 102574 | pC->isTable = 1; |
| 102378 | 102575 | pC->noReuse = 1; |
| 102379 | 102576 | pC->uc.pCursor = sqlite3BtreeFakeValidCursor(); |
| 102380 | 102577 | } |
| 102381 | | - pC->nullRow = 1; |
| 102578 | + pC->nullRow = (pOp->p2==0); |
| 102382 | 102579 | pC->cacheStatus = CACHE_STALE; |
| 102383 | 102580 | if( pC->eCurType==CURTYPE_BTREE ){ |
| 102384 | 102581 | assert( pC->uc.pCursor!=0 ); |
| 102385 | 102582 | sqlite3BtreeClearCursor(pC->uc.pCursor); |
| 102386 | 102583 | } |
| | @@ -120900,10 +121097,11 @@ |
| 120900 | 121097 | /* Verify that constraints are still satisfied */ |
| 120901 | 121098 | if( pNew->pCheck!=0 |
| 120902 | 121099 | || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0) |
| 120903 | 121100 | || (pTab->tabFlags & TF_Strict)!=0 |
| 120904 | 121101 | ){ |
| 121102 | + pParse->colNamesSet = 1; |
| 120905 | 121103 | sqlite3NestedParse(pParse, |
| 120906 | 121104 | "SELECT CASE WHEN quick_check GLOB 'CHECK*'" |
| 120907 | 121105 | " THEN raise(ABORT,'CHECK constraint failed')" |
| 120908 | 121106 | " WHEN quick_check GLOB 'non-* value in*'" |
| 120909 | 121107 | " THEN raise(ABORT,'type mismatch on DEFAULT')" |
| | @@ -134337,11 +134535,11 @@ |
| 134337 | 134535 | } |
| 134338 | 134536 | if( argc==3 ){ |
| 134339 | 134537 | p2 = sqlite3_value_int64(argv[2]); |
| 134340 | 134538 | if( p2==0 && sqlite3_value_type(argv[2])==SQLITE_NULL ) return; |
| 134341 | 134539 | }else{ |
| 134342 | | - p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; |
| 134540 | + p2 = LARGEST_INT64; |
| 134343 | 134541 | } |
| 134344 | 134542 | if( p1==0 ){ |
| 134345 | 134543 | #ifdef SQLITE_SUBSTR_COMPATIBILITY |
| 134346 | 134544 | /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as |
| 134347 | 134545 | ** as substr(X,1,N) - it returns the first N characters of X. This |
| | @@ -135776,10 +135974,25 @@ |
| 135776 | 135974 | sqlite3_result_text(context, "?000", 4, SQLITE_STATIC); |
| 135777 | 135975 | } |
| 135778 | 135976 | } |
| 135779 | 135977 | #endif /* SQLITE_SOUNDEX */ |
| 135780 | 135978 | |
| 135979 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_BUILTIN_OOM_FUNCTION) |
| 135980 | +/* |
| 135981 | +** This SQL function just invokes sqlite3OomFault() and then returns |
| 135982 | +** NULL. Used for testing only. |
| 135983 | +*/ |
| 135984 | +static void oomFunc( |
| 135985 | + sqlite3_context *context, |
| 135986 | + int argc, |
| 135987 | + sqlite3_value **argv |
| 135988 | +){ |
| 135989 | + sqlite3 *db = sqlite3_context_db_handle(context); |
| 135990 | + sqlite3OomFault(db); |
| 135991 | +} |
| 135992 | +#endif /* SQLITE_DEBUG || SQLITE_BUILTIN_OOM_FUNCTION */ |
| 135993 | + |
| 135781 | 135994 | #ifndef SQLITE_OMIT_LOAD_EXTENSION |
| 135782 | 135995 | /* |
| 135783 | 135996 | ** A function that loads a shared-library extension then returns NULL. |
| 135784 | 135997 | */ |
| 135785 | 135998 | static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ |
| | @@ -137146,10 +137359,52 @@ |
| 137146 | 137359 | sqlite3_result_text(context, "{}", 2, SQLITE_STATIC); |
| 137147 | 137360 | } |
| 137148 | 137361 | } |
| 137149 | 137362 | #endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */ |
| 137150 | 137363 | |
| 137364 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_WALSTAT) |
| 137365 | +/* |
| 137366 | +** Implementation of sqlite_walstat(SCHEMA). |
| 137367 | +** |
| 137368 | +** Return JSON text that describes the current state of a WAL file. |
| 137369 | +** This function is for debugging and analysis only. It is not part |
| 137370 | +** of production builds. This function is not part of the SQLite API |
| 137371 | +** and is likely to change or be removed in future versions of SQLite. |
| 137372 | +*/ |
| 137373 | +static void walstatFunc( |
| 137374 | + sqlite3_context *context, |
| 137375 | + int argc, |
| 137376 | + sqlite3_value **argv |
| 137377 | +){ |
| 137378 | + sqlite3 *db = sqlite3_context_db_handle(context); |
| 137379 | + const char *zDbName; |
| 137380 | + sqlite3_str *pStr; |
| 137381 | + Btree *pBtree; |
| 137382 | + |
| 137383 | + zDbName = (const char*)sqlite3_value_text(argv[0]); |
| 137384 | + pBtree = sqlite3DbNameToBtree(db, zDbName); |
| 137385 | + if( pBtree ){ |
| 137386 | + Pager *pPager; |
| 137387 | + sqlite3BtreeEnter(pBtree); |
| 137388 | + pPager = sqlite3BtreePager(pBtree); |
| 137389 | + assert( pPager!=0 ); |
| 137390 | + pStr = sqlite3_str_new(db); |
| 137391 | + if( sqlite3_str_errcode(pStr) ){ |
| 137392 | + sqlite3_result_error_nomem(context); |
| 137393 | + }else{ |
| 137394 | + sqlite3_str_append(pStr, "{", 1); |
| 137395 | + sqlite3PagerWalStat(pPager, pStr); |
| 137396 | + sqlite3_str_append(pStr, "}", 1); |
| 137397 | + sqlite3_result_str(context, pStr, SQLITE_FINISH); |
| 137398 | + } |
| 137399 | + sqlite3BtreeLeave(pBtree); |
| 137400 | + }else{ |
| 137401 | + sqlite3_result_text(context, "{}", 2, SQLITE_STATIC); |
| 137402 | + } |
| 137403 | +} |
| 137404 | +#endif /* SQLITE_DEBUG || SQLITE_ENABLE_WALSTAT */ |
| 137405 | + |
| 137151 | 137406 | #ifdef SQLITE_DEBUG |
| 137152 | 137407 | /* |
| 137153 | 137408 | ** Implementation of fpdecode(x,y,z) function. |
| 137154 | 137409 | ** |
| 137155 | 137410 | ** x is a real number that is to be decoded. y is the precision. |
| | @@ -137306,10 +137561,11 @@ |
| 137306 | 137561 | #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC |
| 137307 | 137562 | INLINE_FUNC(sqlite_offset, 1, INLINEFUNC_sqlite_offset, 0 ), |
| 137308 | 137563 | #endif |
| 137309 | 137564 | #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT) |
| 137310 | 137565 | FUNCTION(sqlite_filestat, 1, 0, 0, filestatFunc ), |
| 137566 | + FUNCTION(sqlite_walstat, 1, 0, 0, walstatFunc ), |
| 137311 | 137567 | #endif |
| 137312 | 137568 | FUNCTION(ltrim, 1, 1, 0, trimFunc ), |
| 137313 | 137569 | FUNCTION(ltrim, 2, 1, 0, trimFunc ), |
| 137314 | 137570 | FUNCTION(rtrim, 1, 2, 0, trimFunc ), |
| 137315 | 137571 | FUNCTION(rtrim, 2, 2, 0, trimFunc ), |
| | @@ -137333,10 +137589,13 @@ |
| 137333 | 137589 | FUNCTION(char, -1, 0, 0, charFunc ), |
| 137334 | 137590 | FUNCTION(abs, 1, 0, 0, absFunc ), |
| 137335 | 137591 | #ifdef SQLITE_DEBUG |
| 137336 | 137592 | FUNCTION(fpdecode, 3, 0, 0, fpdecodeFunc ), |
| 137337 | 137593 | FUNCTION(parseuri, -1, 0, 0, parseuriFunc ), |
| 137594 | +#endif |
| 137595 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_BUILTIN_OOM_FUNCTION) |
| 137596 | + FUNCTION(oom, -1, 0, 0, oomFunc ), |
| 137338 | 137597 | #endif |
| 137339 | 137598 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 137340 | 137599 | FUNCTION(round, 1, 0, 0, roundFunc ), |
| 137341 | 137600 | FUNCTION(round, 2, 0, 0, roundFunc ), |
| 137342 | 137601 | #endif |
| | @@ -142714,11 +142973,11 @@ |
| 142714 | 142973 | void (*interruptx)(sqlite3*); |
| 142715 | 142974 | sqlite_int64 (*last_insert_rowid)(sqlite3*); |
| 142716 | 142975 | const char * (*libversion)(void); |
| 142717 | 142976 | int (*libversion_number)(void); |
| 142718 | 142977 | void *(*malloc)(int); |
| 142719 | | - char * (*mprintf)(const char*,...); |
| 142978 | + char *(SQLITE_CDECL*mprintf)(const char*,...); |
| 142720 | 142979 | int (*open)(const char*,sqlite3**); |
| 142721 | 142980 | int (*open16)(const void*,sqlite3**); |
| 142722 | 142981 | int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); |
| 142723 | 142982 | int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); |
| 142724 | 142983 | void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); |
| | @@ -142735,15 +142994,15 @@ |
| 142735 | 142994 | void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); |
| 142736 | 142995 | void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); |
| 142737 | 142996 | void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); |
| 142738 | 142997 | void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); |
| 142739 | 142998 | void (*result_value)(sqlite3_context*,sqlite3_value*); |
| 142740 | | - void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); |
| 142999 | + void *(*rollback_hook)(sqlite3*,void(*)(void*),void*); |
| 142741 | 143000 | int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, |
| 142742 | 143001 | const char*,const char*),void*); |
| 142743 | 143002 | void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); |
| 142744 | | - char * (*xsnprintf)(int,char*,const char*,...); |
| 143003 | + char *(SQLITE_CDECL*xsnprintf)(int,char*,const char*,...); |
| 142745 | 143004 | int (*step)(sqlite3_stmt*); |
| 142746 | 143005 | int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, |
| 142747 | 143006 | char const**,char const**,int*,int*,int*); |
| 142748 | 143007 | void (*thread_cleanup)(void); |
| 142749 | 143008 | int (*total_changes)(sqlite3*); |
| | @@ -142803,11 +143062,11 @@ |
| 142803 | 143062 | int (*vfs_register)(sqlite3_vfs*,int); |
| 142804 | 143063 | int (*vfs_unregister)(sqlite3_vfs*); |
| 142805 | 143064 | int (*xthreadsafe)(void); |
| 142806 | 143065 | void (*result_zeroblob)(sqlite3_context*,int); |
| 142807 | 143066 | void (*result_error_code)(sqlite3_context*,int); |
| 142808 | | - int (*test_control)(int, ...); |
| 143067 | + int (SQLITE_CDECL*test_control)(int, ...); |
| 142809 | 143068 | void (*randomness)(int,void*); |
| 142810 | 143069 | sqlite3 *(*context_db_handle)(sqlite3_context*); |
| 142811 | 143070 | int (*extended_result_codes)(sqlite3*,int); |
| 142812 | 143071 | int (*limit)(sqlite3*,int,int); |
| 142813 | 143072 | sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); |
| | @@ -142823,25 +143082,25 @@ |
| 142823 | 143082 | int (*create_function_v2)(sqlite3*,const char*,int,int,void*, |
| 142824 | 143083 | void (*xFunc)(sqlite3_context*,int,sqlite3_value**), |
| 142825 | 143084 | void (*xStep)(sqlite3_context*,int,sqlite3_value**), |
| 142826 | 143085 | void (*xFinal)(sqlite3_context*), |
| 142827 | 143086 | void(*xDestroy)(void*)); |
| 142828 | | - int (*db_config)(sqlite3*,int,...); |
| 143087 | + int (SQLITE_CDECL*db_config)(sqlite3*,int,...); |
| 142829 | 143088 | sqlite3_mutex *(*db_mutex)(sqlite3*); |
| 142830 | 143089 | int (*db_status)(sqlite3*,int,int*,int*,int); |
| 142831 | 143090 | int (*extended_errcode)(sqlite3*); |
| 142832 | | - void (*log)(int,const char*,...); |
| 143091 | + void (SQLITE_CDECL*log)(int,const char*,...); |
| 142833 | 143092 | sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); |
| 142834 | 143093 | const char *(*sourceid)(void); |
| 142835 | 143094 | int (*stmt_status)(sqlite3_stmt*,int,int); |
| 142836 | 143095 | int (*strnicmp)(const char*,const char*,int); |
| 142837 | 143096 | int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); |
| 142838 | 143097 | int (*wal_autocheckpoint)(sqlite3*,int); |
| 142839 | 143098 | int (*wal_checkpoint)(sqlite3*,const char*); |
| 142840 | 143099 | void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); |
| 142841 | 143100 | int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); |
| 142842 | | - int (*vtab_config)(sqlite3*,int op,...); |
| 143101 | + int (SQLITE_CDECL*vtab_config)(sqlite3*,int op,...); |
| 142843 | 143102 | int (*vtab_on_conflict)(sqlite3*); |
| 142844 | 143103 | /* Version 3.7.16 and later */ |
| 142845 | 143104 | int (*close_v2)(sqlite3*); |
| 142846 | 143105 | const char *(*db_filename)(sqlite3*,const char*); |
| 142847 | 143106 | int (*db_readonly)(sqlite3*,const char*); |
| | @@ -142906,11 +143165,11 @@ |
| 142906 | 143165 | int (*keyword_count)(void); |
| 142907 | 143166 | int (*keyword_name)(int,const char**,int*); |
| 142908 | 143167 | int (*keyword_check)(const char*,int); |
| 142909 | 143168 | sqlite3_str *(*str_new)(sqlite3*); |
| 142910 | 143169 | char *(*str_finish)(sqlite3_str*); |
| 142911 | | - void (*str_appendf)(sqlite3_str*, const char *zFormat, ...); |
| 143170 | + void (SQLITE_CDECL*str_appendf)(sqlite3_str*, const char *zFormat, ...); |
| 142912 | 143171 | void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list); |
| 142913 | 143172 | void (*str_append)(sqlite3_str*, const char *zIn, int N); |
| 142914 | 143173 | void (*str_appendall)(sqlite3_str*, const char *zIn); |
| 142915 | 143174 | void (*str_appendchar)(sqlite3_str*, int N, char C); |
| 142916 | 143175 | void (*str_reset)(sqlite3_str*); |
| | @@ -144551,11 +144810,11 @@ |
| 144551 | 144810 | /* ePragTyp: */ PragTyp_FLAG, |
| 144552 | 144811 | /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, |
| 144553 | 144812 | /* ColNames: */ 0, 0, |
| 144554 | 144813 | /* iArg: */ SQLITE_CountRows }, |
| 144555 | 144814 | #endif |
| 144556 | | -#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN |
| 144815 | +#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && defined(_WIN32) |
| 144557 | 144816 | {/* zName: */ "data_store_directory", |
| 144558 | 144817 | /* ePragTyp: */ PragTyp_DATA_STORE_DIRECTORY, |
| 144559 | 144818 | /* ePragFlg: */ PragFlg_NoColumns1, |
| 144560 | 144819 | /* ColNames: */ 0, 0, |
| 144561 | 144820 | /* iArg: */ 0 }, |
| | @@ -144974,11 +145233,11 @@ |
| 144974 | 145233 | /* ePragFlg: */ PragFlg_Result0|PragFlg_NoColumns1, |
| 144975 | 145234 | /* ColNames: */ 0, 0, |
| 144976 | 145235 | /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, |
| 144977 | 145236 | #endif |
| 144978 | 145237 | }; |
| 144979 | | -/* Number of pragmas: 68 on by default, 78 total. */ |
| 145238 | +/* Number of pragmas: 67 on by default, 78 total. */ |
| 144980 | 145239 | |
| 144981 | 145240 | /************** End of pragma.h **********************************************/ |
| 144982 | 145241 | /************** Continuing where we left off in pragma.c *********************/ |
| 144983 | 145242 | |
| 144984 | 145243 | /* |
| | @@ -145027,11 +145286,11 @@ |
| 145027 | 145286 | static const u8 iLength[] = {2, 2, 3, 5, 3, 4, 5, 4}; |
| 145028 | 145287 | static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 3, 2}; |
| 145029 | 145288 | /* on no off false yes true extra full */ |
| 145030 | 145289 | int i, n; |
| 145031 | 145290 | if( sqlite3Isdigit(*z) ){ |
| 145032 | | - return (u8)sqlite3Atoi(z); |
| 145291 | + return sqlite3Atoi(z)!=0; |
| 145033 | 145292 | } |
| 145034 | 145293 | n = sqlite3Strlen30(z); |
| 145035 | 145294 | for(i=0; i<ArraySize(iLength); i++){ |
| 145036 | 145295 | if( iLength[i]==n && sqlite3StrNICmp(&zText[iOffset[i]],z,n)==0 |
| 145037 | 145296 | && (!omitFull || iValue[i]<=1) |
| | @@ -146086,11 +146345,17 @@ |
| 146086 | 146345 | }else{ |
| 146087 | 146346 | if( !db->autoCommit ){ |
| 146088 | 146347 | sqlite3ErrorMsg(pParse, |
| 146089 | 146348 | "Safety level may not be changed inside a transaction"); |
| 146090 | 146349 | }else if( iDb!=1 ){ |
| 146091 | | - int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK; |
| 146350 | + int iLevel; |
| 146351 | + if( sqlite3Isdigit(zRight[0]) ){ |
| 146352 | + iLevel = sqlite3Atoi(zRight); |
| 146353 | + }else{ |
| 146354 | + iLevel = getSafetyLevel(zRight,0,1); |
| 146355 | + } |
| 146356 | + iLevel = (iLevel+1) & PAGER_SYNCHRONOUS_MASK; |
| 146092 | 146357 | if( iLevel==0 ) iLevel = 1; |
| 146093 | 146358 | pDb->safety_level = iLevel; |
| 146094 | 146359 | pDb->bSyncSet = 1; |
| 146095 | 146360 | setAllPagerFlags(db); |
| 146096 | 146361 | } |
| | @@ -149688,10 +149953,11 @@ |
| 149688 | 149953 | static int sqlite3ProcessJoin(Parse *pParse, Select *p){ |
| 149689 | 149954 | SrcList *pSrc; /* All tables in the FROM clause */ |
| 149690 | 149955 | int i, j; /* Loop counters */ |
| 149691 | 149956 | SrcItem *pLeft; /* Left table being joined */ |
| 149692 | 149957 | SrcItem *pRight; /* Right table being joined */ |
| 149958 | + int bSeenTFunc = 0; /* True if have seen table-valued function */ |
| 149693 | 149959 | |
| 149694 | 149960 | pSrc = p->pSrc; |
| 149695 | 149961 | pLeft = &pSrc->a[0]; |
| 149696 | 149962 | pRight = &pLeft[1]; |
| 149697 | 149963 | for(i=0; i<pSrc->nSrc-1; i++, pRight++, pLeft++){ |
| | @@ -149830,11 +150096,22 @@ |
| 149830 | 150096 | pRight->u3.pOn = 0; |
| 149831 | 150097 | pRight->fg.isOn = 1; |
| 149832 | 150098 | p->selFlags |= SF_OnToWhere; |
| 149833 | 150099 | } |
| 149834 | 150100 | |
| 149835 | | - if( pRight->fg.isTabFunc && joinType==EP_OuterON && pRight->u1.pFuncArg ){ |
| 150101 | + if( bSeenTFunc==0 ){ |
| 150102 | + bSeenTFunc = (pLeft->fg.isTabFunc && pLeft->u1.pFuncArg); |
| 150103 | + } |
| 150104 | + |
| 150105 | + /* We also need to call sqlite3SelectCheckOnClauses() to verify that |
| 150106 | + ** table-valued function arguments do not illegally refer to any tables to |
| 150107 | + ** their right. This test is required if either (a) there is a RIGHT JOIN |
| 150108 | + ** in the SrcList, or (b) there is a LEFT JOIN to the right of a |
| 150109 | + ** table-valued function. */ |
| 150110 | + if( (pRight->fg.isTabFunc && joinType==EP_OuterON && pRight->u1.pFuncArg) |
| 150111 | + || (bSeenTFunc && joinType==EP_OuterON) |
| 150112 | + ){ |
| 149836 | 150113 | p->selFlags |= SF_OnToWhere; |
| 149837 | 150114 | } |
| 149838 | 150115 | } |
| 149839 | 150116 | return 0; |
| 149840 | 150117 | } |
| | @@ -150939,10 +151216,13 @@ |
| 150939 | 151216 | /* Open any cursors needed for sorter-reference expressions */ |
| 150940 | 151217 | for(i=0; i<pSort->nDefer; i++){ |
| 150941 | 151218 | Table *pTab = pSort->aDefer[i].pTab; |
| 150942 | 151219 | int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); |
| 150943 | 151220 | sqlite3OpenTable(pParse, pSort->aDefer[i].iCsr, iDb, pTab, OP_OpenRead); |
| 151221 | + sqlite3VdbeAddOp2(v, OP_Rewind, pSort->aDefer[i].iCsr, |
| 151222 | + sqlite3VdbeCurrentAddr(v)+1); |
| 151223 | + VdbeCoverage(v); |
| 150944 | 151224 | nRefKey = MAX(nRefKey, pSort->aDefer[i].nKey); |
| 150945 | 151225 | } |
| 150946 | 151226 | #endif |
| 150947 | 151227 | |
| 150948 | 151228 | iTab = pSort->iECursor; |
| | @@ -156638,11 +156918,11 @@ |
| 156638 | 156918 | ** Type used for Walker callbacks by selectCheckOnClauses(). |
| 156639 | 156919 | */ |
| 156640 | 156920 | typedef struct CheckOnCtx CheckOnCtx; |
| 156641 | 156921 | struct CheckOnCtx { |
| 156642 | 156922 | SrcList *pSrc; /* SrcList for this context */ |
| 156643 | | - int iJoin; /* Cursors must be left of this one, if not zero */ |
| 156923 | + int iJoin; /* Cursors must be left of this one, if not negative */ |
| 156644 | 156924 | int bFuncArg; /* True for table-function arg */ |
| 156645 | 156925 | CheckOnCtx *pParent; /* Parent context */ |
| 156646 | 156926 | }; |
| 156647 | 156927 | |
| 156648 | 156928 | /* |
| | @@ -156671,15 +156951,15 @@ |
| 156671 | 156951 | /* If CheckOnCtx.iJoin is already set, then fall through and process |
| 156672 | 156952 | ** this expression node as normal. Or, if CheckOnCtx.iJoin is still 0, |
| 156673 | 156953 | ** set it to the cursor number of the RHS of the join to which this |
| 156674 | 156954 | ** ON expression was attached and then iterate through the entire |
| 156675 | 156955 | ** expression. */ |
| 156676 | | - assert( pCtx->iJoin==0 || pCtx->iJoin==pExpr->w.iJoin ); |
| 156677 | | - if( pCtx->iJoin==0 ){ |
| 156956 | + assert( pCtx->iJoin<0 || pCtx->iJoin==pExpr->w.iJoin ); |
| 156957 | + if( pCtx->iJoin<0 ){ |
| 156678 | 156958 | pCtx->iJoin = pExpr->w.iJoin; |
| 156679 | 156959 | sqlite3WalkExprNN(pWalker, pExpr); |
| 156680 | | - pCtx->iJoin = 0; |
| 156960 | + pCtx->iJoin = -1; |
| 156681 | 156961 | return WRC_Prune; |
| 156682 | 156962 | } |
| 156683 | 156963 | } |
| 156684 | 156964 | |
| 156685 | 156965 | if( pExpr->op==TK_COLUMN ){ |
| | @@ -156693,11 +156973,11 @@ |
| 156693 | 156973 | int nSrc = pSrc->nSrc; |
| 156694 | 156974 | int ii; |
| 156695 | 156975 | for(ii=0; ii<nSrc && pSrc->a[ii].iCursor!=iTab; ii++){} |
| 156696 | 156976 | if( ii<nSrc ){ |
| 156697 | 156977 | /* pSrc is the FROM clause that contains iTab */ |
| 156698 | | - if( pCtx->iJoin ){ |
| 156978 | + if( pCtx->iJoin>=0 ){ |
| 156699 | 156979 | for(ii--; ii>=0 && pSrc->a[ii].iCursor!=pCtx->iJoin; ii--){} |
| 156700 | 156980 | if( ii>=0 ){ |
| 156701 | 156981 | /* Table iJoin appears to the left of table iTab in the SrcList. |
| 156702 | 156982 | ** Therefore the expression refers to a table to its right. */ |
| 156703 | 156983 | sqlite3ErrorMsg(pWalker->pParse, |
| | @@ -156725,10 +157005,11 @@ |
| 156725 | 157005 | }else{ |
| 156726 | 157006 | CheckOnCtx sCtx; |
| 156727 | 157007 | memset(&sCtx, 0, sizeof(sCtx)); |
| 156728 | 157008 | sCtx.pSrc = pSelect->pSrc; |
| 156729 | 157009 | sCtx.pParent = pCtx; |
| 157010 | + sCtx.iJoin = -1; |
| 156730 | 157011 | pWalker->u.pCheckOnCtx = &sCtx; |
| 156731 | 157012 | sqlite3WalkSelect(pWalker, pSelect); |
| 156732 | 157013 | pWalker->u.pCheckOnCtx = pCtx; |
| 156733 | 157014 | pSelect->selFlags &= ~SF_OnToWhere; |
| 156734 | 157015 | return WRC_Prune; |
| | @@ -156750,24 +157031,45 @@ |
| 156750 | 157031 | w.xExprCallback = selectCheckOnClausesExpr; |
| 156751 | 157032 | w.xSelectCallback = selectCheckOnClausesSelect; |
| 156752 | 157033 | w.u.pCheckOnCtx = &sCtx; |
| 156753 | 157034 | memset(&sCtx, 0, sizeof(sCtx)); |
| 156754 | 157035 | sCtx.pSrc = pSelect->pSrc; |
| 157036 | + sCtx.iJoin = -1; |
| 156755 | 157037 | sqlite3WalkExpr(&w, pSelect->pWhere); |
| 156756 | 157038 | pSelect->selFlags &= ~SF_OnToWhere; |
| 156757 | 157039 | |
| 156758 | 157040 | /* Check for any table-function args that are attached to virtual tables |
| 156759 | | - ** on the RHS of an outer join. They are subject to the same constraints |
| 156760 | | - ** as ON clauses. */ |
| 157041 | + ** on the RHS of an outer join. They are subject to similar constraints |
| 157042 | + ** as ON clauses. Specifically: |
| 157043 | + ** |
| 157044 | + ** * If the table-valued function is to the left of any RIGHT JOIN, or if |
| 157045 | + ** it is the RHS of a RIGHT JOIN, then the table-valued function arguments |
| 157046 | + ** may not refer to any tables to the right of this one. |
| 157047 | + ** |
| 157048 | + ** * If the table-valued function is to the left of a LEFT JOIN, then it |
| 157049 | + ** may not refer to any table that occurs to the right of the LEFT JOIN. |
| 157050 | + */ |
| 156761 | 157051 | sCtx.bFuncArg = 1; |
| 156762 | 157052 | for(ii=0; ii<pSelect->pSrc->nSrc; ii++){ |
| 156763 | 157053 | SrcItem *pItem = &pSelect->pSrc->a[ii]; |
| 156764 | | - if( pItem->fg.isTabFunc |
| 156765 | | - && (pItem->fg.jointype & JT_OUTER) |
| 156766 | | - ){ |
| 156767 | | - sCtx.iJoin = pItem->iCursor; |
| 156768 | | - sqlite3WalkExprList(&w, pItem->u1.pFuncArg); |
| 157054 | + if( pItem->fg.isTabFunc ){ |
| 157055 | + sCtx.iJoin = -1; |
| 157056 | + if( (pItem->fg.jointype & (JT_LTORJ|JT_RIGHT)) ){ |
| 157057 | + sCtx.iJoin = pItem->iCursor; |
| 157058 | + }else{ |
| 157059 | + int jj; |
| 157060 | + for(jj=ii+1; jj<pSelect->pSrc->nSrc; jj++){ |
| 157061 | + SrcItem *pItem2 = &pSelect->pSrc->a[jj]; |
| 157062 | + if( pItem2->fg.jointype & JT_OUTER ){ |
| 157063 | + sCtx.iJoin = pItem2[-1].iCursor; |
| 157064 | + break; |
| 157065 | + } |
| 157066 | + } |
| 157067 | + } |
| 157068 | + if( sCtx.iJoin>=0 ){ |
| 157069 | + sqlite3WalkExprList(&w, pItem->u1.pFuncArg); |
| 157070 | + } |
| 156769 | 157071 | } |
| 156770 | 157072 | } |
| 156771 | 157073 | } |
| 156772 | 157074 | |
| 156773 | 157075 | /* |
| | @@ -160077,12 +160379,11 @@ |
| 160077 | 160379 | ** it has been converted into REAL. |
| 160078 | 160380 | */ |
| 160079 | 160381 | static SQLITE_NOINLINE void columnDefaultUncommonCase( |
| 160080 | 160382 | Vdbe *v, /* Byte code under construction */ |
| 160081 | 160383 | Table *pTab, /* The table */ |
| 160082 | | - Column *pCol, /* Which column of the table */ |
| 160083 | | - int iReg /* Register in which results are stored */ |
| 160384 | + Column *pCol /* Which column of the table */ |
| 160084 | 160385 | ){ |
| 160085 | 160386 | sqlite3_value *pValue = 0; |
| 160086 | 160387 | u8 enc = ENC(sqlite3VdbeDb(v)); |
| 160087 | 160388 | Parse *pParse = sqlite3VdbeParser(v); |
| 160088 | 160389 | assert( !IsView(pTab) ); |
| | @@ -160090,15 +160391,10 @@ |
| 160090 | 160391 | sqlite3ColumnExprAuth(pTab,pCol,pParse), enc, |
| 160091 | 160392 | pCol->affinity, &pValue); |
| 160092 | 160393 | if( pValue ){ |
| 160093 | 160394 | sqlite3VdbeAppendP4(v, pValue, P4_MEM); |
| 160094 | 160395 | } |
| 160095 | | -#ifndef SQLITE_OMIT_FLOATING_POINT |
| 160096 | | - if( pCol->affinity==SQLITE_AFF_REAL ){ |
| 160097 | | - sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); |
| 160098 | | - } |
| 160099 | | -#endif |
| 160100 | 160396 | } |
| 160101 | 160397 | SQLITE_PRIVATE void sqlite3ColumnDefault( |
| 160102 | 160398 | Vdbe *v, /* Byte code under construction */ |
| 160103 | 160399 | Table *pTab, /* The table */ |
| 160104 | 160400 | int i, /* Which column of the table */ |
| | @@ -160107,11 +160403,11 @@ |
| 160107 | 160403 | Column *pCol; |
| 160108 | 160404 | assert( pTab!=0 ); |
| 160109 | 160405 | assert( pTab->nCol>i ); |
| 160110 | 160406 | pCol = &pTab->aCol[i]; |
| 160111 | 160407 | if( pCol->iDflt ){ |
| 160112 | | - columnDefaultUncommonCase(v,pTab,pCol,iReg); |
| 160408 | + columnDefaultUncommonCase(v,pTab,pCol); |
| 160113 | 160409 | } |
| 160114 | 160410 | #ifndef SQLITE_OMIT_FLOATING_POINT |
| 160115 | 160411 | if( pCol->affinity==SQLITE_AFF_REAL ){ |
| 160116 | 160412 | sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); |
| 160117 | 160413 | } |
| | @@ -165194,21 +165490,11 @@ |
| 165194 | 165490 | ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ |
| 165195 | 165491 | testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); |
| 165196 | 165492 | testcase( pTerm->wtFlags & TERM_VIRTUAL ); |
| 165197 | 165493 | r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j); |
| 165198 | 165494 | if( r1!=regBase+j ){ |
| 165199 | | - /* If this routine is being called as part of a RIGHT JOIN loop, then |
| 165200 | | - ** register r1 may be used by the body of the loop that the RIGHT JOIN |
| 165201 | | - ** will jump back into (e.g. if pTerm is a sub-query). This can cause |
| 165202 | | - ** problems if (say) the affinity of r1 is modified by the caller of |
| 165203 | | - ** this routine. So, always take a copy of the value in this case. */ |
| 165204 | | - if( nReg==1 && pParse->withinRJSubrtn==0 ){ |
| 165205 | | - sqlite3ReleaseTempReg(pParse, regBase); |
| 165206 | | - regBase = r1; |
| 165207 | | - }else{ |
| 165208 | | - sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); |
| 165209 | | - } |
| 165495 | + sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); |
| 165210 | 165496 | } |
| 165211 | 165497 | if( pTerm->eOperator & WO_IN ){ |
| 165212 | 165498 | if( pTerm->pExpr->flags & EP_xIsSelect ){ |
| 165213 | 165499 | /* No affinity ever needs to be (or should be) applied to a value |
| 165214 | 165500 | ** from the RHS of an "? IN (SELECT ...)" expression. The |
| | @@ -165824,10 +166110,13 @@ |
| 165824 | 166110 | ); |
| 165825 | 166111 | if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ |
| 165826 | 166112 | pLevel->iLeftJoin = ++pParse->nMem; |
| 165827 | 166113 | sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); |
| 165828 | 166114 | VdbeComment((v, "init LEFT JOIN match flag")); |
| 166115 | + if( pTabItem->fg.viaCoroutine ){ |
| 166116 | + sqlite3VdbeAddOp2(v, OP_NullRow, pTabItem->iCursor, 1); |
| 166117 | + } |
| 165829 | 166118 | } |
| 165830 | 166119 | |
| 165831 | 166120 | /* Special case of a FROM clause subquery implemented as a co-routine */ |
| 165832 | 166121 | if( pTabItem->fg.viaCoroutine ){ |
| 165833 | 166122 | int regYield; |
| | @@ -176880,21 +177169,21 @@ |
| 176880 | 177169 | sqlite3VdbeChangeP5(v, pLevel->p5); |
| 176881 | 177170 | VdbeCoverage(v); |
| 176882 | 177171 | VdbeCoverageIf(v, pLevel->op==OP_Next); |
| 176883 | 177172 | VdbeCoverageIf(v, pLevel->op==OP_Prev); |
| 176884 | 177173 | VdbeCoverageIf(v, pLevel->op==OP_VNext); |
| 176885 | | - if( pLevel->regBignull ){ |
| 176886 | | - sqlite3VdbeResolveLabel(v, pLevel->addrBignull); |
| 176887 | | - sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1); |
| 176888 | | - VdbeCoverage(v); |
| 176889 | | - } |
| 176890 | 177174 | #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT |
| 176891 | 177175 | if( addrSeek ){ |
| 176892 | 177176 | sqlite3VdbeJumpHere(v, addrSeek); |
| 176893 | 177177 | addrSeek = 0; |
| 176894 | 177178 | } |
| 176895 | 177179 | #endif |
| 177180 | + if( pLevel->regBignull ){ |
| 177181 | + sqlite3VdbeResolveLabel(v, pLevel->addrBignull); |
| 177182 | + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1); |
| 177183 | + VdbeCoverage(v); |
| 177184 | + } |
| 176896 | 177185 | } |
| 176897 | 177186 | if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){ |
| 176898 | 177187 | struct InLoop *pIn; |
| 176899 | 177188 | int j; |
| 176900 | 177189 | sqlite3VdbeResolveLabel(v, pLevel->addrNxt); |
| | @@ -177517,10 +177806,11 @@ |
| 177517 | 177806 | ){ |
| 177518 | 177807 | struct CallCount *p; |
| 177519 | 177808 | UNUSED_PARAMETER(nArg); assert( nArg==0 ); |
| 177520 | 177809 | UNUSED_PARAMETER(apArg); |
| 177521 | 177810 | p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); |
| 177811 | + assert( p!=0 ); |
| 177522 | 177812 | p->nStep++; |
| 177523 | 177813 | } |
| 177524 | 177814 | static void percent_rankValueFunc(sqlite3_context *pCtx){ |
| 177525 | 177815 | struct CallCount *p; |
| 177526 | 177816 | p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); |
| | @@ -177562,10 +177852,11 @@ |
| 177562 | 177852 | ){ |
| 177563 | 177853 | struct CallCount *p; |
| 177564 | 177854 | UNUSED_PARAMETER(nArg); assert( nArg==0 ); |
| 177565 | 177855 | UNUSED_PARAMETER(apArg); |
| 177566 | 177856 | p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); |
| 177857 | + assert( p!=0 ); |
| 177567 | 177858 | p->nStep++; |
| 177568 | 177859 | } |
| 177569 | 177860 | static void cume_distValueFunc(sqlite3_context *pCtx){ |
| 177570 | 177861 | struct CallCount *p; |
| 177571 | 177862 | p = (struct CallCount*)sqlite3_aggregate_context(pCtx, 0); |
| | @@ -177618,10 +177909,11 @@ |
| 177618 | 177909 | ){ |
| 177619 | 177910 | struct NtileCtx *p; |
| 177620 | 177911 | assert( nArg==1 ); UNUSED_PARAMETER(nArg); |
| 177621 | 177912 | UNUSED_PARAMETER(apArg); |
| 177622 | 177913 | p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); |
| 177914 | + assert( p!=0 ); |
| 177623 | 177915 | p->iRow++; |
| 177624 | 177916 | } |
| 177625 | 177917 | static void ntileValueFunc(sqlite3_context *pCtx){ |
| 177626 | 177918 | struct NtileCtx *p; |
| 177627 | 177919 | p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); |
| | @@ -184558,10 +184850,11 @@ |
| 184558 | 184850 | if( yymsp[-5].minor.yy203 ){ |
| 184559 | 184851 | SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1]; |
| 184560 | 184852 | SrcItem *pOld = yymsp[-3].minor.yy203->a; |
| 184561 | 184853 | assert( pOld->fg.fixedSchema==0 ); |
| 184562 | 184854 | pNew->zName = pOld->zName; |
| 184855 | + pOld->zName = 0; |
| 184563 | 184856 | assert( pOld->fg.fixedSchema==0 ); |
| 184564 | 184857 | if( pOld->fg.isSubquery ){ |
| 184565 | 184858 | pNew->fg.isSubquery = 1; |
| 184566 | 184859 | pNew->u4.pSubq = pOld->u4.pSubq; |
| 184567 | 184860 | pOld->u4.pSubq = 0; |
| | @@ -184577,12 +184870,17 @@ |
| 184577 | 184870 | if( pOld->fg.isTabFunc ){ |
| 184578 | 184871 | pNew->u1.pFuncArg = pOld->u1.pFuncArg; |
| 184579 | 184872 | pOld->u1.pFuncArg = 0; |
| 184580 | 184873 | pOld->fg.isTabFunc = 0; |
| 184581 | 184874 | pNew->fg.isTabFunc = 1; |
| 184875 | + }else if( pOld->fg.isIndexedBy ){ |
| 184876 | + pNew->u1.zIndexedBy = pOld->u1.zIndexedBy; |
| 184877 | + pOld->u1.zIndexedBy = 0; |
| 184878 | + pOld->fg.isIndexedBy = 0; |
| 184879 | + pNew->fg.isIndexedBy = 1; |
| 184582 | 184880 | } |
| 184583 | | - pOld->zName = 0; |
| 184881 | + pNew->fg.notIndexed = pOld->fg.notIndexed; |
| 184584 | 184882 | } |
| 184585 | 184883 | sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy203); |
| 184586 | 184884 | }else{ |
| 184587 | 184885 | Select *pSubquery; |
| 184588 | 184886 | sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203); |
| | @@ -188939,11 +189237,11 @@ |
| 188939 | 189237 | |
| 188940 | 189238 | /* |
| 188941 | 189239 | ** This is the default collating function named "BINARY" which is always |
| 188942 | 189240 | ** available. |
| 188943 | 189241 | */ |
| 188944 | | -static int binCollFunc( |
| 189242 | +SQLITE_PRIVATE int sqlite3BinaryCompare( |
| 188945 | 189243 | void *NotUsed, |
| 188946 | 189244 | int nKey1, const void *pKey1, |
| 188947 | 189245 | int nKey2, const void *pKey2 |
| 188948 | 189246 | ){ |
| 188949 | 189247 | int rc, n; |
| | @@ -188971,20 +189269,23 @@ |
| 188971 | 189269 | ){ |
| 188972 | 189270 | const u8 *pK1 = (const u8*)pKey1; |
| 188973 | 189271 | const u8 *pK2 = (const u8*)pKey2; |
| 188974 | 189272 | while( nKey1 && pK1[nKey1-1]==' ' ) nKey1--; |
| 188975 | 189273 | while( nKey2 && pK2[nKey2-1]==' ' ) nKey2--; |
| 188976 | | - return binCollFunc(pUser, nKey1, pKey1, nKey2, pKey2); |
| 189274 | + return sqlite3BinaryCompare(pUser, nKey1, pKey1, nKey2, pKey2); |
| 188977 | 189275 | } |
| 188978 | 189276 | |
| 188979 | 189277 | /* |
| 188980 | 189278 | ** Return true if CollSeq is the default built-in BINARY. |
| 188981 | 189279 | */ |
| 189280 | +#if !SQLITE_USES_INLINE |
| 188982 | 189281 | SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq *p){ |
| 188983 | | - assert( p==0 || p->xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 ); |
| 188984 | | - return p==0 || p->xCmp==binCollFunc; |
| 189282 | + assert( p==0 || p->xCmp!=sqlite3BinaryCompare |
| 189283 | + || strcmp(p->zName,"BINARY")==0 ); |
| 189284 | + return p==0 || p->xCmp==sqlite3BinaryCompare; |
| 188985 | 189285 | } |
| 189286 | +#endif |
| 188986 | 189287 | |
| 188987 | 189288 | /* |
| 188988 | 189289 | ** Another built-in collating sequence: NOCASE. |
| 188989 | 189290 | ** |
| 188990 | 189291 | ** This collating sequence is intended to be used for "case independent |
| | @@ -189932,11 +190233,11 @@ |
| 189932 | 190233 | p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0); |
| 189933 | 190234 | if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){ |
| 189934 | 190235 | if( db->nVdbeActive ){ |
| 189935 | 190236 | sqlite3ErrorWithMsg(db, SQLITE_BUSY, |
| 189936 | 190237 | "unable to delete/modify user-function due to active statements"); |
| 189937 | | - assert( !db->mallocFailed ); |
| 190238 | + assert( !db->mallocFailed || db->nVdbeExec>0 ); |
| 189938 | 190239 | return SQLITE_BUSY; |
| 189939 | 190240 | }else{ |
| 189940 | 190241 | sqlite3ExpirePreparedStatements(db, 0); |
| 189941 | 190242 | } |
| 189942 | 190243 | }else if( xSFunc==0 && xFinal==0 ){ |
| | @@ -191454,13 +191755,16 @@ |
| 191454 | 191755 | ** conversions. The only error that can occur here is a malloc() failure. |
| 191455 | 191756 | ** |
| 191456 | 191757 | ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating |
| 191457 | 191758 | ** functions: |
| 191458 | 191759 | */ |
| 191459 | | - createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0); |
| 191460 | | - createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0); |
| 191461 | | - createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0); |
| 191760 | + createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, |
| 191761 | + sqlite3BinaryCompare, 0); |
| 191762 | + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, |
| 191763 | + sqlite3BinaryCompare, 0); |
| 191764 | + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, |
| 191765 | + sqlite3BinaryCompare, 0); |
| 191462 | 191766 | createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); |
| 191463 | 191767 | createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0); |
| 191464 | 191768 | if( db->mallocFailed ){ |
| 191465 | 191769 | goto opendb_out; |
| 191466 | 191770 | } |
| | @@ -198200,12 +198504,12 @@ |
| 198200 | 198504 | Fts3Table *pTab = 0; |
| 198201 | 198505 | Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ |
| 198202 | 198506 | const char *zStart = "<b>"; |
| 198203 | 198507 | const char *zEnd = "</b>"; |
| 198204 | 198508 | const char *zEllipsis = "<b>...</b>"; |
| 198205 | | - int iCol = -1; |
| 198206 | | - int nToken = 15; /* Default number of tokens in snippet */ |
| 198509 | + i64 iCol = -1; |
| 198510 | + i64 nToken = 15; /* Default number of tokens in snippet */ |
| 198207 | 198511 | |
| 198208 | 198512 | /* There must be at least one argument passed to this function (otherwise |
| 198209 | 198513 | ** the non-overloaded version would have been called instead of this one). |
| 198210 | 198514 | */ |
| 198211 | 198515 | assert( nVal>=1 ); |
| | @@ -198217,13 +198521,13 @@ |
| 198217 | 198521 | } |
| 198218 | 198522 | if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return; |
| 198219 | 198523 | pTab = (Fts3Table *)pCsr->base.pVtab; |
| 198220 | 198524 | |
| 198221 | 198525 | switch( nVal ){ |
| 198222 | | - case 6: nToken = sqlite3_value_int(apVal[5]); |
| 198526 | + case 6: nToken = sqlite3_value_int64(apVal[5]); |
| 198223 | 198527 | /* no break */ deliberate_fall_through |
| 198224 | | - case 5: iCol = sqlite3_value_int(apVal[4]); |
| 198528 | + case 5: iCol = sqlite3_value_int64(apVal[4]); |
| 198225 | 198529 | /* no break */ deliberate_fall_through |
| 198226 | 198530 | case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]); |
| 198227 | 198531 | /* no break */ deliberate_fall_through |
| 198228 | 198532 | case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]); |
| 198229 | 198533 | /* no break */ deliberate_fall_through |
| | @@ -198232,10 +198536,13 @@ |
| 198232 | 198536 | if( !zEllipsis || !zEnd || !zStart ){ |
| 198233 | 198537 | sqlite3_result_error_nomem(pContext); |
| 198234 | 198538 | }else if( nToken==0 || iCol>=pTab->nColumn ){ |
| 198235 | 198539 | sqlite3_result_text(pContext, "", -1, SQLITE_STATIC); |
| 198236 | 198540 | }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ |
| 198541 | + if( iCol<0 ) iCol = -1; |
| 198542 | + if( nToken<-64 ) nToken = -64; |
| 198543 | + if( nToken>64 ) nToken = 64; |
| 198237 | 198544 | sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken); |
| 198238 | 198545 | } |
| 198239 | 198546 | } |
| 198240 | 198547 | |
| 198241 | 198548 | /* |
| | @@ -203595,14 +203902,15 @@ |
| 203595 | 203902 | } |
| 203596 | 203903 | |
| 203597 | 203904 | if( c->iOffset>iStartOffset ){ |
| 203598 | 203905 | int n = c->iOffset-iStartOffset; |
| 203599 | 203906 | if( n>c->nAllocated ){ |
| 203907 | + i64 nNew = n + 20; |
| 203600 | 203908 | char *pNew; |
| 203601 | | - c->nAllocated = n+20; |
| 203602 | | - pNew = sqlite3_realloc64(c->zToken, c->nAllocated); |
| 203909 | + pNew = sqlite3_realloc64(c->zToken, nNew); |
| 203603 | 203910 | if( !pNew ) return SQLITE_NOMEM; |
| 203911 | + c->nAllocated = (int)nNew; |
| 203604 | 203912 | c->zToken = pNew; |
| 203605 | 203913 | } |
| 203606 | 203914 | porter_stemmer(&z[iStartOffset], n, c->zToken, pnBytes); |
| 203607 | 203915 | *pzToken = c->zToken; |
| 203608 | 203916 | *piStartOffset = iStartOffset; |
| | @@ -210126,42 +210434,46 @@ |
| 210126 | 210434 | ); |
| 210127 | 210435 | if( rc==SQLITE_OK ){ |
| 210128 | 210436 | rc = sqlite3Fts3SegReaderStart(p, &csr, &filter); |
| 210129 | 210437 | } |
| 210130 | 210438 | |
| 210131 | | - if( rc==SQLITE_OK ){ |
| 210132 | | - while( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){ |
| 210133 | | - char *pCsr = csr.aDoclist; |
| 210134 | | - char *pEnd = &pCsr[csr.nDoclist]; |
| 210135 | | - |
| 210136 | | - i64 iDocid = 0; |
| 210137 | | - i64 iCol = 0; |
| 210138 | | - u64 iPos = 0; |
| 210139 | | - |
| 210140 | | - pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid); |
| 210141 | | - while( pCsr<pEnd ){ |
| 210142 | | - u64 iVal = 0; |
| 210143 | | - pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal); |
| 210144 | | - if( pCsr<pEnd ){ |
| 210145 | | - if( iVal==0 || iVal==1 ){ |
| 210146 | | - iCol = 0; |
| 210147 | | - iPos = 0; |
| 210148 | | - if( iVal ){ |
| 210149 | | - pCsr += sqlite3Fts3GetVarint(pCsr, &iCol); |
| 210150 | | - }else{ |
| 210151 | | - pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal); |
| 210152 | | - if( p->bDescIdx ){ |
| 210153 | | - iDocid = (i64)((u64)iDocid - iVal); |
| 210154 | | - }else{ |
| 210155 | | - iDocid = (i64)((u64)iDocid + iVal); |
| 210156 | | - } |
| 210157 | | - } |
| 210158 | | - }else{ |
| 210159 | | - iPos += (iVal - 2); |
| 210439 | + while( rc==SQLITE_OK && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p,&csr)) ){ |
| 210440 | + char *pCsr = csr.aDoclist; |
| 210441 | + char *pEnd = &pCsr[csr.nDoclist]; |
| 210442 | + |
| 210443 | + i64 iDocid = 0; |
| 210444 | + int iCol = 0; |
| 210445 | + u64 iPos = 0; |
| 210446 | + |
| 210447 | + rc = SQLITE_OK; |
| 210448 | + pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid); |
| 210449 | + while( pCsr<pEnd ){ |
| 210450 | + u64 iVal = 0; |
| 210451 | + pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal); |
| 210452 | + if( pCsr<pEnd ){ |
| 210453 | + if( iVal==0 || iVal==1 ){ |
| 210454 | + iCol = 0; |
| 210455 | + iPos = 0; |
| 210456 | + if( iVal ){ |
| 210457 | + pCsr += fts3GetVarint32(pCsr, &iCol); |
| 210458 | + }else{ |
| 210459 | + pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal); |
| 210460 | + if( p->bDescIdx ){ |
| 210461 | + iDocid = (i64)((u64)iDocid - iVal); |
| 210462 | + }else{ |
| 210463 | + iDocid = (i64)((u64)iDocid + iVal); |
| 210464 | + } |
| 210465 | + } |
| 210466 | + }else{ |
| 210467 | + iPos += (iVal - 2); |
| 210468 | + if( iPos>0x7FFFFFFF ){ |
| 210469 | + rc = SQLITE_CORRUPT_VTAB; |
| 210470 | + break; |
| 210471 | + }else{ |
| 210160 | 210472 | cksum = cksum ^ fts3ChecksumEntry( |
| 210161 | 210473 | csr.zTerm, csr.nTerm, iLangid, iIndex, iDocid, |
| 210162 | | - (int)iCol, (int)iPos |
| 210474 | + iCol, (int)iPos |
| 210163 | 210475 | ); |
| 210164 | 210476 | } |
| 210165 | 210477 | } |
| 210166 | 210478 | } |
| 210167 | 210479 | } |
| | @@ -212193,13 +212505,12 @@ |
| 212193 | 212505 | if( !pCsr->pExpr ){ |
| 212194 | 212506 | sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); |
| 212195 | 212507 | return; |
| 212196 | 212508 | } |
| 212197 | 212509 | |
| 212198 | | - /* Limit the snippet length to 64 tokens. */ |
| 212199 | | - if( nToken<-64 ) nToken = -64; |
| 212200 | | - if( nToken>+64 ) nToken = +64; |
| 212510 | + /* The snippet length should already have been limited to 64 tokens. */ |
| 212511 | + assert( nToken>=-64 && nToken<=64 ); |
| 212201 | 212512 | |
| 212202 | 212513 | for(nSnippet=1; 1; nSnippet++){ |
| 212203 | 212514 | |
| 212204 | 212515 | int iSnip; /* Loop counter 0..nSnippet-1 */ |
| 212205 | 212516 | u64 mCovered = 0; /* Bitmask of phrases covered by snippet */ |
| | @@ -215936,11 +216247,14 @@ |
| 215936 | 216247 | jsonStringTooDeep(pOut); |
| 215937 | 216248 | } |
| 215938 | 216249 | while( pOut->eErr==0 ){ |
| 215939 | 216250 | jsonPrettyIndent(pPretty); |
| 215940 | 216251 | j = jsonTranslateBlobToPrettyText(pPretty, j); |
| 215941 | | - if( j>=iEnd ) break; |
| 216252 | + if( j>=iEnd ){ |
| 216253 | + if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; |
| 216254 | + break; |
| 216255 | + } |
| 215942 | 216256 | jsonAppendRawNZ(pOut, ",\n", 2); |
| 215943 | 216257 | } |
| 215944 | 216258 | jsonAppendChar(pOut, '\n'); |
| 215945 | 216259 | pPretty->nIndent--; |
| 215946 | 216260 | jsonPrettyIndent(pPretty); |
| | @@ -218896,11 +219210,11 @@ |
| 218896 | 219210 | sqlite3_result_text64(ctx, p->path.zBuf, n, |
| 218897 | 219211 | SQLITE_TRANSIENT, SQLITE_UTF8); |
| 218898 | 219212 | break; |
| 218899 | 219213 | } |
| 218900 | 219214 | default: { |
| 218901 | | - sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_STATIC); |
| 219215 | + sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_TRANSIENT); |
| 218902 | 219216 | break; |
| 218903 | 219217 | } |
| 218904 | 219218 | case JEACH_JSON: { |
| 218905 | 219219 | if( p->sParse.zJson==0 ){ |
| 218906 | 219220 | sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob, |
| | @@ -219828,10 +220142,22 @@ |
| 219828 | 220142 | p[6] = (i>> 8)&0xFF; |
| 219829 | 220143 | p[7] = (i>> 0)&0xFF; |
| 219830 | 220144 | #endif |
| 219831 | 220145 | return 8; |
| 219832 | 220146 | } |
| 220147 | + |
| 220148 | +/* |
| 220149 | +** Translate pVal into a 32-bit integer. If pVal is an integer |
| 220150 | +** that is larger than 32 bits, the cap it at the largest or |
| 220151 | +** smallest 32-bit integer. |
| 220152 | +*/ |
| 220153 | +static int rtreeValueInt32(sqlite3_value *pVal){ |
| 220154 | + i64 v64 = sqlite3_value_int64(pVal); |
| 220155 | + if( v64>2147483647 ) return 2147483647; |
| 220156 | + if( v64<-2147483648LL ) return (int)-2147483648LL; |
| 220157 | + return (int)v64; |
| 220158 | +} |
| 219833 | 220159 | |
| 219834 | 220160 | /* |
| 219835 | 220161 | ** Increment the reference count of node p. |
| 219836 | 220162 | */ |
| 219837 | 220163 | static void nodeReference(RtreeNode *p){ |
| | @@ -220109,11 +220435,21 @@ |
| 220109 | 220435 | pNode->isDirty = 0; |
| 220110 | 220436 | rc = sqlite3_reset(p); |
| 220111 | 220437 | sqlite3_bind_null(p, 2); |
| 220112 | 220438 | if( pNode->iNode==0 && rc==SQLITE_OK ){ |
| 220113 | 220439 | pNode->iNode = sqlite3_last_insert_rowid(pRtree->db); |
| 220114 | | - nodeHashInsert(pRtree, pNode); |
| 220440 | + if( pNode->iNode==0 ){ |
| 220441 | + /* If the SQL statement has succeeded but sqlite3_last_insert_rowid() |
| 220442 | + ** returns 0, then the shadow table schema has been corrupted somehow |
| 220443 | + ** (e.g. the %_node table has been replaced by a WITHOUT ROWID table). |
| 220444 | + ** It would be dangerous to continue in this case as the hash table |
| 220445 | + ** implementation assumes iNode==0 means that the node is not part |
| 220446 | + ** of the hash table. */ |
| 220447 | + rc = SQLITE_CORRUPT_VTAB; |
| 220448 | + }else{ |
| 220449 | + nodeHashInsert(pRtree, pNode); |
| 220450 | + } |
| 220115 | 220451 | } |
| 220116 | 220452 | } |
| 220117 | 220453 | return rc; |
| 220118 | 220454 | } |
| 220119 | 220455 | |
| | @@ -222232,39 +222568,64 @@ |
| 222232 | 222568 | } |
| 222233 | 222569 | |
| 222234 | 222570 | return rc; |
| 222235 | 222571 | } |
| 222236 | 222572 | |
| 222237 | | -/* |
| 222238 | | -** Rounding constants for float->double conversion. |
| 222239 | | -*/ |
| 222240 | | -#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */ |
| 222241 | | -#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */ |
| 222242 | | - |
| 222243 | 222573 | #if !defined(SQLITE_RTREE_INT_ONLY) |
| 222244 | 222574 | /* |
| 222245 | 222575 | ** Convert an sqlite3_value into an RtreeValue (presumably a float) |
| 222246 | 222576 | ** while taking care to round toward negative or positive, respectively. |
| 222247 | 222577 | */ |
| 222248 | 222578 | static RtreeValue rtreeValueDown(sqlite3_value *v){ |
| 222249 | 222579 | double d = sqlite3_value_double(v); |
| 222250 | 222580 | float f = (float)d; |
| 222251 | 222581 | if( f>d ){ |
| 222252 | | - f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS)); |
| 222582 | + unsigned int x; |
| 222583 | + memcpy(&x, &f, 4); |
| 222584 | + x = (x & 0x80000000)!=0 ? x+1 : x-1; |
| 222585 | + memcpy(&f, &x, 4); |
| 222253 | 222586 | } |
| 222254 | 222587 | return f; |
| 222255 | 222588 | } |
| 222256 | 222589 | static RtreeValue rtreeValueUp(sqlite3_value *v){ |
| 222257 | 222590 | double d = sqlite3_value_double(v); |
| 222258 | 222591 | float f = (float)d; |
| 222259 | 222592 | if( f<d ){ |
| 222260 | | - f = (float)(d*(d<0 ? RNDTOWARDS : RNDAWAY)); |
| 222593 | + unsigned int x; |
| 222594 | + memcpy(&x, &f, 4); |
| 222595 | + x = (x & 0x80000000)!=0 ? x-1 : x+1; |
| 222596 | + memcpy(&f, &x, 4); |
| 222261 | 222597 | } |
| 222262 | 222598 | return f; |
| 222263 | 222599 | } |
| 222264 | 222600 | #endif /* !defined(SQLITE_RTREE_INT_ONLY) */ |
| 222265 | 222601 | |
| 222602 | +#if !defined(SQLITE_RTREE_INT_ONLY) && defined(SQLITE_DEBUG) |
| 222603 | +/* |
| 222604 | +** SQL function: rtree_round32(V,F) |
| 222605 | +** |
| 222606 | +** Convert the floating point value V to the nearest 32-bit float |
| 222607 | +** and return that 32-bit float value. Round up if F is true, or |
| 222608 | +** down if F is falsed. |
| 222609 | +** |
| 222610 | +** Debugging and testing use only. |
| 222611 | +*/ |
| 222612 | +static void rtreeRoundFunc( |
| 222613 | + sqlite3_context *ctx, |
| 222614 | + int nArg, |
| 222615 | + sqlite3_value **apArg |
| 222616 | +){ |
| 222617 | + float f; |
| 222618 | + if( sqlite3_value_int(apArg[1]) ){ |
| 222619 | + f = rtreeValueUp(apArg[0]); |
| 222620 | + }else{ |
| 222621 | + f = rtreeValueDown(apArg[0]); |
| 222622 | + } |
| 222623 | + sqlite3_result_double(ctx, (double)f); |
| 222624 | +} |
| 222625 | +#endif /* !defined(SQLITE_RTREE_INT_ONLY) && defined(SQLITE_DEBUG) */ |
| 222626 | + |
| 222266 | 222627 | /* |
| 222267 | 222628 | ** A constraint has failed while inserting a row into an rtree table. |
| 222268 | 222629 | ** Assuming no OOM error occurs, this function sets the error message |
| 222269 | 222630 | ** (at pRtree->base.zErrMsg) to an appropriate value and returns |
| 222270 | 222631 | ** SQLITE_CONSTRAINT. |
| | @@ -222373,12 +222734,12 @@ |
| 222373 | 222734 | } |
| 222374 | 222735 | }else |
| 222375 | 222736 | #endif |
| 222376 | 222737 | { |
| 222377 | 222738 | for(ii=0; ii<nn; ii+=2){ |
| 222378 | | - cell.aCoord[ii].i = sqlite3_value_int(aData[ii+3]); |
| 222379 | | - cell.aCoord[ii+1].i = sqlite3_value_int(aData[ii+4]); |
| 222739 | + cell.aCoord[ii].i = rtreeValueInt32(aData[ii+3]); |
| 222740 | + cell.aCoord[ii+1].i = rtreeValueInt32(aData[ii+4]); |
| 222380 | 222741 | if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){ |
| 222381 | 222742 | rc = rtreeConstraintError(pRtree, ii+1); |
| 222382 | 222743 | goto constraint; |
| 222383 | 222744 | } |
| 222384 | 222745 | } |
| | @@ -222976,16 +223337,18 @@ |
| 222976 | 223337 | Rtree tree; |
| 222977 | 223338 | int ii; |
| 222978 | 223339 | int nData; |
| 222979 | 223340 | int errCode; |
| 222980 | 223341 | sqlite3_str *pOut; |
| 223342 | + i64 nDim64; |
| 222981 | 223343 | |
| 222982 | 223344 | UNUSED_PARAMETER(nArg); |
| 222983 | 223345 | memset(&node, 0, sizeof(RtreeNode)); |
| 222984 | 223346 | memset(&tree, 0, sizeof(Rtree)); |
| 222985 | | - tree.nDim = (u8)sqlite3_value_int(apArg[0]); |
| 222986 | | - if( tree.nDim<1 || tree.nDim>5 ) return; |
| 223347 | + nDim64 = sqlite3_value_int64(apArg[0]); |
| 223348 | + if( nDim64<1 || nDim64>5 ) return; |
| 223349 | + tree.nDim = (u8)nDim64; |
| 222987 | 223350 | tree.nDim2 = tree.nDim*2; |
| 222988 | 223351 | tree.nBytesPerCell = 8 + 8 * tree.nDim; |
| 222989 | 223352 | node.zData = (u8 *)sqlite3_value_blob(apArg[1]); |
| 222990 | 223353 | if( node.zData==0 ) return; |
| 222991 | 223354 | nData = sqlite3_value_bytes(apArg[1]); |
| | @@ -225386,10 +225749,16 @@ |
| 225386 | 225749 | rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0); |
| 225387 | 225750 | } |
| 225388 | 225751 | if( rc==SQLITE_OK ){ |
| 225389 | 225752 | rc = sqlite3_create_function(db, "rtreecheck", -1, utf8, 0,rtreecheck, 0,0); |
| 225390 | 225753 | } |
| 225754 | +#if defined(SQLITE_DEBUG) && !defined(SQLITE_RTREE_INT_ONLY) |
| 225755 | + if( rc==SQLITE_OK ){ |
| 225756 | + rc = sqlite3_create_function(db, "rtree_round", 2, utf8, 0, |
| 225757 | + rtreeRoundFunc, 0, 0); |
| 225758 | + } |
| 225759 | +#endif /* SQLITE_DEBUG && !SQLITE_RTREE_INT_ONLY */ |
| 225391 | 225760 | if( rc==SQLITE_OK ){ |
| 225392 | 225761 | #ifdef SQLITE_RTREE_INT_ONLY |
| 225393 | 225762 | void *c = (void *)RTREE_COORD_INT32; |
| 225394 | 225763 | #else |
| 225395 | 225764 | void *c = (void *)RTREE_COORD_REAL32; |
| | @@ -228466,19 +228835,31 @@ |
| 228466 | 228835 | ); |
| 228467 | 228836 | } |
| 228468 | 228837 | |
| 228469 | 228838 | /* Check that all non-HIDDEN columns in the destination table are also |
| 228470 | 228839 | ** present in the input table. Populate the abTblPk[], azTblType[] and |
| 228471 | | - ** aiTblOrder[] arrays at the same time. */ |
| 228840 | + ** aiTblOrder[] arrays at the same time. |
| 228841 | + ** |
| 228842 | + ** RBU does not support tables with GENERATED columns. If the target |
| 228843 | + ** table has any, return an error. */ |
| 228472 | 228844 | if( p->rc==SQLITE_OK ){ |
| 228473 | 228845 | p->rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, |
| 228474 | | - sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl) |
| 228846 | + sqlite3_mprintf("PRAGMA table_xinfo(%Q)", pIter->zTbl) |
| 228475 | 228847 | ); |
| 228476 | 228848 | } |
| 228477 | 228849 | while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 228478 | 228850 | const char *zName = (const char*)sqlite3_column_text(pStmt, 1); |
| 228479 | | - if( zName==0 ) break; /* An OOM - finalize() below returns S_NOMEM */ |
| 228851 | + int eHidden = sqlite3_column_int(pStmt, 6); |
| 228852 | + if( zName==0 ) break; /* An OOM. Bail out */ |
| 228853 | + if( eHidden==1 ) continue; /* Hidden column. Ignore */ |
| 228854 | + if( eHidden!=0 ){ |
| 228855 | + p->rc = SQLITE_ERROR; |
| 228856 | + p->zErrmsg = sqlite3_mprintf( |
| 228857 | + "generated columns not supported: %s.%s", pIter->zTbl, zName |
| 228858 | + ); |
| 228859 | + break; |
| 228860 | + } |
| 228480 | 228861 | for(i=iOrder; i<pIter->nTblCol; i++){ |
| 228481 | 228862 | if( 0==strcmp(zName, pIter->azTblCol[i]) ) break; |
| 228482 | 228863 | } |
| 228483 | 228864 | if( i==pIter->nTblCol ){ |
| 228484 | 228865 | p->rc = SQLITE_ERROR; |
| | @@ -229327,11 +229708,11 @@ |
| 229327 | 229708 | int nIdxAlloc = 0; |
| 229328 | 229709 | for(i=0; zSql[i]; i++){ |
| 229329 | 229710 | char c = zSql[i]; |
| 229330 | 229711 | |
| 229331 | 229712 | /* If necessary, grow the pIter->aIdxCol[] array */ |
| 229332 | | - if( iIdxCol==nIdxAlloc ){ |
| 229713 | + if( iIdxCol>=(nIdxAlloc-1) ){ |
| 229333 | 229714 | RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc64( |
| 229334 | 229715 | pIter->aIdxCol, nIdxAlloc*sizeof(RbuSpan) + 16*sizeof(RbuSpan) |
| 229335 | 229716 | ); |
| 229336 | 229717 | if( aIdxCol==0 ){ |
| 229337 | 229718 | rc = SQLITE_NOMEM; |
| | @@ -233129,28 +233510,28 @@ |
| 233129 | 233510 | StatPage *p = &pCsr->aPage[pCsr->iPage]; |
| 233130 | 233511 | if( !pCsr->isAgg ) statResetCounts(pCsr); |
| 233131 | 233512 | while( p->iCell<p->nCell ){ |
| 233132 | 233513 | StatCell *pCell = &p->aCell[p->iCell]; |
| 233133 | 233514 | while( pCell->iOvfl<pCell->nOvfl ){ |
| 233134 | | - int nUsable, iOvfl; |
| 233515 | + int nUsable; |
| 233516 | + int iOvfl = pCell->iOvfl; |
| 233135 | 233517 | sqlite3BtreeEnter(pBt); |
| 233136 | 233518 | nUsable = sqlite3BtreeGetPageSize(pBt) - |
| 233137 | 233519 | sqlite3BtreeGetReserveNoMutex(pBt); |
| 233138 | 233520 | sqlite3BtreeLeave(pBt); |
| 233139 | 233521 | pCsr->nPage++; |
| 233522 | + pCsr->iPageno = pCell->aOvfl[iOvfl]; |
| 233140 | 233523 | statSizeAndOffset(pCsr); |
| 233141 | 233524 | if( pCell->iOvfl<pCell->nOvfl-1 ){ |
| 233142 | 233525 | pCsr->nPayload += nUsable - 4; |
| 233143 | 233526 | }else{ |
| 233144 | 233527 | pCsr->nPayload += pCell->nLastOvfl; |
| 233145 | 233528 | pCsr->nUnused += nUsable - 4 - pCell->nLastOvfl; |
| 233146 | 233529 | } |
| 233147 | | - iOvfl = pCell->iOvfl; |
| 233148 | 233530 | pCell->iOvfl++; |
| 233149 | 233531 | if( !pCsr->isAgg ){ |
| 233150 | 233532 | pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); |
| 233151 | | - pCsr->iPageno = pCell->aOvfl[iOvfl]; |
| 233152 | 233533 | pCsr->zPagetype = "overflow"; |
| 233153 | 233534 | pCsr->zPath = z = sqlite3_mprintf( |
| 233154 | 233535 | "%s%.3x+%.6x", p->zPath, p->iCell, iOvfl |
| 233155 | 233536 | ); |
| 233156 | 233537 | return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK; |
| | @@ -240890,11 +241271,11 @@ |
| 240890 | 241271 | |
| 240891 | 241272 | |
| 240892 | 241273 | if( pIter ){ |
| 240893 | 241274 | sqlite3changeset_pk(pIter, &abPK, &nCol); |
| 240894 | 241275 | }else if( !pTab && !pGrp->db ){ |
| 240895 | | - return SQLITE_OK; |
| 241276 | + return SQLITE_ERROR; |
| 240896 | 241277 | } |
| 240897 | 241278 | |
| 240898 | 241279 | /* If one was not found above, create a new table now */ |
| 240899 | 241280 | if( !pTab ){ |
| 240900 | 241281 | SessionTable **ppNew; |
| | @@ -240916,11 +241297,11 @@ |
| 240916 | 241297 | pTab->nCol = 0; |
| 240917 | 241298 | rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); |
| 240918 | 241299 | if( rc || pTab->nCol==0 ){ |
| 240919 | 241300 | sqlite3_free(pTab->azCol); |
| 240920 | 241301 | sqlite3_free(pTab); |
| 240921 | | - return rc; |
| 241302 | + return rc ? rc : SQLITE_ERROR; |
| 240922 | 241303 | } |
| 240923 | 241304 | } |
| 240924 | 241305 | |
| 240925 | 241306 | /* The new object must be linked on to the end of the list, not |
| 240926 | 241307 | ** simply added to the start of it. This is to ensure that the |
| | @@ -241754,48 +242135,44 @@ |
| 241754 | 242135 | rc = SQLITE_MISUSE; |
| 241755 | 242136 | }else if( eOp!=SQLITE_INSERT && eOp!=SQLITE_UPDATE && eOp!=SQLITE_DELETE ){ |
| 241756 | 242137 | rc = SQLITE_ERROR; |
| 241757 | 242138 | }else{ |
| 241758 | 242139 | rc = sessionChangesetFindTable(pGrp, zTab, 0, &pTab); |
| 241759 | | - } |
| 241760 | | - if( rc==SQLITE_OK ){ |
| 241761 | | - if( pTab==0 ){ |
| 241762 | | - if( pzErr ){ |
| 241763 | | - *pzErr = sqlite3_mprintf("no such table: %s", zTab); |
| 241764 | | - } |
| 241765 | | - rc = SQLITE_ERROR; |
| 241766 | | - }else{ |
| 241767 | | - int nReq = pTab->nCol * (eOp==SQLITE_UPDATE ? 2 : 1); |
| 241768 | | - pGrp->cd.pTab = pTab; |
| 241769 | | - pGrp->cd.eOp = eOp; |
| 241770 | | - pGrp->cd.bIndirect = bIndirect; |
| 241771 | | - |
| 241772 | | - if( pGrp->cd.nBufAlloc<nReq ){ |
| 241773 | | - SessionBuffer *aBuf = (SessionBuffer*)sqlite3_realloc( |
| 241774 | | - pGrp->cd.aBuf, nReq * sizeof(SessionBuffer) |
| 241775 | | - ); |
| 241776 | | - if( aBuf==0 ){ |
| 241777 | | - rc = SQLITE_NOMEM; |
| 241778 | | - }else{ |
| 241779 | | - memset(&aBuf[pGrp->cd.nBufAlloc], 0, |
| 241780 | | - sizeof(SessionBuffer) * (nReq - pGrp->cd.nBufAlloc) |
| 241781 | | - ); |
| 241782 | | - pGrp->cd.aBuf = aBuf; |
| 241783 | | - pGrp->cd.nBufAlloc = nReq; |
| 241784 | | - } |
| 241785 | | - } |
| 242140 | + if( pTab==0 && pzErr ){ |
| 242141 | + *pzErr = sqlite3_mprintf("no such table: %s", zTab); |
| 242142 | + } |
| 242143 | + } |
| 242144 | + if( rc==SQLITE_OK ){ |
| 242145 | + int nReq = pTab->nCol * (eOp==SQLITE_UPDATE ? 2 : 1); |
| 242146 | + pGrp->cd.pTab = pTab; |
| 242147 | + pGrp->cd.eOp = eOp; |
| 242148 | + pGrp->cd.bIndirect = bIndirect; |
| 242149 | + |
| 242150 | + if( pGrp->cd.nBufAlloc<nReq ){ |
| 242151 | + SessionBuffer *aBuf = (SessionBuffer*)sqlite3_realloc( |
| 242152 | + pGrp->cd.aBuf, nReq * sizeof(SessionBuffer) |
| 242153 | + ); |
| 242154 | + if( aBuf==0 ){ |
| 242155 | + rc = SQLITE_NOMEM; |
| 242156 | + }else{ |
| 242157 | + memset(&aBuf[pGrp->cd.nBufAlloc], 0, |
| 242158 | + sizeof(SessionBuffer) * (nReq - pGrp->cd.nBufAlloc) |
| 242159 | + ); |
| 242160 | + pGrp->cd.aBuf = aBuf; |
| 242161 | + pGrp->cd.nBufAlloc = nReq; |
| 242162 | + } |
| 242163 | + } |
| 241786 | 242164 | |
| 241787 | 242165 | #ifdef SQLITE_DEBUG |
| 241788 | | - { |
| 241789 | | - /* Assert that all column values are currently undefined */ |
| 241790 | | - int ii; |
| 241791 | | - for(ii=0; ii<pGrp->cd.nBufAlloc; ii++){ |
| 241792 | | - assert( pGrp->cd.aBuf[ii].nBuf==0 ); |
| 241793 | | - } |
| 241794 | | - } |
| 241795 | | -#endif |
| 241796 | | - } |
| 242166 | + { |
| 242167 | + /* Assert that all column values are currently undefined */ |
| 242168 | + int ii; |
| 242169 | + for(ii=0; ii<pGrp->cd.nBufAlloc; ii++){ |
| 242170 | + assert( pGrp->cd.aBuf[ii].nBuf==0 ); |
| 242171 | + } |
| 242172 | + } |
| 242173 | +#endif |
| 241797 | 242174 | } |
| 241798 | 242175 | |
| 241799 | 242176 | return rc; |
| 241800 | 242177 | } |
| 241801 | 242178 | |
| | @@ -245585,10 +245962,20 @@ |
| 245585 | 245962 | } |
| 245586 | 245963 | |
| 245587 | 245964 | return rc; |
| 245588 | 245965 | } |
| 245589 | 245966 | |
| 245967 | +/* |
| 245968 | +** Return the integer value of pVal, clamped to the range [-1, 0x7FFFFFFF]. |
| 245969 | +** This is used for the column-number arguments of auxiliary functions, |
| 245970 | +** so that 64-bit values that are too large or too small to fit in a |
| 245971 | +** 32-bit signed integer are not truncated to what might be a valid |
| 245972 | +** column number. |
| 245973 | +*/ |
| 245974 | +static int fts5ValueClampedInt(sqlite3_value *pVal){ |
| 245975 | + return (int)MIN(MAX(sqlite3_value_int64(pVal), -1), 0x7FFFFFFF); |
| 245976 | +} |
| 245590 | 245977 | |
| 245591 | 245978 | /* |
| 245592 | 245979 | ** Implementation of highlight() function. |
| 245593 | 245980 | */ |
| 245594 | 245981 | static void fts5HighlightFunction( |
| | @@ -245606,11 +245993,11 @@ |
| 245606 | 245993 | const char *zErr = "wrong number of arguments to function highlight()"; |
| 245607 | 245994 | sqlite3_result_error(pCtx, zErr, -1); |
| 245608 | 245995 | return; |
| 245609 | 245996 | } |
| 245610 | 245997 | |
| 245611 | | - iCol = sqlite3_value_int(apVal[0]); |
| 245998 | + iCol = fts5ValueClampedInt(apVal[0]); |
| 245612 | 245999 | memset(&ctx, 0, sizeof(HighlightContext)); |
| 245613 | 246000 | ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]); |
| 245614 | 246001 | ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); |
| 245615 | 246002 | ctx.iRangeEnd = -1; |
| 245616 | 246003 | rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); |
| | @@ -245805,11 +246192,11 @@ |
| 245805 | 246192 | return; |
| 245806 | 246193 | } |
| 245807 | 246194 | |
| 245808 | 246195 | nCol = pApi->xColumnCount(pFts); |
| 245809 | 246196 | memset(&ctx, 0, sizeof(HighlightContext)); |
| 245810 | | - iCol = sqlite3_value_int(apVal[0]); |
| 246197 | + iCol = fts5ValueClampedInt(apVal[0]); |
| 245811 | 246198 | ctx.zOpen = fts5ValueToText(apVal[1]); |
| 245812 | 246199 | ctx.zClose = fts5ValueToText(apVal[2]); |
| 245813 | 246200 | ctx.iRangeEnd = -1; |
| 245814 | 246201 | zEllips = fts5ValueToText(apVal[3]); |
| 245815 | 246202 | nToken = (int)(MIN( MAX(sqlite3_value_int64(apVal[4]), 0), 64)); |
| | @@ -246137,11 +246524,11 @@ |
| 246137 | 246524 | const char *z = "non-integer argument passed to function fts5_get_locale()"; |
| 246138 | 246525 | sqlite3_result_error(pCtx, z, -1); |
| 246139 | 246526 | return; |
| 246140 | 246527 | } |
| 246141 | 246528 | |
| 246142 | | - iCol = sqlite3_value_int(apVal[0]); |
| 246529 | + iCol = fts5ValueClampedInt(apVal[0]); |
| 246143 | 246530 | if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){ |
| 246144 | 246531 | sqlite3_result_error_code(pCtx, SQLITE_RANGE); |
| 246145 | 246532 | return; |
| 246146 | 246533 | } |
| 246147 | 246534 | |
| | @@ -259897,10 +260284,13 @@ |
| 259897 | 260284 | *pCksum = cksum; |
| 259898 | 260285 | return rc; |
| 259899 | 260286 | } |
| 259900 | 260287 | |
| 259901 | 260288 | /* |
| 260289 | +** This function is purely an internal test. It does not contribute to |
| 260290 | +** FTS functionality, or even the integrity-check, in any way. |
| 260291 | +** |
| 259902 | 260292 | ** Check if buffer z[], size n bytes, contains as series of valid utf-8 |
| 259903 | 260293 | ** encoded codepoints. If so, return 0. Otherwise, if the buffer does not |
| 259904 | 260294 | ** contain valid utf-8, return non-zero. |
| 259905 | 260295 | */ |
| 259906 | 260296 | static int fts5TestUtf8(const char *z, int n){ |
| | @@ -259918,12 +260308,12 @@ |
| 259918 | 260308 | if( i+2>=n || (z[i+1] & 0xC0)!=0x80 || (z[i+2] & 0xC0)!=0x80 ) return 1; |
| 259919 | 260309 | i += 3; |
| 259920 | 260310 | }else |
| 259921 | 260311 | if( (z[i] & 0xF8)==0xF0 ){ |
| 259922 | 260312 | if( i+3>=n || (z[i+1] & 0xC0)!=0x80 || (z[i+2] & 0xC0)!=0x80 ) return 1; |
| 259923 | | - if( (z[i+2] & 0xC0)!=0x80 ) return 1; |
| 259924 | | - i += 3; |
| 260313 | + if( (z[i+3] & 0xC0)!=0x80 ) return 1; |
| 260314 | + i += 4; |
| 259925 | 260315 | }else{ |
| 259926 | 260316 | return 1; |
| 259927 | 260317 | } |
| 259928 | 260318 | } |
| 259929 | 260319 | |
| | @@ -264813,11 +265203,11 @@ |
| 264813 | 265203 | int nArg, /* Number of args */ |
| 264814 | 265204 | sqlite3_value **apUnused /* Function arguments */ |
| 264815 | 265205 | ){ |
| 264816 | 265206 | assert( nArg==0 ); |
| 264817 | 265207 | UNUSED_PARAM2(nArg, apUnused); |
| 264818 | | - sqlite3_result_text(pCtx, "fts5: 2026-08-27 10:58:16 555f31c64d3fcc55df2715a7c8c1cb28503b2c0eb21d950ccdcbf6f577593dd5", -1, SQLITE_TRANSIENT); |
| 265208 | + sqlite3_result_text(pCtx, "fts5: 2026-10-01 11:21:02 92709f54d4c58cf174f305b58971a01878af313157a11549b588a25216701f5c", -1, SQLITE_TRANSIENT); |
| 264819 | 265209 | } |
| 264820 | 265210 | |
| 264821 | 265211 | /* |
| 264822 | 265212 | ** Implementation of fts5_locale(LOCALE, TEXT) function. |
| 264823 | 265213 | ** |
| | @@ -265706,79 +266096,10 @@ |
| 265706 | 266096 | ); |
| 265707 | 266097 | sqlite3_reset(pStorage->pSavedRow); |
| 265708 | 266098 | pStorage->pSavedRow = 0; |
| 265709 | 266099 | } |
| 265710 | 266100 | |
| 265711 | | -/* |
| 265712 | | -** This function is called to process a DELETE on a contentless_delete=1 |
| 265713 | | -** table. It adds the tombstone required to delete the entry with rowid |
| 265714 | | -** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs, |
| 265715 | | -** an SQLite error code. |
| 265716 | | -*/ |
| 265717 | | -static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){ |
| 265718 | | - i64 iOrigin = 0; |
| 265719 | | - sqlite3_stmt *pLookup = 0; |
| 265720 | | - int rc = SQLITE_OK; |
| 265721 | | - |
| 265722 | | - assert( p->pConfig->bContentlessDelete ); |
| 265723 | | - assert( p->pConfig->eContent==FTS5_CONTENT_NONE |
| 265724 | | - || p->pConfig->eContent==FTS5_CONTENT_UNINDEXED |
| 265725 | | - ); |
| 265726 | | - |
| 265727 | | - /* Look up the origin of the document in the %_docsize table. Store |
| 265728 | | - ** this in stack variable iOrigin. */ |
| 265729 | | - rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0); |
| 265730 | | - if( rc==SQLITE_OK ){ |
| 265731 | | - sqlite3_bind_int64(pLookup, 1, iDel); |
| 265732 | | - if( SQLITE_ROW==sqlite3_step(pLookup) ){ |
| 265733 | | - iOrigin = sqlite3_column_int64(pLookup, 1); |
| 265734 | | - } |
| 265735 | | - rc = sqlite3_reset(pLookup); |
| 265736 | | - } |
| 265737 | | - |
| 265738 | | - if( rc==SQLITE_OK && iOrigin!=0 ){ |
| 265739 | | - rc = sqlite3Fts5IndexContentlessDelete(p->pIndex, iOrigin, iDel); |
| 265740 | | - } |
| 265741 | | - |
| 265742 | | - return rc; |
| 265743 | | -} |
| 265744 | | - |
| 265745 | | -/* |
| 265746 | | -** Insert a record into the %_docsize table. Specifically, do: |
| 265747 | | -** |
| 265748 | | -** INSERT OR REPLACE INTO %_docsize(id, sz) VALUES(iRowid, pBuf); |
| 265749 | | -** |
| 265750 | | -** If there is no %_docsize table (as happens if the columnsize=0 option |
| 265751 | | -** is specified when the FTS5 table is created), this function is a no-op. |
| 265752 | | -*/ |
| 265753 | | -static int fts5StorageInsertDocsize( |
| 265754 | | - Fts5Storage *p, /* Storage module to write to */ |
| 265755 | | - i64 iRowid, /* id value */ |
| 265756 | | - Fts5Buffer *pBuf /* sz value */ |
| 265757 | | -){ |
| 265758 | | - int rc = SQLITE_OK; |
| 265759 | | - if( p->pConfig->bColumnsize ){ |
| 265760 | | - sqlite3_stmt *pReplace = 0; |
| 265761 | | - rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0); |
| 265762 | | - if( rc==SQLITE_OK ){ |
| 265763 | | - sqlite3_bind_int64(pReplace, 1, iRowid); |
| 265764 | | - if( p->pConfig->bContentlessDelete ){ |
| 265765 | | - i64 iOrigin = 0; |
| 265766 | | - rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); |
| 265767 | | - sqlite3_bind_int64(pReplace, 3, iOrigin); |
| 265768 | | - } |
| 265769 | | - } |
| 265770 | | - if( rc==SQLITE_OK ){ |
| 265771 | | - sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); |
| 265772 | | - sqlite3_step(pReplace); |
| 265773 | | - rc = sqlite3_reset(pReplace); |
| 265774 | | - sqlite3_bind_null(pReplace, 2); |
| 265775 | | - } |
| 265776 | | - } |
| 265777 | | - return rc; |
| 265778 | | -} |
| 265779 | | - |
| 265780 | 266101 | /* |
| 265781 | 266102 | ** Load the contents of the "averages" record from disk into the |
| 265782 | 266103 | ** p->nTotalRow and p->aTotalSize[] variables. If successful, and if |
| 265783 | 266104 | ** argument bCache is true, set the p->bTotalsValid flag to indicate |
| 265784 | 266105 | ** that the contents of aTotalSize[] and nTotalRow are valid until |
| | @@ -265819,10 +266140,114 @@ |
| 265819 | 266140 | } |
| 265820 | 266141 | sqlite3_free(buf.p); |
| 265821 | 266142 | |
| 265822 | 266143 | return rc; |
| 265823 | 266144 | } |
| 266145 | + |
| 266146 | +static int fts5StorageDecodeSizeArray( |
| 266147 | + int *aCol, int nCol, /* Array to populate */ |
| 266148 | + const u8 *aBlob, int nBlob /* Record to read varints from */ |
| 266149 | +){ |
| 266150 | + int i; |
| 266151 | + int iOff = 0; |
| 266152 | + for(i=0; i<nCol; i++){ |
| 266153 | + if( iOff>=nBlob ) return 1; |
| 266154 | + iOff += fts5GetVarint32(&aBlob[iOff], aCol[i]); |
| 266155 | + } |
| 266156 | + return (iOff!=nBlob); |
| 266157 | +} |
| 266158 | + |
| 266159 | +/* |
| 266160 | +** This function is called to process a DELETE on a contentless_delete=1 |
| 266161 | +** table. It adds the tombstone required to delete the entry with rowid |
| 266162 | +** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs, |
| 266163 | +** an SQLite error code. |
| 266164 | +*/ |
| 266165 | +static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){ |
| 266166 | + i64 iOrigin = 0; |
| 266167 | + sqlite3_stmt *pLookup = 0; |
| 266168 | + int rc = SQLITE_OK; |
| 266169 | + |
| 266170 | + assert( p->pConfig->bContentlessDelete ); |
| 266171 | + assert( p->pConfig->eContent==FTS5_CONTENT_NONE |
| 266172 | + || p->pConfig->eContent==FTS5_CONTENT_UNINDEXED |
| 266173 | + ); |
| 266174 | + |
| 266175 | + rc = fts5StorageLoadTotals(p, 1); |
| 266176 | + if( rc!=SQLITE_OK ) return rc; |
| 266177 | + |
| 266178 | + /* Look up the origin of the document in the %_docsize table. Store |
| 266179 | + ** this in stack variable iOrigin. */ |
| 266180 | + rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0); |
| 266181 | + if( rc==SQLITE_OK ){ |
| 266182 | + int rc2; |
| 266183 | + sqlite3_bind_int64(pLookup, 1, iDel); |
| 266184 | + if( SQLITE_ROW==sqlite3_step(pLookup) ){ |
| 266185 | + int *aCol = (int*)sqlite3_malloc64(p->pConfig->nCol * sizeof(int)); |
| 266186 | + if( aCol==0 ){ |
| 266187 | + rc = SQLITE_NOMEM; |
| 266188 | + }else{ |
| 266189 | + const u8 *aBlob = sqlite3_column_blob(pLookup, 0); |
| 266190 | + int nBlob = sqlite3_column_bytes(pLookup, 0); |
| 266191 | + int ii; |
| 266192 | + if( fts5StorageDecodeSizeArray(aCol, p->pConfig->nCol, aBlob, nBlob) ){ |
| 266193 | + rc = SQLITE_CORRUPT_VTAB; |
| 266194 | + }else{ |
| 266195 | + for(ii=0; ii<p->pConfig->nCol; ii++){ |
| 266196 | + p->aTotalSize[ii] -= aCol[ii]; |
| 266197 | + } |
| 266198 | + } |
| 266199 | + sqlite3_free(aCol); |
| 266200 | + } |
| 266201 | + iOrigin = sqlite3_column_int(pLookup, 1); |
| 266202 | + } |
| 266203 | + rc2 = sqlite3_reset(pLookup); |
| 266204 | + if( rc==SQLITE_OK ) rc = rc2; |
| 266205 | + } |
| 266206 | + |
| 266207 | + if( rc==SQLITE_OK && iOrigin!=0 ){ |
| 266208 | + rc = sqlite3Fts5IndexContentlessDelete(p->pIndex, iOrigin, iDel); |
| 266209 | + p->nTotalRow--; |
| 266210 | + } |
| 266211 | + |
| 266212 | + return rc; |
| 266213 | +} |
| 266214 | + |
| 266215 | +/* |
| 266216 | +** Insert a record into the %_docsize table. Specifically, do: |
| 266217 | +** |
| 266218 | +** INSERT OR REPLACE INTO %_docsize(id, sz) VALUES(iRowid, pBuf); |
| 266219 | +** |
| 266220 | +** If there is no %_docsize table (as happens if the columnsize=0 option |
| 266221 | +** is specified when the FTS5 table is created), this function is a no-op. |
| 266222 | +*/ |
| 266223 | +static int fts5StorageInsertDocsize( |
| 266224 | + Fts5Storage *p, /* Storage module to write to */ |
| 266225 | + i64 iRowid, /* id value */ |
| 266226 | + Fts5Buffer *pBuf /* sz value */ |
| 266227 | +){ |
| 266228 | + int rc = SQLITE_OK; |
| 266229 | + if( p->pConfig->bColumnsize ){ |
| 266230 | + sqlite3_stmt *pReplace = 0; |
| 266231 | + rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0); |
| 266232 | + if( rc==SQLITE_OK ){ |
| 266233 | + sqlite3_bind_int64(pReplace, 1, iRowid); |
| 266234 | + if( p->pConfig->bContentlessDelete ){ |
| 266235 | + i64 iOrigin = 0; |
| 266236 | + rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); |
| 266237 | + sqlite3_bind_int64(pReplace, 3, iOrigin); |
| 266238 | + } |
| 266239 | + } |
| 266240 | + if( rc==SQLITE_OK ){ |
| 266241 | + sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); |
| 266242 | + sqlite3_step(pReplace); |
| 266243 | + rc = sqlite3_reset(pReplace); |
| 266244 | + sqlite3_bind_null(pReplace, 2); |
| 266245 | + } |
| 266246 | + } |
| 266247 | + return rc; |
| 266248 | +} |
| 265824 | 266249 | |
| 265825 | 266250 | /* |
| 265826 | 266251 | ** Remove a row from the FTS table. |
| 265827 | 266252 | */ |
| 265828 | 266253 | static int sqlite3Fts5StorageDelete( |
| | @@ -266481,23 +266906,10 @@ |
| 266481 | 266906 | }else{ |
| 266482 | 266907 | sqlite3_finalize(pStmt); |
| 266483 | 266908 | } |
| 266484 | 266909 | } |
| 266485 | 266910 | |
| 266486 | | -static int fts5StorageDecodeSizeArray( |
| 266487 | | - int *aCol, int nCol, /* Array to populate */ |
| 266488 | | - const u8 *aBlob, int nBlob /* Record to read varints from */ |
| 266489 | | -){ |
| 266490 | | - int i; |
| 266491 | | - int iOff = 0; |
| 266492 | | - for(i=0; i<nCol; i++){ |
| 266493 | | - if( iOff>=nBlob ) return 1; |
| 266494 | | - iOff += fts5GetVarint32(&aBlob[iOff], aCol[i]); |
| 266495 | | - } |
| 266496 | | - return (iOff!=nBlob); |
| 266497 | | -} |
| 266498 | | - |
| 266499 | 266911 | /* |
| 266500 | 266912 | ** Argument aCol points to an array of integers containing one entry for |
| 266501 | 266913 | ** each table column. This function reads the %_docsize record for the |
| 266502 | 266914 | ** specified rowid and populates aCol[] with the results. |
| 266503 | 266915 | ** |
| 266504 | 266916 | |