Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Update the built-in SQLite to the latest trunk version for testing. Enable floating-point math functions in SQLite. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
3ce667ae583477af82c6c07c7d685cf5 |
| User & Date: | drh 2025-01-29 20:28:43.000 |
Context
|
2025-01-31
| ||
| 11:49 | Correct a typo in tool/emcc.sh.in which could cause all of the configure-time work to locate the emcc binary to go unused. Reported in [https://sqlite.org/forum/forumpost/feb325cdde5b6f37|sqlite forum post feb325cdde5b6f37] (sqlite uses a slight variant of this script). check-in: f020f45681 user: stephan tags: trunk | |
|
2025-01-30
| ||
| 20:33 | Partial work toward copying sqlite3-src.tar.gz in to build libsqlite3.a in parallel instead of a single-core build from extsrc/sqlite3.c. Closed-Leaf check-in: 9990c2d1db user: wyoung tags: MISTAKE | |
|
2025-01-29
| ||
| 20:28 | Update the built-in SQLite to the latest trunk version for testing. Enable floating-point math functions in SQLite. check-in: 3ce667ae58 user: drh tags: trunk | |
|
2025-01-28
| ||
| 21:48 | (Typo) Correcting substitution. Forum post [forum:/forumpost/e0c11cfb01|Forum thread e0c11cfb01]. check-in: 2e41b8c32f user: brickviking tags: trunk | |
Changes
Changes to extsrc/shell.c.
| ︙ | ︙ | |||
353 354 355 356 357 358 359 360 361 362 363 364 365 366 | ** in the CLI, or other context clues in other applications) for all ** other output channels. ** ** The default behavior, if neither of the above is defined is to ** use O_U8TEXT when writing to the Windows console (or anything ** else for which _isatty() returns true) and to use O_BINARY or O_TEXT ** for all other output channels. */ #if defined(SQLITE_U8TEXT_ONLY) # define UseWtextForOutput(fd) 1 # define UseWtextForInput(fd) 1 # define IsConsole(fd) _isatty(_fileno(fd)) #elif defined(SQLITE_U8TEXT_STDIO) # define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr) | > > > > > | 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | ** in the CLI, or other context clues in other applications) for all ** other output channels. ** ** The default behavior, if neither of the above is defined is to ** use O_U8TEXT when writing to the Windows console (or anything ** else for which _isatty() returns true) and to use O_BINARY or O_TEXT ** for all other output channels. ** ** The SQLITE_USE_W32_FOR_CONSOLE_IO macro is also available. If ** defined, it forces the use of Win32 APIs for all console I/O, both ** input and output. This is necessary for some non-Microsoft run-times ** that implement stdio differently from Microsoft/Visual-Studio. */ #if defined(SQLITE_U8TEXT_ONLY) # define UseWtextForOutput(fd) 1 # define UseWtextForInput(fd) 1 # define IsConsole(fd) _isatty(_fileno(fd)) #elif defined(SQLITE_U8TEXT_STDIO) # define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr) |
| ︙ | ︙ | |||
455 456 457 458 459 460 461 |
/* When reading from the command-prompt in Windows, it is necessary
** to use _O_WTEXT input mode to read UTF-16 characters, then translate
** that into UTF-8. Otherwise, non-ASCII characters all get translated
** into '?'.
*/
wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) );
if( b1==0 ) return 0;
| | | | 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
/* When reading from the command-prompt in Windows, it is necessary
** to use _O_WTEXT input mode to read UTF-16 characters, then translate
** that into UTF-8. Otherwise, non-ASCII characters all get translated
** into '?'.
*/
wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) );
if( b1==0 ) return 0;
#ifdef SQLITE_USE_W32_FOR_CONSOLE_IO
DWORD nRead = 0;
if( IsConsole(in)
&& ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz-1, &nRead, 0)
){
b1[nRead] = 0;
}else
#endif
{
_setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
if( fgetws(b1, sz/4, in)==0 ){
|
| ︙ | ︙ | |||
533 534 535 536 537 538 539 |
*/
int sz = (int)strlen(z);
wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) );
if( b1==0 ) return 0;
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
b1[sz] = 0;
| | > | | | 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 |
*/
int sz = (int)strlen(z);
wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) );
if( b1==0 ) return 0;
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
b1[sz] = 0;
#ifdef SQLITE_USE_W32_FOR_CONSOLE_IO
DWORD nWr = 0;
if( IsConsole(out)
&& WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),b1,sz,&nWr,0)
){
/* If writing to the console, then the WriteConsoleW() is all we
** need to do. */
}else
#endif
{
/* As long as SQLITE_USE_W32_FOR_CONSOLE_IO is not defined, or for
** non-console I/O even if that macro is defined, write using the
** standard library. */
_setmode(_fileno(out), _O_U8TEXT);
if( UseBinaryWText(out) ){
piecemealOutput(b1, sz, out);
}else{
fputws(b1, out);
}
}
|
| ︙ | ︙ | |||
5310 5311 5312 5313 5314 5315 5316 |
pOut[2] = (qv) & 0xff;
deliberate_fall_through; /* FALLTHRU */
case 2:
pOut[1] = (qv>>8) & 0xff;
deliberate_fall_through; /* FALLTHRU */
case 1:
pOut[0] = (qv>>16) & 0xff;
| | | 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 |
pOut[2] = (qv) & 0xff;
deliberate_fall_through; /* FALLTHRU */
case 2:
pOut[1] = (qv>>8) & 0xff;
deliberate_fall_through; /* FALLTHRU */
case 1:
pOut[0] = (qv>>16) & 0xff;
break;
}
pOut += nbo;
}
return pOut;
}
/* This function does the work for the SQLite base64(x) UDF. */
|
| ︙ | ︙ | |||
17195 17196 17197 17198 17199 17200 17201 |
/*
** Close the dynamic library handle pHandle.
*/
static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
vfstraceOnOff(pInfo, VTR_DLCLOSE);
| | | 17201 17202 17203 17204 17205 17206 17207 17208 17209 17210 17211 17212 17213 17214 17215 |
/*
** Close the dynamic library handle pHandle.
*/
static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
vfstraceOnOff(pInfo, VTR_DLCLOSE);
vfstrace_printf(pInfo, "%s.xDlClose()\n", pInfo->zVfsName);
pRoot->xDlClose(pRoot, pHandle);
}
/*
** Populate the buffer pointed to by zBufOut with nByte bytes of
** random data.
*/
|
| ︙ | ︙ | |||
31631 31632 31633 31634 31635 31636 31637 31638 31639 31640 31641 31642 31643 31644 |
{ 0x00400000, 1, "ReleaseReg" },
{ 0x00800000, 1, "FlttnUnionAll" },
{ 0x01000000, 1, "IndexedEXpr" },
{ 0x02000000, 1, "Coroutines" },
{ 0x04000000, 1, "NullUnusedCols" },
{ 0x08000000, 1, "OnePass" },
{ 0x10000000, 1, "OrderBySubq" },
{ 0xffffffff, 0, "All" },
};
unsigned int curOpt;
unsigned int newOpt;
unsigned int m;
int ii;
int nOff;
| > | 31637 31638 31639 31640 31641 31642 31643 31644 31645 31646 31647 31648 31649 31650 31651 |
{ 0x00400000, 1, "ReleaseReg" },
{ 0x00800000, 1, "FlttnUnionAll" },
{ 0x01000000, 1, "IndexedEXpr" },
{ 0x02000000, 1, "Coroutines" },
{ 0x04000000, 1, "NullUnusedCols" },
{ 0x08000000, 1, "OnePass" },
{ 0x10000000, 1, "OrderBySubq" },
{ 0x20000000, 1, "StarQuery" },
{ 0xffffffff, 0, "All" },
};
unsigned int curOpt;
unsigned int newOpt;
unsigned int m;
int ii;
int nOff;
|
| ︙ | ︙ |
Changes to extsrc/sqlite3.c.
1 2 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.49.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines ** the programming interface to the SQLite library. (If you do not have ** the "sqlite3.h" header file at hand, you will find a copy embedded within ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed ** if you want a wrapper to interface SQLite with your choice of programming ** language. The code for the "sqlite3" command-line shell is also in a ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in ** d7c07581203a0a88456588e49e51b40a8341 with changes in files: ** ** */ #ifndef SQLITE_AMALGAMATION #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE |
| ︙ | ︙ | |||
461 462 463 464 465 466 467 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.49.0" #define SQLITE_VERSION_NUMBER 3049000 #define SQLITE_SOURCE_ID "2025-01-29 18:53:19 d7c07581203a0a88456588e49e51b40a8341b0e7121809f75be0ee882d91650f" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
11063 11064 11065 11066 11067 11068 11069 | ** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Serialize a database ** | | | > | 11063 11064 11065 11066 11067 11068 11069 11070 11071 11072 11073 11074 11075 11076 11077 11078 11079 | ** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Serialize a database ** ** The sqlite3_serialize(D,S,P,F) interface returns a pointer to ** memory that is a serialization of the S database on ** [database connection] D. If S is a NULL pointer, the main database is used. ** If P is not a NULL pointer, then the size of the database in bytes ** is written into *P. ** ** For an ordinary on-disk database file, the serialization is just a ** copy of the disk file. For an in-memory database or a "TEMP" database, ** the serialization is the same sequence of bytes which would be written ** to disk if that database where backed up to disk. |
| ︙ | ︙ | |||
15125 15126 15127 15128 15129 15130 15131 15132 15133 15134 15135 15136 15137 15138 | ** ** The LogEst can be negative to indicate fractional values. ** Examples: ** ** 0.5 -> -10 0.1 -> -33 0.0625 -> -40 */ typedef INT16_TYPE LogEst; /* ** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer */ #ifndef SQLITE_PTRSIZE # if defined(__SIZEOF_POINTER__) # define SQLITE_PTRSIZE __SIZEOF_POINTER__ | > > | 15126 15127 15128 15129 15130 15131 15132 15133 15134 15135 15136 15137 15138 15139 15140 15141 | ** ** The LogEst can be negative to indicate fractional values. ** Examples: ** ** 0.5 -> -10 0.1 -> -33 0.0625 -> -40 */ typedef INT16_TYPE LogEst; #define LOGEST_MIN (-32768) #define LOGEST_MAX (32767) /* ** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer */ #ifndef SQLITE_PTRSIZE # if defined(__SIZEOF_POINTER__) # define SQLITE_PTRSIZE __SIZEOF_POINTER__ |
| ︙ | ︙ | |||
15395 15396 15397 15398 15399 15400 15401 | ** ** (---any--) Top-level block structure ** 0x-------F High-level debug messages ** 0x----FFF- More detail ** 0xFFFF---- Low-level debug messages ** ** 0x00000001 Code generation | | > > | 15398 15399 15400 15401 15402 15403 15404 15405 15406 15407 15408 15409 15410 15411 15412 15413 15414 15415 15416 15417 15418 15419 15420 15421 15422 15423 15424 15425 15426 15427 15428 15429 15430 15431 15432 | ** ** (---any--) Top-level block structure ** 0x-------F High-level debug messages ** 0x----FFF- More detail ** 0xFFFF---- Low-level debug messages ** ** 0x00000001 Code generation ** 0x00000002 Solver (Use 0x40000 for less detail) ** 0x00000004 Solver costs ** 0x00000008 WhereLoop inserts ** ** 0x00000010 Display sqlite3_index_info xBestIndex calls ** 0x00000020 Range an equality scan metrics ** 0x00000040 IN operator decisions ** 0x00000080 WhereLoop cost adjustments ** 0x00000100 ** 0x00000200 Covering index decisions ** 0x00000400 OR optimization ** 0x00000800 Index scanner ** 0x00001000 More details associated with code generation ** 0x00002000 ** 0x00004000 Show all WHERE terms at key points ** 0x00008000 Show the full SELECT statement at key places ** ** 0x00010000 Show more detail when printing WHERE terms ** 0x00020000 Show WHERE terms returned from whereScanNext() ** 0x00040000 Solver overview messages ** 0x00080000 Star-query heuristic */ /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. ** |
| ︙ | ︙ | |||
18095 18096 18097 18098 18099 18100 18101 18102 18103 18104 18105 18106 18107 18108 | #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. */ #define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) #define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) | > | 18100 18101 18102 18103 18104 18105 18106 18107 18108 18109 18110 18111 18112 18113 18114 | #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ #define SQLITE_StarQuery 0x20000000 /* Heurists for star queries */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. */ #define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) #define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) |
| ︙ | ︙ | |||
19424 19425 19426 19427 19428 19429 19430 |
**
** INSERT INTO t(a,b,c) ...
**
** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
*/
struct IdList {
int nId; /* Number of identifiers on the list */
| < < < < < | 19430 19431 19432 19433 19434 19435 19436 19437 19438 19439 19440 19441 19442 19443 19444 19445 |
**
** INSERT INTO t(a,b,c) ...
**
** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
*/
struct IdList {
int nId; /* Number of identifiers on the list */
struct IdList_item {
char *zName; /* Name of the identifier */
} a[1];
};
/*
** Allowed values for IdList.eType, which determines which value of the a.u4
** is valid.
*/
|
| ︙ | ︙ | |||
23577 23578 23579 23580 23581 23582 23583 23584 23585 23586 23587 23588 23589 23590 | int szMalloc; /* Size of the zMalloc allocation */ u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ u16 mScopyFlags; /* flags value immediately after the shallow copy */ #endif }; /* ** Size of struct Mem not including the Mem.zMalloc member or anything that ** follows. */ | > | 23578 23579 23580 23581 23582 23583 23584 23585 23586 23587 23588 23589 23590 23591 23592 | int szMalloc; /* Size of the zMalloc allocation */ u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ u16 mScopyFlags; /* flags value immediately after the shallow copy */ u8 bScopy; /* The pScopyFrom of some other Mem *might* point here */ #endif }; /* ** Size of struct Mem not including the Mem.zMalloc member or anything that ** follows. */ |
| ︙ | ︙ | |||
24675 24676 24677 24678 24679 24680 24681 24682 24683 24684 24685 24686 24687 24688 |
zDate++;
while( sqlite3Isdigit(*zDate) ){
ms = ms*10.0 + *zDate - '0';
rScale *= 10.0;
zDate++;
}
ms /= rScale;
}
}else{
s = 0;
}
p->validJD = 0;
p->rawS = 0;
p->validHMS = 1;
| > > > | 24677 24678 24679 24680 24681 24682 24683 24684 24685 24686 24687 24688 24689 24690 24691 24692 24693 |
zDate++;
while( sqlite3Isdigit(*zDate) ){
ms = ms*10.0 + *zDate - '0';
rScale *= 10.0;
zDate++;
}
ms /= rScale;
/* Truncate to avoid problems with sub-milliseconds
** rounding. https://sqlite.org/forum/forumpost/766a2c9231 */
if( ms>0.999 ) ms = 0.999;
}
}else{
s = 0;
}
p->validJD = 0;
p->rawS = 0;
p->validHMS = 1;
|
| ︙ | ︙ | |||
25882 25883 25884 25885 25886 25887 25888 |
case 'd': /* Fall thru */
case 'e': {
sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D);
break;
}
case 'f': { /* Fractional seconds. (Non-standard) */
double s = x.s;
| | | 25887 25888 25889 25890 25891 25892 25893 25894 25895 25896 25897 25898 25899 25900 25901 |
case 'd': /* Fall thru */
case 'e': {
sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D);
break;
}
case 'f': { /* Fractional seconds. (Non-standard) */
double s = x.s;
if( NEVER(s>59.999) ) s = 59.999;
sqlite3_str_appendf(&sRes, "%06.3f", s);
break;
}
case 'F': {
sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D);
break;
}
|
| ︙ | ︙ | |||
33813 33814 33815 33816 33817 33818 33819 |
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; i<pList->nId; i++){
char *zName = pList->a[i].zName;
int moreToFollow = i<pList->nId - 1;
if( zName==0 ) zName = "(null)";
sqlite3TreeViewPush(&pView, moreToFollow);
sqlite3TreeViewLine(pView, 0);
| < | < < < < < < < < < < < < < | 33818 33819 33820 33821 33822 33823 33824 33825 33826 33827 33828 33829 33830 33831 33832 |
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; i<pList->nId; i++){
char *zName = pList->a[i].zName;
int moreToFollow = i<pList->nId - 1;
if( zName==0 ) zName = "(null)";
sqlite3TreeViewPush(&pView, moreToFollow);
sqlite3TreeViewLine(pView, 0);
fprintf(stdout, "%s\n", zName);
sqlite3TreeViewPop(&pView);
}
}
}
SQLITE_PRIVATE void sqlite3TreeViewIdList(
TreeView *pView,
const IdList *pList,
|
| ︙ | ︙ | |||
40168 40169 40170 40171 40172 40173 40174 |
int rc;
unixInodeInfo *pInode = pFile->pInode;
assert( pInode!=0 );
assert( sqlite3_mutex_held(pInode->pLockMutex) );
if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){
if( pInode->bProcessLock==0 ){
struct flock lock;
| | | 40159 40160 40161 40162 40163 40164 40165 40166 40167 40168 40169 40170 40171 40172 40173 |
int rc;
unixInodeInfo *pInode = pFile->pInode;
assert( pInode!=0 );
assert( sqlite3_mutex_held(pInode->pLockMutex) );
if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){
if( pInode->bProcessLock==0 ){
struct flock lock;
/* assert( pInode->nLock==0 ); <-- Not true if unix-excl READONLY used */
lock.l_whence = SEEK_SET;
lock.l_start = SHARED_FIRST;
lock.l_len = SHARED_SIZE;
lock.l_type = F_WRLCK;
rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile);
if( rc<0 ) return rc;
pInode->bProcessLock = 1;
|
| ︙ | ︙ | |||
58051 58052 58053 58054 58055 58056 58057 |
assert( pPager->fd!=0 );
if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */
if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */
#ifndef SQLITE_OMIT_WAL
if( pPager->pWal ){
u32 iRead = 0;
(void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
| | | 58042 58043 58044 58045 58046 58047 58048 58049 58050 58051 58052 58053 58054 58055 58056 |
assert( pPager->fd!=0 );
if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */
if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */
#ifndef SQLITE_OMIT_WAL
if( pPager->pWal ){
u32 iRead = 0;
(void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
if( iRead ) return 0; /* Case (4) */
}
#endif
assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
& SQLITE_IOCAP_SUBPAGE_READ)==0 ){
return 0; /* Case (2) */
}
|
| ︙ | ︙ | |||
83999 84000 84001 84002 84003 84004 84005 |
**
** This is used for testing and debugging only - to help ensure that shallow
** copies (created by OP_SCopy) are not misused.
*/
SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
int i;
Mem *pX;
| > | | | | | | | | | | | | | | | | | | | | > > | 83990 83991 83992 83993 83994 83995 83996 83997 83998 83999 84000 84001 84002 84003 84004 84005 84006 84007 84008 84009 84010 84011 84012 84013 84014 84015 84016 84017 84018 84019 84020 84021 84022 84023 84024 84025 84026 84027 |
**
** This is used for testing and debugging only - to help ensure that shallow
** copies (created by OP_SCopy) are not misused.
*/
SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
int i;
Mem *pX;
if( pMem->bScopy ){
for(i=1, pX=pVdbe->aMem+1; i<pVdbe->nMem; i++, pX++){
if( pX->pScopyFrom==pMem ){
u16 mFlags;
if( pVdbe->db->flags & SQLITE_VdbeTrace ){
sqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n",
(int)(pX - pVdbe->aMem), (int)(pMem - pVdbe->aMem));
}
/* If pX is marked as a shallow copy of pMem, then try to verify that
** no significant changes have been made to pX since the OP_SCopy.
** A significant change would indicated a missed call to this
** function for pX. Minor changes, such as adding or removing a
** dual type, are allowed, as long as the underlying value is the
** same. */
mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
/* pMem is the register that is changing. But also mark pX as
** undefined so that we can quickly detect the shallow-copy error */
pX->flags = MEM_Undefined;
pX->pScopyFrom = 0;
}
}
pMem->bScopy = 0;
}
pMem->pScopyFrom = 0;
}
#endif /* SQLITE_DEBUG */
/*
** Make an shallow copy of pFrom into pTo. Prior contents of
|
| ︙ | ︙ | |||
87161 87162 87163 87164 87165 87166 87167 87168 87169 87170 87171 87172 87173 87174 |
if( N>0 ){
do{
p->flags = flags;
p->db = db;
p->szMalloc = 0;
#ifdef SQLITE_DEBUG
p->pScopyFrom = 0;
#endif
p++;
}while( (--N)>0 );
}
}
/*
| > | 87155 87156 87157 87158 87159 87160 87161 87162 87163 87164 87165 87166 87167 87168 87169 |
if( N>0 ){
do{
p->flags = flags;
p->db = db;
p->szMalloc = 0;
#ifdef SQLITE_DEBUG
p->pScopyFrom = 0;
p->bScopy = 0;
#endif
p++;
}while( (--N)>0 );
}
}
/*
|
| ︙ | ︙ | |||
91346 91347 91348 91349 91350 91351 91352 |
** from interrupting a statement that has not yet started.
*/
if( db->nVdbeActive==0 ){
AtomicStore(&db->u1.isInterrupted, 0);
}
assert( db->nVdbeWrite>0 || db->autoCommit==0
| | | 91341 91342 91343 91344 91345 91346 91347 91348 91349 91350 91351 91352 91353 91354 91355 |
** from interrupting a statement that has not yet started.
*/
if( db->nVdbeActive==0 ){
AtomicStore(&db->u1.isInterrupted, 0);
}
assert( db->nVdbeWrite>0 || db->autoCommit==0
|| ((db->nDeferredCons + db->nDeferredImmCons)==0)
);
#ifndef SQLITE_OMIT_TRACE
if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0
&& !db->init.busy && p->zSql ){
sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
}else{
|
| ︙ | ︙ | |||
91857 91858 91859 91860 91861 91862 91863 91864 91865 91866 91867 91868 91869 91870 |
/* .szMalloc = */ (int)0,
/* .uTemp = */ (u32)0,
/* .zMalloc = */ (char*)0,
/* .xDel = */ (void(*)(void*))0,
#ifdef SQLITE_DEBUG
/* .pScopyFrom = */ (Mem*)0,
/* .mScopyFlags= */ 0,
#endif
};
return &nullMem;
}
/*
** Check to see if column iCol of the given statement is valid. If
| > | 91852 91853 91854 91855 91856 91857 91858 91859 91860 91861 91862 91863 91864 91865 91866 |
/* .szMalloc = */ (int)0,
/* .uTemp = */ (u32)0,
/* .zMalloc = */ (char*)0,
/* .xDel = */ (void(*)(void*))0,
#ifdef SQLITE_DEBUG
/* .pScopyFrom = */ (Mem*)0,
/* .mScopyFlags= */ 0,
/* .bScopy = */ 0,
#endif
};
return &nullMem;
}
/*
** Check to see if column iCol of the given statement is valid. If
|
| ︙ | ︙ | |||
92739 92740 92741 92742 92743 92744 92745 92746 92747 92748 92749 92750 92751 92752 92753 92754 92755 92756 92757 92758 92759 |
** This function is called from within a pre-update callback to retrieve
** a field of the row currently being updated or deleted.
*/
SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p;
Mem *pMem;
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_API_ARMOR
if( db==0 || ppValue==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
p = db->pPreUpdate;
/* Test that this call is being made from within an SQLITE_DELETE or
** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
if( !p || p->op==SQLITE_INSERT ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_old_out;
}
if( p->pPk ){
| > | > > | | 92735 92736 92737 92738 92739 92740 92741 92742 92743 92744 92745 92746 92747 92748 92749 92750 92751 92752 92753 92754 92755 92756 92757 92758 92759 92760 92761 92762 92763 92764 92765 92766 92767 92768 |
** This function is called from within a pre-update callback to retrieve
** a field of the row currently being updated or deleted.
*/
SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p;
Mem *pMem;
int rc = SQLITE_OK;
int iStore = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( db==0 || ppValue==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
p = db->pPreUpdate;
/* Test that this call is being made from within an SQLITE_DELETE or
** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
if( !p || p->op==SQLITE_INSERT ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_old_out;
}
if( p->pPk ){
iStore = sqlite3TableColumnToIndex(p->pPk, iIdx);
}else{
iStore = sqlite3TableColumnToStorage(p->pTab, iIdx);
}
if( iStore>=p->pCsr->nField || iStore<0 ){
rc = SQLITE_RANGE;
goto preupdate_old_out;
}
if( iIdx==p->pTab->iPKey ){
*ppValue = pMem = &p->oldipk;
sqlite3VdbeMemSetInt64(pMem, p->iKey1);
|
| ︙ | ︙ | |||
92786 92787 92788 92789 92790 92791 92792 |
if( rc!=SQLITE_OK ){
sqlite3DbFree(db, aRec);
goto preupdate_old_out;
}
p->aRecord = aRec;
}
| | | | 92785 92786 92787 92788 92789 92790 92791 92792 92793 92794 92795 92796 92797 92798 92799 92800 |
if( rc!=SQLITE_OK ){
sqlite3DbFree(db, aRec);
goto preupdate_old_out;
}
p->aRecord = aRec;
}
pMem = *ppValue = &p->pUnpacked->aMem[iStore];
if( iStore>=p->pUnpacked->nField ){
/* This occurs when the table has been extended using ALTER TABLE
** ADD COLUMN. The value to return is the default value of the column. */
Column *pCol = &p->pTab->aCol[iIdx];
if( pCol->iDflt>0 ){
if( p->apDflt==0 ){
int nByte = sizeof(sqlite3_value*)*p->pTab->nCol;
p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte);
|
| ︙ | ︙ | |||
92891 92892 92893 92894 92895 92896 92897 92898 92899 92900 92901 92902 92903 92904 92905 92906 92907 92908 92909 |
** This function is called from within a pre-update callback to retrieve
** a field of the row currently being updated or inserted.
*/
SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p;
int rc = SQLITE_OK;
Mem *pMem;
#ifdef SQLITE_ENABLE_API_ARMOR
if( db==0 || ppValue==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
p = db->pPreUpdate;
if( !p || p->op==SQLITE_DELETE ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_new_out;
}
if( p->pPk && p->op!=SQLITE_UPDATE ){
| > | > > > | | | | | | | | 92890 92891 92892 92893 92894 92895 92896 92897 92898 92899 92900 92901 92902 92903 92904 92905 92906 92907 92908 92909 92910 92911 92912 92913 92914 92915 92916 92917 92918 92919 92920 92921 92922 92923 92924 92925 92926 92927 92928 92929 92930 92931 92932 92933 92934 92935 92936 92937 92938 92939 92940 92941 92942 92943 92944 92945 92946 92947 92948 92949 92950 92951 92952 92953 92954 92955 92956 92957 92958 92959 92960 92961 92962 92963 92964 92965 92966 92967 92968 |
** This function is called from within a pre-update callback to retrieve
** a field of the row currently being updated or inserted.
*/
SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p;
int rc = SQLITE_OK;
Mem *pMem;
int iStore = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( db==0 || ppValue==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
p = db->pPreUpdate;
if( !p || p->op==SQLITE_DELETE ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_new_out;
}
if( p->pPk && p->op!=SQLITE_UPDATE ){
iStore = sqlite3TableColumnToIndex(p->pPk, iIdx);
}else{
iStore = sqlite3TableColumnToStorage(p->pTab, iIdx);
}
if( iStore>=p->pCsr->nField || iStore<0 ){
rc = SQLITE_RANGE;
goto preupdate_new_out;
}
if( p->op==SQLITE_INSERT ){
/* For an INSERT, memory cell p->iNewReg contains the serialized record
** that is being inserted. Deserialize it. */
UnpackedRecord *pUnpack = p->pNewUnpacked;
if( !pUnpack ){
Mem *pData = &p->v->aMem[p->iNewReg];
rc = ExpandBlob(pData);
if( rc!=SQLITE_OK ) goto preupdate_new_out;
pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z);
if( !pUnpack ){
rc = SQLITE_NOMEM;
goto preupdate_new_out;
}
p->pNewUnpacked = pUnpack;
}
pMem = &pUnpack->aMem[iStore];
if( iIdx==p->pTab->iPKey ){
sqlite3VdbeMemSetInt64(pMem, p->iKey2);
}else if( iStore>=pUnpack->nField ){
pMem = (sqlite3_value *)columnNullValue();
}
}else{
/* For an UPDATE, memory cell (p->iNewReg+1+iStore) contains the required
** value. Make a copy of the cell contents and return a pointer to it.
** It is not safe to return a pointer to the memory cell itself as the
** caller may modify the value text encoding.
*/
assert( p->op==SQLITE_UPDATE );
if( !p->aNew ){
p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField);
if( !p->aNew ){
rc = SQLITE_NOMEM;
goto preupdate_new_out;
}
}
assert( iStore>=0 && iStore<p->pCsr->nField );
pMem = &p->aNew[iStore];
if( pMem->flags==0 ){
if( iIdx==p->pTab->iPKey ){
sqlite3VdbeMemSetInt64(pMem, p->iKey2);
}else{
rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iStore]);
if( rc!=SQLITE_OK ) goto preupdate_new_out;
}
}
}
*ppValue = pMem;
preupdate_new_out:
|
| ︙ | ︙ | |||
94040 94041 94042 94043 94044 94045 94046 94047 94048 94049 94050 94051 94052 94053 |
}
if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
}
static void registerTrace(int iReg, Mem *p){
printf("R[%d] = ", iReg);
memTracePrint(p);
if( p->pScopyFrom ){
printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg]));
}
printf("\n");
sqlite3VdbeCheckMemInvariants(p);
}
/**/ void sqlite3PrintMem(Mem *pMem){
memTracePrint(pMem);
| > | 94043 94044 94045 94046 94047 94048 94049 94050 94051 94052 94053 94054 94055 94056 94057 |
}
if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
}
static void registerTrace(int iReg, Mem *p){
printf("R[%d] = ", iReg);
memTracePrint(p);
if( p->pScopyFrom ){
assert( p->pScopyFrom->bScopy );
printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg]));
}
printf("\n");
sqlite3VdbeCheckMemInvariants(p);
}
/**/ void sqlite3PrintMem(Mem *pMem){
memTracePrint(pMem);
|
| ︙ | ︙ | |||
95023 95024 95025 95026 95027 95028 95029 95030 95031 95032 95033 95034 95035 95036 |
memAboutToChange(p, pOut);
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
pIn1->pScopyFrom = 0;
{ int i;
for(i=1; i<p->nMem; i++){
if( aMem[i].pScopyFrom==pIn1 ){
aMem[i].pScopyFrom = pOut;
}
}
}
#endif
Deephemeralize(pOut);
REGISTER_TRACE(p2++, pOut);
| > | 95027 95028 95029 95030 95031 95032 95033 95034 95035 95036 95037 95038 95039 95040 95041 |
memAboutToChange(p, pOut);
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
pIn1->pScopyFrom = 0;
{ int i;
for(i=1; i<p->nMem; i++){
if( aMem[i].pScopyFrom==pIn1 ){
assert( aMem[i].bScopy );
aMem[i].pScopyFrom = pOut;
}
}
}
#endif
Deephemeralize(pOut);
REGISTER_TRACE(p2++, pOut);
|
| ︙ | ︙ | |||
95095 95096 95097 95098 95099 95100 95101 95102 95103 95104 95105 95106 95107 95108 | pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; assert( pOut!=pIn1 ); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); #ifdef SQLITE_DEBUG pOut->pScopyFrom = pIn1; pOut->mScopyFlags = pIn1->flags; #endif break; } /* Opcode: IntCopy P1 P2 * * * ** Synopsis: r[P2]=r[P1] ** | > | 95100 95101 95102 95103 95104 95105 95106 95107 95108 95109 95110 95111 95112 95113 95114 | pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; assert( pOut!=pIn1 ); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); #ifdef SQLITE_DEBUG pOut->pScopyFrom = pIn1; pOut->mScopyFlags = pIn1->flags; pIn1->bScopy = 1; #endif break; } /* Opcode: IntCopy P1 P2 * * * ** Synopsis: r[P2]=r[P1] ** |
| ︙ | ︙ | |||
111358 111359 111360 111361 111362 111363 111364 |
return pNew;
}
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
IdList *pNew;
int i;
assert( db!=0 );
if( p==0 ) return 0;
| < < < | 111364 111365 111366 111367 111368 111369 111370 111371 111372 111373 111374 111375 111376 111377 111378 111379 111380 111381 111382 111383 111384 |
return pNew;
}
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
IdList *pNew;
int i;
assert( db!=0 );
if( p==0 ) return 0;
pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) );
if( pNew==0 ) return 0;
pNew->nId = p->nId;
for(i=0; i<p->nId; i++){
struct IdList_item *pNewItem = &pNew->a[i];
const struct IdList_item *pOldItem = &p->a[i];
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
}
return pNew;
}
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
Select *pRet = 0;
Select *pNext = 0;
Select **pp = &pRet;
|
| ︙ | ︙ | |||
126724 126725 126726 126727 126728 126729 126730 |
/*
** Delete an IdList.
*/
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
int i;
assert( db!=0 );
if( pList==0 ) return;
| < | 126727 126728 126729 126730 126731 126732 126733 126734 126735 126736 126737 126738 126739 126740 |
/*
** Delete an IdList.
*/
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
int i;
assert( db!=0 );
if( pList==0 ) return;
for(i=0; i<pList->nId; i++){
sqlite3DbFree(db, pList->a[i].zName);
}
sqlite3DbNNFreeNN(db, pList);
}
/*
|
| ︙ | ︙ | |||
128105 128106 128107 128108 128109 128110 128111 |
#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */
static int matchQuality(
FuncDef *p, /* The function we are evaluating for match quality */
int nArg, /* Desired number of arguments. (-1)==any */
u8 enc /* Desired text encoding */
){
int match;
| | > | > > > > > | 128107 128108 128109 128110 128111 128112 128113 128114 128115 128116 128117 128118 128119 128120 128121 128122 128123 128124 128125 128126 128127 128128 128129 128130 128131 128132 |
#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */
static int matchQuality(
FuncDef *p, /* The function we are evaluating for match quality */
int nArg, /* Desired number of arguments. (-1)==any */
u8 enc /* Desired text encoding */
){
int match;
assert( p->nArg>=(-4) && p->nArg!=(-2) );
assert( nArg>=(-2) );
/* Wrong number of arguments means "no match" */
if( p->nArg!=nArg ){
if( nArg==(-2) ) return p->xSFunc==0 ? 0 : FUNC_PERFECT_MATCH;
if( p->nArg>=0 ) return 0;
/* Special p->nArg values available to built-in functions only:
** -3 1 or more arguments required
** -4 2 or more arguments required
*/
if( p->nArg<(-2) && nArg<(-2-p->nArg) ) return 0;
}
/* Give a better score to a function with a specific number of arguments
** than to function that accepts any number of arguments. */
if( p->nArg==nArg ){
match = 4;
}else{
|
| ︙ | ︙ | |||
132074 132075 132076 132077 132078 132079 132080 |
#endif
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
FUNCTION(trim, 1, 3, 0, trimFunc ),
FUNCTION(trim, 2, 3, 0, trimFunc ),
| | < | < | 132082 132083 132084 132085 132086 132087 132088 132089 132090 132091 132092 132093 132094 132095 132096 132097 132098 132099 |
#endif
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
FUNCTION(trim, 1, 3, 0, trimFunc ),
FUNCTION(trim, 2, 3, 0, trimFunc ),
FUNCTION(min, -3, 0, 1, minmaxFunc ),
WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ),
FUNCTION(max, -3, 1, 1, minmaxFunc ),
WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ),
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
FUNCTION2(subtype, 1, 0, 0, subtypeFunc,
SQLITE_FUNC_TYPEOF|SQLITE_SUBTYPE),
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
FUNCTION2(octet_length, 1, 0, 0, bytelengthFunc,SQLITE_FUNC_BYTELEN),
|
| ︙ | ︙ | |||
132106 132107 132108 132109 132110 132111 132112 |
FUNCTION(round, 2, 0, 0, roundFunc ),
#endif
FUNCTION(upper, 1, 0, 0, upperFunc ),
FUNCTION(lower, 1, 0, 0, lowerFunc ),
FUNCTION(hex, 1, 0, 0, hexFunc ),
FUNCTION(unhex, 1, 0, 0, unhexFunc ),
FUNCTION(unhex, 2, 0, 0, unhexFunc ),
| | < | < < | 132112 132113 132114 132115 132116 132117 132118 132119 132120 132121 132122 132123 132124 132125 132126 132127 |
FUNCTION(round, 2, 0, 0, roundFunc ),
#endif
FUNCTION(upper, 1, 0, 0, upperFunc ),
FUNCTION(lower, 1, 0, 0, lowerFunc ),
FUNCTION(hex, 1, 0, 0, hexFunc ),
FUNCTION(unhex, 1, 0, 0, unhexFunc ),
FUNCTION(unhex, 2, 0, 0, unhexFunc ),
FUNCTION(concat, -3, 0, 0, concatFunc ),
FUNCTION(concat_ws, -4, 0, 0, concatwsFunc ),
INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ),
VFUNCTION(random, 0, 0, 0, randomFunc ),
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
|
| ︙ | ︙ | |||
132154 132155 132156 132157 132158 132159 132160 |
#else
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
#endif
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
FUNCTION(unknown, -1, 0, 0, unknownFunc ),
#endif
| < < | 132157 132158 132159 132160 132161 132162 132163 132164 132165 132166 132167 132168 132169 132170 |
#else
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
#endif
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
FUNCTION(unknown, -1, 0, 0, unknownFunc ),
#endif
#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
MFUNCTION(ceil, 1, xCeil, ceilingFunc ),
MFUNCTION(ceiling, 1, xCeil, ceilingFunc ),
MFUNCTION(floor, 1, xFloor, ceilingFunc ),
#if SQLITE_HAVE_C99_MATH_FUNCS
MFUNCTION(trunc, 1, trunc, ceilingFunc ),
#endif
|
| ︙ | ︙ | |||
132193 132194 132195 132196 132197 132198 132199 |
#endif
MFUNCTION(sqrt, 1, sqrt, math1Func ),
MFUNCTION(radians, 1, degToRad, math1Func ),
MFUNCTION(degrees, 1, radToDeg, math1Func ),
MFUNCTION(pi, 0, 0, piFunc ),
#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */
FUNCTION(sign, 1, 0, 0, signFunc ),
| | | < | < | 132194 132195 132196 132197 132198 132199 132200 132201 132202 132203 132204 132205 132206 132207 132208 132209 132210 |
#endif
MFUNCTION(sqrt, 1, sqrt, math1Func ),
MFUNCTION(radians, 1, degToRad, math1Func ),
MFUNCTION(degrees, 1, radToDeg, math1Func ),
MFUNCTION(pi, 0, 0, piFunc ),
#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */
FUNCTION(sign, 1, 0, 0, signFunc ),
INLINE_FUNC(coalesce, -4, INLINEFUNC_coalesce, 0 ),
INLINE_FUNC(iif, -4, INLINEFUNC_iif, 0 ),
INLINE_FUNC(if, -4, INLINEFUNC_iif, 0 ),
};
#ifndef SQLITE_OMIT_ALTERTABLE
sqlite3AlterFunctions();
#endif
sqlite3WindowFunctions();
sqlite3RegisterDateTimeFunctions();
sqlite3RegisterJsonFunctions();
|
| ︙ | ︙ | |||
134643 134644 134645 134646 134647 134648 134649 134650 134651 134652 134653 134654 134655 134656 | int regFromSelect = 0;/* Base register for data coming from SELECT */ int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ int regRowCount = 0; /* Memory cell used for the row counter */ int regIns; /* Block of regs holding rowid+data being inserted */ int regRowid; /* registers holding insert rowid */ int regData; /* register holding first column to insert */ int *aRegIdx = 0; /* One register allocated to each index */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to insert into a view */ Trigger *pTrigger; /* List of triggers on pTab, if required */ int tmask; /* Mask of trigger times */ #endif | > | 134642 134643 134644 134645 134646 134647 134648 134649 134650 134651 134652 134653 134654 134655 134656 | int regFromSelect = 0;/* Base register for data coming from SELECT */ int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ int regRowCount = 0; /* Memory cell used for the row counter */ int regIns; /* Block of regs holding rowid+data being inserted */ int regRowid; /* registers holding insert rowid */ int regData; /* register holding first column to insert */ int *aRegIdx = 0; /* One register allocated to each index */ int *aTabColMap = 0; /* Mapping from pTab columns to pCol entries */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to insert into a view */ Trigger *pTrigger; /* List of triggers on pTab, if required */ int tmask; /* Mask of trigger times */ #endif |
| ︙ | ︙ | |||
134787 134788 134789 134790 134791 134792 134793 |
** bIdListInOrder is true if the columns in IDLIST are in storage
** order. This enables an optimization that avoids shuffling the
** columns into storage order. False negatives are harmless,
** but false positives will cause database corruption.
*/
bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0;
if( pColumn ){
| | | | < < > > | | | 134787 134788 134789 134790 134791 134792 134793 134794 134795 134796 134797 134798 134799 134800 134801 134802 134803 134804 134805 134806 134807 134808 134809 |
** bIdListInOrder is true if the columns in IDLIST are in storage
** order. This enables an optimization that avoids shuffling the
** columns into storage order. False negatives are harmless,
** but false positives will cause database corruption.
*/
bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0;
if( pColumn ){
aTabColMap = sqlite3DbMallocZero(db, pTab->nCol*sizeof(int));
if( aTabColMap==0 ) goto insert_cleanup;
for(i=0; i<pColumn->nId; i++){
const char *zCName = pColumn->a[i].zName;
u8 hName = sqlite3StrIHash(zCName);
for(j=0; j<pTab->nCol; j++){
if( pTab->aCol[j].hName!=hName ) continue;
if( sqlite3StrICmp(zCName, pTab->aCol[j].zCnName)==0 ){
if( aTabColMap[j]==0 ) aTabColMap[j] = i+1;
if( i!=j ) bIdListInOrder = 0;
if( j==pTab->iPKey ){
ipkColumn = i; assert( !withoutRowid );
}
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){
sqlite3ErrorMsg(pParse,
|
| ︙ | ︙ | |||
135117 135118 135119 135120 135121 135122 135123 |
sqlite3ExprCodeFactorable(pParse,
sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
iRegStore);
continue;
}
}
if( pColumn ){
| | | | | | 135117 135118 135119 135120 135121 135122 135123 135124 135125 135126 135127 135128 135129 135130 135131 135132 135133 135134 135135 135136 135137 135138 135139 135140 135141 |
sqlite3ExprCodeFactorable(pParse,
sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
iRegStore);
continue;
}
}
if( pColumn ){
j = aTabColMap[i];
assert( j>=0 && j<=pColumn->nId );
if( j==0 ){
/* A column not named in the insert column list gets its
** default value */
sqlite3ExprCodeFactorable(pParse,
sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
iRegStore);
continue;
}
k = j - 1;
}else if( nColumn==0 ){
/* This is INSERT INTO ... DEFAULT VALUES. Load the default value. */
sqlite3ExprCodeFactorable(pParse,
sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
iRegStore);
continue;
}else{
|
| ︙ | ︙ | |||
135372 135373 135374 135375 135376 135377 135378 | } insert_cleanup: sqlite3SrcListDelete(db, pTabList); sqlite3ExprListDelete(db, pList); sqlite3UpsertDelete(db, pUpsert); sqlite3SelectDelete(db, pSelect); | > | > > | 135372 135373 135374 135375 135376 135377 135378 135379 135380 135381 135382 135383 135384 135385 135386 135387 135388 135389 |
}
insert_cleanup:
sqlite3SrcListDelete(db, pTabList);
sqlite3ExprListDelete(db, pList);
sqlite3UpsertDelete(db, pUpsert);
sqlite3SelectDelete(db, pSelect);
if( pColumn ){
sqlite3IdListDelete(db, pColumn);
sqlite3DbFree(db, aTabColMap);
}
if( aRegIdx ) sqlite3DbNNFreeNN(db, aRegIdx);
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
** they may interfere with compilation of other functions in this file
** (or in another file, if this file becomes part of the amalgamation). */
#ifdef isView
|
| ︙ | ︙ | |||
157959 157960 157961 157962 157963 157964 157965 157966 | } u; u32 wsFlags; /* WHERE_* flags describing the plan */ u16 nLTerm; /* Number of entries in aLTerm[] */ u16 nSkip; /* Number of NULL aLTerm[] entries */ /**** whereLoopXfer() copies fields above ***********************/ # define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) u16 nLSlot; /* Number of slots allocated for aLTerm[] */ LogEst rStarDelta; /* Cost delta due to star-schema heuristic. Not | > | > | 157962 157963 157964 157965 157966 157967 157968 157969 157970 157971 157972 157973 157974 157975 157976 157977 157978 157979 |
} u;
u32 wsFlags; /* WHERE_* flags describing the plan */
u16 nLTerm; /* Number of entries in aLTerm[] */
u16 nSkip; /* Number of NULL aLTerm[] entries */
/**** whereLoopXfer() copies fields above ***********************/
# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot)
u16 nLSlot; /* Number of slots allocated for aLTerm[] */
#ifdef WHERETRACE_ENABLED
LogEst rStarDelta; /* Cost delta due to star-schema heuristic. Not
** initialized unless pWInfo->bStarUsed */
#endif
WhereTerm **aLTerm; /* WhereTerms used */
WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */
};
/* This object holds the prerequisites and the cost of running a
** subquery on one operand of an OR operator in the WHERE clause.
|
| ︙ | ︙ | |||
158009 158010 158011 158012 158013 158014 158015 |
** at the end is the chosen query plan.
*/
struct WherePath {
Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */
Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */
LogEst nRow; /* Estimated number of rows generated by this path */
LogEst rCost; /* Total cost of this path */
| | | 158014 158015 158016 158017 158018 158019 158020 158021 158022 158023 158024 158025 158026 158027 158028 |
** at the end is the chosen query plan.
*/
struct WherePath {
Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */
Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */
LogEst nRow; /* Estimated number of rows generated by this path */
LogEst rCost; /* Total cost of this path */
LogEst rUnsort; /* Total cost of this path ignoring sorting costs */
i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */
WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */
};
/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause. Each WHERE
|
| ︙ | ︙ | |||
158282 158283 158284 158285 158286 158287 158288 | u8 nLevel; /* Number of nested loop */ i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ unsigned bDeferredSeek :1; /* Uses OP_DeferredSeek */ unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ | | | > > > > | 158287 158288 158289 158290 158291 158292 158293 158294 158295 158296 158297 158298 158299 158300 158301 158302 158303 158304 158305 158306 158307 | u8 nLevel; /* Number of nested loop */ i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ unsigned bDeferredSeek :1; /* Uses OP_DeferredSeek */ unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ unsigned sorted :1; /* True if really sorted (not just grouped) */ unsigned bStarDone :1; /* True if check for star-query is complete */ unsigned bStarUsed :1; /* True if star-query heuristic is used */ LogEst nRowOut; /* Estimated number of output rows */ #ifdef WHERETRACE_ENABLED LogEst rTotalCost; /* Total cost of the solution */ #endif int iTop; /* The very beginning of the WHERE loop */ int iEndWhere; /* End of the WHERE clause itself */ WhereLoop *pLoops; /* List of all WhereLoop objects */ WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ WhereClause sWC; /* Decomposition of the WHERE clause */ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ |
| ︙ | ︙ | |||
164230 164231 164232 164233 164234 164235 164236 |
Table *pTab = pIdx->pTable;
const char *zSep = "";
char *zText = 0;
int ii = 0;
sqlite3_str *pStr = sqlite3_str_new(pParse->db);
sqlite3_str_appendf(pStr,"CREATE AUTOMATIC INDEX ON %s(", pTab->zName);
assert( pIdx->nColumn>1 );
| | | 164239 164240 164241 164242 164243 164244 164245 164246 164247 164248 164249 164250 164251 164252 164253 |
Table *pTab = pIdx->pTable;
const char *zSep = "";
char *zText = 0;
int ii = 0;
sqlite3_str *pStr = sqlite3_str_new(pParse->db);
sqlite3_str_appendf(pStr,"CREATE AUTOMATIC INDEX ON %s(", pTab->zName);
assert( pIdx->nColumn>1 );
assert( pIdx->aiColumn[pIdx->nColumn-1]==XN_ROWID || !HasRowid(pTab) );
for(ii=0; ii<(pIdx->nColumn-1); ii++){
const char *zName = 0;
int iCol = pIdx->aiColumn[ii];
zName = pTab->aCol[iCol].zCnName;
sqlite3_str_appendf(pStr, "%s%s", zSep, zName);
zSep = ", ";
|
| ︙ | ︙ | |||
164360 164361 164362 164363 164364 164365 164366 164367 164368 164369 164370 164371 164372 164373 164374 164375 164376 164377 164378 |
** original table changes and the index and table cannot both be used
** if they go out of sync.
*/
if( IsView(pTable) ){
extraCols = ALLBITS & ~idxCols;
}else{
extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
}
mxBitCol = MIN(BMS-1,pTable->nCol);
testcase( pTable->nCol==BMS-1 );
testcase( pTable->nCol==BMS-2 );
for(i=0; i<mxBitCol; i++){
if( extraCols & MASKBIT(i) ) nKeyCol++;
}
if( pSrc->colUsed & MASKBIT(BMS-1) ){
nKeyCol += pTable->nCol - BMS + 1;
}
/* Construct the Index object to describe this index */
| > > > > > > > > > > > > > | > | 164369 164370 164371 164372 164373 164374 164375 164376 164377 164378 164379 164380 164381 164382 164383 164384 164385 164386 164387 164388 164389 164390 164391 164392 164393 164394 164395 164396 164397 164398 164399 164400 164401 164402 164403 164404 164405 164406 164407 164408 164409 |
** original table changes and the index and table cannot both be used
** if they go out of sync.
*/
if( IsView(pTable) ){
extraCols = ALLBITS & ~idxCols;
}else{
extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
}
if( !HasRowid(pTable) ){
/* For WITHOUT ROWID tables, ensure that all PRIMARY KEY columns are
** either in the idxCols mask or in the extraCols mask */
for(i=0; i<pTable->nCol; i++){
if( (pTable->aCol[i].colFlags & COLFLAG_PRIMKEY)==0 ) continue;
if( i>=BMS-1 ){
extraCols |= MASKBIT(BMS-1);
break;
}
if( idxCols & MASKBIT(i) ) continue;
extraCols |= MASKBIT(i);
}
}
mxBitCol = MIN(BMS-1,pTable->nCol);
testcase( pTable->nCol==BMS-1 );
testcase( pTable->nCol==BMS-2 );
for(i=0; i<mxBitCol; i++){
if( extraCols & MASKBIT(i) ) nKeyCol++;
}
if( pSrc->colUsed & MASKBIT(BMS-1) ){
nKeyCol += pTable->nCol - BMS + 1;
}
/* Construct the Index object to describe this index */
pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+HasRowid(pTable),
0, &zNotUsed);
if( pIdx==0 ) goto end_auto_index_create;
pLoop->u.btree.pIndex = pIdx;
pIdx->zName = "auto-index";
pIdx->pTable = pTable;
n = 0;
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
|
| ︙ | ︙ | |||
164428 164429 164430 164431 164432 164433 164434 |
for(i=BMS-1; i<pTable->nCol; i++){
pIdx->aiColumn[n] = i;
pIdx->azColl[n] = sqlite3StrBINARY;
n++;
}
}
assert( n==nKeyCol );
| > | | > | 164451 164452 164453 164454 164455 164456 164457 164458 164459 164460 164461 164462 164463 164464 164465 164466 164467 164468 |
for(i=BMS-1; i<pTable->nCol; i++){
pIdx->aiColumn[n] = i;
pIdx->azColl[n] = sqlite3StrBINARY;
n++;
}
}
assert( n==nKeyCol );
if( HasRowid(pTable) ){
pIdx->aiColumn[n] = XN_ROWID;
pIdx->azColl[n] = sqlite3StrBINARY;
}
/* Create the automatic index */
explainAutomaticIndex(pParse, pIdx, pPartial!=0, &addrExp);
assert( pLevel->iIdxCur>=0 );
pLevel->iIdxCur = pParse->nTab++;
sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
|
| ︙ | ︙ | |||
165696 165697 165698 165699 165700 165701 165702 165703 |
** | | .-- prereq Idx wsFlags----. | |
** | | | Name | | |
** | | | __|__ nEq ---. ___|__ | __|__
** | / \ / \ / \ | / \ / \ / \
** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31
*/
SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){
if( pWC ){
| > | > | 165721 165722 165723 165724 165725 165726 165727 165728 165729 165730 165731 165732 165733 165734 165735 165736 165737 165738 165739 165740 165741 165742 165743 165744 165745 165746 165747 |
** | | .-- prereq Idx wsFlags----. | |
** | | | Name | | |
** | | | __|__ nEq ---. ___|__ | __|__
** | / \ / \ / \ | / \ / \ / \
** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31
*/
SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){
WhereInfo *pWInfo;
if( pWC ){
pWInfo = pWC->pWInfo;
int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
Table *pTab = pItem->pSTab;
Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
sqlite3DebugPrintf(" %12s",
pItem->zAlias ? pItem->zAlias : pTab->zName);
}else{
pWInfo = 0;
sqlite3DebugPrintf("%c%2d.%03llx.%03llx %c%d",
p->cId, p->iTab, p->maskSelf, p->prereq & 0xfff, p->cId, p->iTab);
}
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
const char *zName;
if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
|
| ︙ | ︙ | |||
165738 165739 165740 165741 165742 165743 165744 |
sqlite3_free(z);
}
if( p->wsFlags & WHERE_SKIPSCAN ){
sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
}else{
sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm);
}
| > > > > | > | 165765 165766 165767 165768 165769 165770 165771 165772 165773 165774 165775 165776 165777 165778 165779 165780 165781 165782 165783 165784 |
sqlite3_free(z);
}
if( p->wsFlags & WHERE_SKIPSCAN ){
sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
}else{
sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm);
}
if( pWInfo && pWInfo->bStarUsed && p->rStarDelta!=0 ){
sqlite3DebugPrintf(" cost %d,%d,%d delta=%d\n",
p->rSetup, p->rRun, p->nOut, p->rStarDelta);
}else{
sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
}
if( p->nLTerm && (sqlite3WhereTrace & 0x4000)!=0 ){
int i;
for(i=0; i<p->nLTerm; i++){
sqlite3WhereTermPrint(p->aLTerm[i], i);
}
}
}
|
| ︙ | ︙ | |||
167204 167205 167206 167207 167208 167209 167210 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* Automatic indexes */ if( !pBuilder->pOrSet /* Not part of an OR optimization */ && (pWInfo->wctrlFlags & (WHERE_RIGHT_JOIN|WHERE_OR_SUBCLAUSE))==0 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 && !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */ && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ | < | 167236 167237 167238 167239 167240 167241 167242 167243 167244 167245 167246 167247 167248 167249 |
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/* Automatic indexes */
if( !pBuilder->pOrSet /* Not part of an OR optimization */
&& (pWInfo->wctrlFlags & (WHERE_RIGHT_JOIN|WHERE_OR_SUBCLAUSE))==0
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
&& !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */
&& !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */
&& !pSrc->fg.isCorrelated /* Not a correlated subquery */
&& !pSrc->fg.isRecursive /* Not a recursive common table expression. */
&& (pSrc->fg.jointype & JT_RIGHT)==0 /* Not the right tab of a RIGHT JOIN */
){
/* Generate auto-index WhereLoops */
LogEst rLogSize; /* Logarithm of the number of rows in the table */
WhereTerm *pTerm;
|
| ︙ | ︙ | |||
168707 168708 168709 168710 168711 168712 168713 | ** each step of the solver search algorithm to avoid exponential behavior. ** ** The value returned is a tuning parameter. Currently the value is: ** ** 18 for star queries ** 12 otherwise ** | | | > | | > > | > > | | | > | > > > > > > > > > | < > > > > > > > > > > > > > | | | | > > | > > | > > > > > | > > > > > > | > > | > | > > > > > > | > | > > > > > > > > > > > > | > > > > > > > | > > > > > | | > | > > > > | > | | < < | | > > | > > > | > | > | > | < > > | > > | > > > > > > > > > > > > | > > > > > > | | > > | > > > > > > > > > > > > > > > > > > > > > > | 168738 168739 168740 168741 168742 168743 168744 168745 168746 168747 168748 168749 168750 168751 168752 168753 168754 168755 168756 168757 168758 168759 168760 168761 168762 168763 168764 168765 168766 168767 168768 168769 168770 168771 168772 168773 168774 168775 168776 168777 168778 168779 168780 168781 168782 168783 168784 168785 168786 168787 168788 168789 168790 168791 168792 168793 168794 168795 168796 168797 168798 168799 168800 168801 168802 168803 168804 168805 168806 168807 168808 168809 168810 168811 168812 168813 168814 168815 168816 168817 168818 168819 168820 168821 168822 168823 168824 168825 168826 168827 168828 168829 168830 168831 168832 168833 168834 168835 168836 168837 168838 168839 168840 168841 168842 168843 168844 168845 168846 168847 168848 168849 168850 168851 168852 168853 168854 168855 168856 168857 168858 168859 168860 168861 168862 168863 168864 168865 168866 168867 168868 168869 168870 168871 168872 168873 168874 168875 168876 168877 168878 168879 168880 168881 168882 168883 168884 168885 168886 168887 168888 168889 168890 168891 168892 168893 168894 168895 168896 168897 168898 168899 168900 168901 168902 168903 168904 168905 168906 168907 168908 168909 168910 168911 168912 168913 168914 168915 168916 168917 168918 168919 168920 168921 168922 168923 168924 168925 168926 168927 168928 168929 168930 168931 168932 168933 168934 168935 168936 168937 168938 168939 168940 168941 168942 168943 168944 168945 168946 |
** each step of the solver search algorithm to avoid exponential behavior.
**
** The value returned is a tuning parameter. Currently the value is:
**
** 18 for star queries
** 12 otherwise
**
** For the purposes of this heuristic, a star-query is defined as a query
** with a large central table that is joined using an INNER JOIN,
** not CROSS or OUTER JOINs, against four or more smaller tables.
** The central table is called the "fact" table. The smaller tables
** that get joined are "dimension tables". Also, any table that is
** self-joined cannot be a dimension table; we assume that dimension
** tables may only be joined against fact tables.
**
** SIDE EFFECT: (and really the whole point of this subroutine)
**
** If pWInfo describes a star-query, then the cost for SCANs of dimension
** WhereLoops is increased to be slightly larger than the cost of a SCAN
** in the fact table. Only SCAN costs are increased. SEARCH costs are
** unchanged. This heuristic helps keep fact tables in outer loops. Without
** this heuristic, paths with fact tables in outer loops tend to get pruned
** by the mxChoice limit on the number of paths, resulting in poor query
** plans. See the starschema1.test test module for examples of queries
** that need this heuristic to find good query plans.
**
** This heuristic can be completely disabled, so that no query is
** considered a star-query, using SQLITE_TESTCTRL_OPTIMIZATION to
** disable the SQLITE_StarQuery optimization. In the CLI, the command
** to do that is: ".testctrl opt -starquery".
**
** HISTORICAL NOTES:
**
** This optimization was first added on 2024-05-09 by check-in 38db9b5c83d.
** The original optimization reduced the cost and output size estimate for
** fact tables to help them move to outer loops. But months later (as people
** started upgrading) performance regression reports started caming in,
** including:
**
** forum post b18ef983e68d06d1 (2024-12-21)
** forum post 0025389d0860af82 (2025-01-14)
** forum post d87570a145599033 (2025-01-17)
**
** To address these, the criteria for a star-query was tightened to exclude
** cases where the fact and dimensions are separated by an outer join, and
** the affect of star-schema detection was changed to increase the rRun cost
** on just full table scans of dimension tables, rather than reducing costs
** in the all access methods of the fact table.
*/
static int computeMxChoice(WhereInfo *pWInfo){
int nLoop = pWInfo->nLevel; /* Number of terms in the join */
WhereLoop *pWLoop; /* For looping over WhereLoops */
#ifdef SQLITE_DEBUG
/* The star-query detection code below makes use of the following
** properties of the WhereLoop list, so verify them before
** continuing:
** (1) .maskSelf is the bitmask corresponding to .iTab
** (2) The WhereLoop list is in ascending .iTab order
*/
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
assert( pWLoop->maskSelf==MASKBIT(pWLoop->iTab) );
assert( pWLoop->pNextLoop==0 || pWLoop->iTab<=pWLoop->pNextLoop->iTab );
}
#endif /* SQLITE_DEBUG */
if( nLoop>=5
&& !pWInfo->bStarDone
&& OptimizationEnabled(pWInfo->pParse->db, SQLITE_StarQuery)
){
SrcItem *aFromTabs; /* All terms of the FROM clause */
int iFromIdx; /* Term of FROM clause is the candidate fact-table */
Bitmask m; /* Bitmask for candidate fact-table */
Bitmask mSelfJoin = 0; /* Tables that cannot be dimension tables */
WhereLoop *pStart; /* Where to start searching for dimension-tables */
pWInfo->bStarDone = 1; /* Only do this computation once */
/* Look for fact tables with four or more dimensions where the
** dimension tables are not separately from the fact tables by an outer
** or cross join. Adjust cost weights if found.
*/
assert( !pWInfo->bStarUsed );
aFromTabs = pWInfo->pTabList->a;
pStart = pWInfo->pLoops;
for(iFromIdx=0, m=1; iFromIdx<nLoop; iFromIdx++, m<<=1){
int nDep = 0; /* Number of dimension tables */
LogEst mxRun; /* Maximum SCAN cost of a fact table */
Bitmask mSeen = 0; /* Mask of dimension tables */
SrcItem *pFactTab; /* The candidate fact table */
pFactTab = aFromTabs + iFromIdx;
if( (pFactTab->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
/* If the candidate fact-table is the right table of an outer join
** restrict the search for dimension-tables to be tables to the right
** of the fact-table. */
if( iFromIdx+4 > nLoop ) break; /* Impossible to reach nDep>=4 */
while( pStart && pStart->iTab<=iFromIdx ){
pStart = pStart->pNextLoop;
}
}
for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){
if( (aFromTabs[pWLoop->iTab].fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
/* Fact-tables and dimension-tables cannot be separated by an
** outer join (at least for the definition of fact- and dimension-
** used by this heuristic). */
break;
}
if( (pWLoop->prereq & m)!=0 /* pWInfo depends on iFromIdx */
&& (pWLoop->maskSelf & mSeen)==0 /* pWInfo not already a dependency */
&& (pWLoop->maskSelf & mSelfJoin)==0 /* Not a self-join */
){
if( aFromTabs[pWLoop->iTab].pSTab==pFactTab->pSTab ){
mSelfJoin |= m;
}else{
nDep++;
mSeen |= pWLoop->maskSelf;
}
}
}
if( nDep<=3 ) continue;
/* If we reach this point, it means that pFactTab is a fact table
** with four or more dimensions connected by inner joins. Proceed
** to make cost adjustments. */
#ifdef WHERETRACE_ENABLED
/* Make sure rStarDelta values are initialized */
if( !pWInfo->bStarUsed ){
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
pWLoop->rStarDelta = 0;
}
}
#endif
pWInfo->bStarUsed = 1;
/* Compute the maximum cost of any WhereLoop for the
** fact table plus one epsilon */
mxRun = LOGEST_MIN;
for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){
if( pWLoop->iTab<iFromIdx ) continue;
if( pWLoop->iTab>iFromIdx ) break;
if( pWLoop->rRun>mxRun ) mxRun = pWLoop->rRun;
}
if( ALWAYS(mxRun<LOGEST_MAX) ) mxRun++;
/* Increase the cost of table scans for dimension tables to be
** slightly more than the maximum cost of the fact table */
for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){
if( (pWLoop->maskSelf & mSeen)==0 ) continue;
if( pWLoop->nLTerm ) continue;
if( pWLoop->rRun<mxRun ){
#ifdef WHERETRACE_ENABLED /* 0x80000 */
if( sqlite3WhereTrace & 0x80000 ){
SrcItem *pDim = aFromTabs + pWLoop->iTab;
sqlite3DebugPrintf(
"Increase SCAN cost of dimension %s(%d) of fact %s(%d) to %d\n",
pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, pWLoop->iTab,
pFactTab->zAlias ? pFactTab->zAlias : pFactTab->pSTab->zName,
iFromIdx, mxRun
);
}
pWLoop->rStarDelta = mxRun - pWLoop->rRun;
#endif /* WHERETRACE_ENABLED */
pWLoop->rRun = mxRun;
}
}
}
#ifdef WHERETRACE_ENABLED /* 0x80000 */
if( (sqlite3WhereTrace & 0x80000)!=0 && pWInfo->bStarUsed ){
sqlite3DebugPrintf("WhereLoops changed by star-query heuristic:\n");
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
if( pWLoop->rStarDelta ){
sqlite3WhereLoopPrint(pWLoop, &pWInfo->sWC);
}
}
}
#endif
}
return pWInfo->bStarUsed ? 18 : 12;
}
/*
** Two WhereLoop objects, pCandidate and pBaseline, are known to have the
** same cost. Look deep into each to see if pCandidate is even slightly
** better than pBaseline. Return false if it is, if pCandidate is is preferred.
** Return true if pBaseline is preferred or if we cannot tell the difference.
**
** Result Meaning
** -------- ----------------------------------------------------------
** true We cannot tell the difference in pCandidate and pBaseline
** false pCandidate seems like a better choice than pBaseline
*/
static SQLITE_NOINLINE int whereLoopIsNoBetter(
const WhereLoop *pCandidate,
const WhereLoop *pBaseline
){
if( (pCandidate->wsFlags & WHERE_INDEXED)==0 ) return 1;
if( (pBaseline->wsFlags & WHERE_INDEXED)==0 ) return 1;
if( pCandidate->u.btree.pIndex->szIdxRow <
pBaseline->u.btree.pIndex->szIdxRow ) return 0;
return 1;
}
/*
** Given the list of WhereLoop objects at pWInfo->pLoops, this routine
** attempts to find the lowest cost path that visits each WhereLoop
** once. This path is then loaded into the pWInfo->a[].pWLoop fields.
**
|
| ︙ | ︙ | |||
168792 168793 168794 168795 168796 168797 168798 | int nLoop; /* Number of terms in the join */ Parse *pParse; /* Parsing context */ int iLoop; /* Loop counter over the terms of the join */ int ii, jj; /* Loop counters */ int mxI = 0; /* Index of next entry to replace */ int nOrderBy; /* Number of ORDER BY clause terms */ LogEst mxCost = 0; /* Maximum cost of a set of paths */ | | | 168956 168957 168958 168959 168960 168961 168962 168963 168964 168965 168966 168967 168968 168969 168970 | int nLoop; /* Number of terms in the join */ Parse *pParse; /* Parsing context */ int iLoop; /* Loop counter over the terms of the join */ int ii, jj; /* Loop counters */ int mxI = 0; /* Index of next entry to replace */ int nOrderBy; /* Number of ORDER BY clause terms */ LogEst mxCost = 0; /* Maximum cost of a set of paths */ LogEst mxUnsort = 0; /* Maximum unsorted cost of a set of path */ int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */ WherePath *aFrom; /* All nFrom paths at the previous level */ WherePath *aTo; /* The nTo best paths at the current level */ WherePath *pFrom; /* An element of aFrom[] that we are working on */ WherePath *pTo; /* An element of aTo[] that we are working on */ WhereLoop *pWLoop; /* One of the WhereLoop objects */ WhereLoop **pX; /* Used to divy up the pSpace memory */ |
| ︙ | ︙ | |||
168821 168822 168823 168824 168825 168826 168827 168828 |
** 2 5
** 3+ 12 or 18 // see computeMxChoice()
*/
if( nLoop<=1 ){
mxChoice = 1;
}else if( nLoop==2 ){
mxChoice = 5;
}else{
| > > | | 168985 168986 168987 168988 168989 168990 168991 168992 168993 168994 168995 168996 168997 168998 168999 169000 169001 169002 |
** 2 5
** 3+ 12 or 18 // see computeMxChoice()
*/
if( nLoop<=1 ){
mxChoice = 1;
}else if( nLoop==2 ){
mxChoice = 5;
}else if( pParse->nErr ){
mxChoice = 1;
}else{
mxChoice = computeMxChoice(pWInfo);
}
assert( nLoop<=pWInfo->pTabList->nSrc );
/* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this
** case the purpose of this call is to estimate the number of rows returned
** by the overall query. Once this estimate has been obtained, the caller
** will invoke this function a second time, passing the estimate as the
|
| ︙ | ︙ | |||
168889 168890 168891 168892 168893 168894 168895 |
** best paths at each generation */
for(iLoop=0; iLoop<nLoop; iLoop++){
nTo = 0;
for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
LogEst nOut; /* Rows visited by (pFrom+pWLoop) */
LogEst rCost; /* Cost of path (pFrom+pWLoop) */
| | | | | | 169055 169056 169057 169058 169059 169060 169061 169062 169063 169064 169065 169066 169067 169068 169069 169070 169071 169072 169073 169074 169075 169076 169077 169078 169079 169080 169081 169082 169083 169084 169085 169086 169087 169088 169089 169090 169091 |
** best paths at each generation */
for(iLoop=0; iLoop<nLoop; iLoop++){
nTo = 0;
for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
LogEst nOut; /* Rows visited by (pFrom+pWLoop) */
LogEst rCost; /* Cost of path (pFrom+pWLoop) */
LogEst rUnsort; /* Unsorted cost of (pFrom+pWLoop) */
i8 isOrdered; /* isOrdered for (pFrom+pWLoop) */
Bitmask maskNew; /* Mask of src visited by (..) */
Bitmask revMask; /* Mask of rev-order loops for (..) */
if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){
/* Do not use an automatic index if the this loop is expected
** to run less than 1.25 times. It is tempting to also exclude
** automatic index usage on an outer loop, but sometimes an automatic
** index is useful in the outer loop of a correlated subquery. */
assert( 10==sqlite3LogEst(2) );
continue;
}
/* At this point, pWLoop is a candidate to be the next loop.
** Compute its cost */
rUnsort = pWLoop->rRun + pFrom->nRow;
if( pWLoop->rSetup ){
rUnsort = sqlite3LogEstAdd(pWLoop->rSetup, rUnsort);
}
rUnsort = sqlite3LogEstAdd(rUnsort, pFrom->rUnsort);
nOut = pFrom->nRow + pWLoop->nOut;
maskNew = pFrom->maskLoop | pWLoop->maskSelf;
isOrdered = pFrom->isOrdered;
if( isOrdered<0 ){
revMask = 0;
isOrdered = wherePathSatisfiesOrderBy(pWInfo,
pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
|
| ︙ | ︙ | |||
168933 168934 168935 168936 168937 168938 168939 |
pWInfo, nRowEst, nOrderBy, isOrdered
);
}
/* TUNING: Add a small extra penalty (3) to sorting as an
** extra encouragement to the query planner to select a plan
** where the rows emerge in the correct order without any sorting
** required. */
| | | | | | 169099 169100 169101 169102 169103 169104 169105 169106 169107 169108 169109 169110 169111 169112 169113 169114 169115 169116 169117 169118 169119 169120 169121 |
pWInfo, nRowEst, nOrderBy, isOrdered
);
}
/* TUNING: Add a small extra penalty (3) to sorting as an
** extra encouragement to the query planner to select a plan
** where the rows emerge in the correct order without any sorting
** required. */
rCost = sqlite3LogEstAdd(rUnsort, aSortCost[isOrdered]) + 3;
WHERETRACE(0x002,
("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",
aSortCost[isOrdered], (nOrderBy-isOrdered), nOrderBy,
rUnsort, rCost));
}else{
rCost = rUnsort;
rUnsort -= 2; /* TUNING: Slight bias in favor of no-sort plans */
}
/* Check to see if pWLoop should be added to the set of
** mxChoice best-so-far paths.
**
** First look for an existing path among best-so-far paths
** that covers the same set of loops and has the same isOrdered
|
| ︙ | ︙ | |||
168967 168968 168969 168970 168971 168972 168973 |
testcase( jj==nTo-1 );
break;
}
}
if( jj>=nTo ){
/* None of the existing best-so-far paths match the candidate. */
if( nTo>=mxChoice
| | | | | | | | | | < | | | | | | | | > < > > > | | 169133 169134 169135 169136 169137 169138 169139 169140 169141 169142 169143 169144 169145 169146 169147 169148 169149 169150 169151 169152 169153 169154 169155 169156 169157 169158 169159 169160 169161 169162 169163 169164 169165 169166 169167 169168 169169 169170 169171 169172 169173 169174 169175 169176 169177 169178 169179 169180 169181 169182 169183 169184 169185 169186 169187 169188 169189 169190 169191 169192 169193 169194 169195 169196 169197 169198 169199 169200 169201 169202 169203 169204 169205 169206 169207 169208 169209 169210 169211 169212 169213 169214 169215 169216 169217 169218 169219 169220 169221 169222 169223 169224 169225 169226 169227 169228 169229 169230 169231 169232 169233 169234 169235 169236 169237 169238 169239 169240 169241 169242 169243 169244 169245 169246 169247 169248 169249 169250 169251 169252 169253 169254 169255 169256 169257 169258 169259 169260 169261 169262 169263 169264 169265 169266 169267 169268 169269 169270 169271 169272 169273 169274 169275 169276 |
testcase( jj==nTo-1 );
break;
}
}
if( jj>=nTo ){
/* None of the existing best-so-far paths match the candidate. */
if( nTo>=mxChoice
&& (rCost>mxCost || (rCost==mxCost && rUnsort>=mxUnsort))
){
/* The current candidate is no better than any of the mxChoice
** paths currently in the best-so-far buffer. So discard
** this candidate as not viable. */
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf("Skip %s cost=%-3d,%3d,%3d order=%c\n",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsort,
isOrdered>=0 ? isOrdered+'0' : '?');
}
#endif
continue;
}
/* If we reach this points it means that the new candidate path
** needs to be added to the set of best-so-far paths. */
if( nTo<mxChoice ){
/* Increase the size of the aTo set by one */
jj = nTo++;
}else{
/* New path replaces the prior worst to keep count below mxChoice */
jj = mxI;
}
pTo = &aTo[jj];
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf("New %s cost=%-3d,%3d,%3d order=%c\n",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsort,
isOrdered>=0 ? isOrdered+'0' : '?');
}
#endif
}else{
/* Control reaches here if best-so-far path pTo=aTo[jj] covers the
** same set of loops and has the same isOrdered setting as the
** candidate path. Check to see if the candidate should replace
** pTo or if the candidate should be skipped.
**
** The conditional is an expanded vector comparison equivalent to:
** (pTo->rCost,pTo->nRow,pTo->rUnsort) <= (rCost,nOut,rUnsort)
*/
if( (pTo->rCost<rCost)
|| (pTo->rCost==rCost && pTo->nRow<nOut)
|| (pTo->rCost==rCost && pTo->nRow==nOut && pTo->rUnsort<rUnsort)
|| (pTo->rCost==rCost && pTo->nRow==nOut && pTo->rUnsort==rUnsort
&& whereLoopIsNoBetter(pWLoop, pTo->aLoop[iLoop]) )
){
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf(
"Skip %s cost=%-3d,%3d,%3d order=%c",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsort,
isOrdered>=0 ? isOrdered+'0' : '?');
sqlite3DebugPrintf(" vs %s cost=%-3d,%3d,%3d order=%c\n",
wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
pTo->rUnsort, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
}
#endif
/* Discard the candidate path from further consideration */
testcase( pTo->rCost==rCost );
continue;
}
testcase( pTo->rCost==rCost+1 );
/* Control reaches here if the candidate path is better than the
** pTo path. Replace pTo with the candidate. */
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf(
"Update %s cost=%-3d,%3d,%3d order=%c",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsort,
isOrdered>=0 ? isOrdered+'0' : '?');
sqlite3DebugPrintf(" was %s cost=%-3d,%3d,%3d order=%c\n",
wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
pTo->rUnsort, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
}
#endif
}
/* pWLoop is a winner. Add it to the set of best so far */
pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf;
pTo->revLoop = revMask;
pTo->nRow = nOut;
pTo->rCost = rCost;
pTo->rUnsort = rUnsort;
pTo->isOrdered = isOrdered;
memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop);
pTo->aLoop[iLoop] = pWLoop;
if( nTo>=mxChoice ){
mxI = 0;
mxCost = aTo[0].rCost;
mxUnsort = aTo[0].nRow;
for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
if( pTo->rCost>mxCost
|| (pTo->rCost==mxCost && pTo->rUnsort>mxUnsort)
){
mxCost = pTo->rCost;
mxUnsort = pTo->rUnsort;
mxI = jj;
}
}
}
}
}
#ifdef WHERETRACE_ENABLED /* >=2 */
if( sqlite3WhereTrace & 0x02 ){
LogEst rMin, rFloor = 0;
int nDone = 0;
int nProgress;
sqlite3DebugPrintf("---- after round %d ----\n", iLoop);
do{
nProgress = 0;
rMin = 0x7fff;
for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){
if( pTo->rCost>rFloor && pTo->rCost<rMin ) rMin = pTo->rCost;
}
for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){
if( pTo->rCost==rMin ){
sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c",
wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?');
if( pTo->isOrdered>0 ){
sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop);
}else{
sqlite3DebugPrintf("\n");
}
nDone++;
nProgress++;
}
}
rFloor = rMin;
}while( nDone<nTo && nProgress>0 );
}
#endif
/* Swap the roles of aFrom and aTo for the next generation */
pFrom = aTo;
aTo = aFrom;
aFrom = pFrom;
|
| ︙ | ︙ | |||
169188 169189 169190 169191 169192 169193 169194 |
if( nOrder==pWInfo->pOrderBy->nExpr ){
pWInfo->sorted = 1;
pWInfo->revMask = revMask;
}
}
}
| | > > > | 169356 169357 169358 169359 169360 169361 169362 169363 169364 169365 169366 169367 169368 169369 169370 169371 169372 169373 |
if( nOrder==pWInfo->pOrderBy->nExpr ){
pWInfo->sorted = 1;
pWInfo->revMask = revMask;
}
}
}
pWInfo->nRowOut = pFrom->nRow;
#ifdef WHERETRACE_ENABLED
pWInfo->rTotalCost = pFrom->rCost;
#endif
/* Free temporary memory and return success */
sqlite3StackFreeNN(pParse->db, pSpace);
return SQLITE_OK;
}
/*
|
| ︙ | ︙ | |||
169586 169587 169588 169589 169590 169591 169592 |
"-> use Bloom-filter on loop %c because there are ~%.1e "
"lookups into %s which has only ~%.1e rows\n",
pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName,
(double)sqlite3LogEstToInt(pTab->nRowLogEst)));
}
}
nSearch += pLoop->nOut;
| < | 169757 169758 169759 169760 169761 169762 169763 169764 169765 169766 169767 169768 169769 169770 |
"-> use Bloom-filter on loop %c because there are ~%.1e "
"lookups into %s which has only ~%.1e rows\n",
pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName,
(double)sqlite3LogEstToInt(pTab->nRowLogEst)));
}
}
nSearch += pLoop->nOut;
}
}
/*
** The index pIdx is used by a query and contains one or more expressions.
** In other words pIdx is an index on an expression. iIdxCur is the cursor
** number for the index and iDataCur is the cursor number for the corresponding
|
| ︙ | ︙ | |||
170069 170070 170071 170072 170073 170074 170075 |
}
if( pParse->nErr ){
goto whereBeginError;
}
assert( db->mallocFailed==0 );
#ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace ){
| | > | 170239 170240 170241 170242 170243 170244 170245 170246 170247 170248 170249 170250 170251 170252 170253 170254 |
}
if( pParse->nErr ){
goto whereBeginError;
}
assert( db->mallocFailed==0 );
#ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace ){
sqlite3DebugPrintf("---- Solution cost=%d, nRow=%d",
pWInfo->rTotalCost, pWInfo->nRowOut);
if( pWInfo->nOBSat>0 ){
sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
}
switch( pWInfo->eDistinct ){
case WHERE_DISTINCT_UNIQUE: {
sqlite3DebugPrintf(" DISTINCT=unique");
break;
|
| ︙ | ︙ | |||
226572 226573 226574 226575 226576 226577 226578 |
** then this variable is the compiled version of:
**
** SELECT 1, NULL, 'abc'
*/
struct SessionTable {
SessionTable *pNext;
char *zName; /* Local name of table */
| | > > | 226743 226744 226745 226746 226747 226748 226749 226750 226751 226752 226753 226754 226755 226756 226757 226758 226759 226760 226761 226762 226763 |
** then this variable is the compiled version of:
**
** SELECT 1, NULL, 'abc'
*/
struct SessionTable {
SessionTable *pNext;
char *zName; /* Local name of table */
int nCol; /* Number of non-hidden columns */
int nTotalCol; /* Number of columns including hidden */
int bStat1; /* True if this is sqlite_stat1 */
int bRowid; /* True if this table uses rowid for PK */
const char **azCol; /* Column names */
const char **azDflt; /* Default value expressions */
int *aiIdx; /* Index to pass to xNew/xOld */
u8 *abPK; /* Array of primary key flags */
int nEntry; /* Total number of entries in hash table */
int nChange; /* Size of apChange[] array */
SessionChange **apChange; /* Hash table buckets */
sqlite3_stmt *pDfltStmt;
};
|
| ︙ | ︙ | |||
226979 226980 226981 226982 226983 226984 226985 226986 |
int bNew, /* True to hash the new.* PK */
int *piHash, /* OUT: Hash value */
int *pbNullPK /* OUT: True if there are NULL values in PK */
){
unsigned int h = 0; /* Hash value to return */
int i; /* Used to iterate through columns */
if( pTab->bRowid ){
| > < < > | | | 227152 227153 227154 227155 227156 227157 227158 227159 227160 227161 227162 227163 227164 227165 227166 227167 227168 227169 227170 227171 227172 227173 227174 227175 227176 227177 227178 227179 227180 227181 |
int bNew, /* True to hash the new.* PK */
int *piHash, /* OUT: Hash value */
int *pbNullPK /* OUT: True if there are NULL values in PK */
){
unsigned int h = 0; /* Hash value to return */
int i; /* Used to iterate through columns */
assert( pTab->nTotalCol==pSession->hook.xCount(pSession->hook.pCtx) );
if( pTab->bRowid ){
h = sessionHashAppendI64(h, iRowid);
}else{
assert( *pbNullPK==0 );
for(i=0; i<pTab->nCol; i++){
if( pTab->abPK[i] ){
int rc;
int eType;
sqlite3_value *pVal;
int iIdx = pTab->aiIdx[i];
if( bNew ){
rc = pSession->hook.xNew(pSession->hook.pCtx, iIdx, &pVal);
}else{
rc = pSession->hook.xOld(pSession->hook.pCtx, iIdx, &pVal);
}
if( rc!=SQLITE_OK ) return rc;
eType = sqlite3_value_type(pVal);
h = sessionHashAppendType(h, eType);
if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
i64 iVal;
|
| ︙ | ︙ | |||
227331 227332 227333 227334 227335 227336 227337 227338 227339 227340 227341 227342 227343 227344 227345 |
for(iCol=0; iCol<pTab->nCol; iCol++){
if( !pTab->abPK[iCol] ){
a += sessionSerialLen(a);
}else{
sqlite3_value *pVal; /* Value returned by preupdate_new/old */
int rc; /* Error code from preupdate_new/old */
int eType = *a++; /* Type of value from change record */
/* The following calls to preupdate_new() and preupdate_old() can not
** fail. This is because they cache their return values, and by the
** time control flows to here they have already been called once from
** within sessionPreupdateHash(). The first two asserts below verify
** this (that the method has already been called). */
if( op==SQLITE_INSERT ){
/* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */
| > | | | 227504 227505 227506 227507 227508 227509 227510 227511 227512 227513 227514 227515 227516 227517 227518 227519 227520 227521 227522 227523 227524 227525 227526 227527 227528 227529 227530 |
for(iCol=0; iCol<pTab->nCol; iCol++){
if( !pTab->abPK[iCol] ){
a += sessionSerialLen(a);
}else{
sqlite3_value *pVal; /* Value returned by preupdate_new/old */
int rc; /* Error code from preupdate_new/old */
int eType = *a++; /* Type of value from change record */
int iIdx = pTab->aiIdx[iCol];
/* The following calls to preupdate_new() and preupdate_old() can not
** fail. This is because they cache their return values, and by the
** time control flows to here they have already been called once from
** within sessionPreupdateHash(). The first two asserts below verify
** this (that the method has already been called). */
if( op==SQLITE_INSERT ){
/* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */
rc = pSession->hook.xNew(pSession->hook.pCtx, iIdx, &pVal);
}else{
/* assert( db->pPreUpdate->pUnpacked ); */
rc = pSession->hook.xOld(pSession->hook.pCtx, iIdx, &pVal);
}
assert( rc==SQLITE_OK );
(void)rc; /* Suppress warning about unused variable */
if( sqlite3_value_type(pVal)!=eType ) return 0;
/* A SessionChange object never has a NULL value in a PK column */
assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
|
| ︙ | ︙ | |||
227467 227468 227469 227470 227471 227472 227473 227474 227475 227476 227477 227478 227479 227480 227481 227482 227483 227484 227485 227486 227487 227488 227489 227490 227491 227492 227493 227494 227495 227496 227497 227498 227499 227500 227501 227502 227503 227504 227505 227506 |
*/
static int sessionTableInfo(
sqlite3_session *pSession, /* For memory accounting. May be NULL */
sqlite3 *db, /* Database connection */
const char *zDb, /* Name of attached database (e.g. "main") */
const char *zThis, /* Table name */
int *pnCol, /* OUT: number of columns */
const char **pzTab, /* OUT: Copy of zThis */
const char ***pazCol, /* OUT: Array of column names for table */
const char ***pazDflt, /* OUT: Array of default value expressions */
u8 **pabPK, /* OUT: Array of booleans - true for PK col */
int *pbRowid /* OUT: True if only PK is a rowid */
){
char *zPragma;
sqlite3_stmt *pStmt;
int rc;
sqlite3_int64 nByte;
int nDbCol = 0;
int nThis;
int i;
u8 *pAlloc = 0;
char **azCol = 0;
char **azDflt = 0;
u8 *abPK = 0;
int bRowid = 0; /* Set to true to use rowid as PK */
assert( pazCol && pabPK );
*pazCol = 0;
*pabPK = 0;
*pnCol = 0;
if( pzTab ) *pzTab = 0;
if( pazDflt ) *pazDflt = 0;
nThis = sqlite3Strlen30(zThis);
if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
if( rc==SQLITE_OK ){
/* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
zPragma = sqlite3_mprintf(
| > > > > > | | | | > | > | | | > > | | | | | | | | | | | | | | | | > | > > > | 227641 227642 227643 227644 227645 227646 227647 227648 227649 227650 227651 227652 227653 227654 227655 227656 227657 227658 227659 227660 227661 227662 227663 227664 227665 227666 227667 227668 227669 227670 227671 227672 227673 227674 227675 227676 227677 227678 227679 227680 227681 227682 227683 227684 227685 227686 227687 227688 227689 227690 227691 227692 227693 227694 227695 227696 227697 227698 227699 227700 227701 227702 227703 227704 227705 227706 227707 227708 227709 227710 227711 227712 227713 227714 227715 227716 227717 227718 227719 227720 227721 227722 227723 227724 227725 227726 227727 227728 227729 227730 227731 227732 227733 227734 227735 227736 227737 227738 227739 227740 227741 227742 227743 227744 227745 227746 227747 227748 227749 227750 227751 227752 227753 227754 227755 227756 227757 227758 227759 227760 227761 227762 227763 227764 227765 227766 227767 227768 227769 227770 227771 227772 227773 227774 227775 227776 227777 227778 227779 227780 227781 227782 227783 227784 227785 227786 227787 227788 227789 227790 227791 227792 227793 227794 227795 227796 |
*/
static int sessionTableInfo(
sqlite3_session *pSession, /* For memory accounting. May be NULL */
sqlite3 *db, /* Database connection */
const char *zDb, /* Name of attached database (e.g. "main") */
const char *zThis, /* Table name */
int *pnCol, /* OUT: number of columns */
int *pnTotalCol, /* OUT: number of hidden columns */
const char **pzTab, /* OUT: Copy of zThis */
const char ***pazCol, /* OUT: Array of column names for table */
const char ***pazDflt, /* OUT: Array of default value expressions */
int **paiIdx, /* OUT: Array of xNew/xOld indexes */
u8 **pabPK, /* OUT: Array of booleans - true for PK col */
int *pbRowid /* OUT: True if only PK is a rowid */
){
char *zPragma;
sqlite3_stmt *pStmt;
int rc;
sqlite3_int64 nByte;
int nDbCol = 0;
int nThis;
int i;
u8 *pAlloc = 0;
char **azCol = 0;
char **azDflt = 0;
u8 *abPK = 0;
int *aiIdx = 0;
int bRowid = 0; /* Set to true to use rowid as PK */
assert( pazCol && pabPK );
*pazCol = 0;
*pabPK = 0;
*pnCol = 0;
if( pnTotalCol ) *pnTotalCol = 0;
if( paiIdx ) *paiIdx = 0;
if( pzTab ) *pzTab = 0;
if( pazDflt ) *pazDflt = 0;
nThis = sqlite3Strlen30(zThis);
if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
if( rc==SQLITE_OK ){
/* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
zPragma = sqlite3_mprintf(
"SELECT 0, 'tbl', '', 0, '', 1, 0 UNION ALL "
"SELECT 1, 'idx', '', 0, '', 2, 0 UNION ALL "
"SELECT 2, 'stat', '', 0, '', 0, 0"
);
}else if( rc==SQLITE_ERROR ){
zPragma = sqlite3_mprintf("");
}else{
return rc;
}
}else{
zPragma = sqlite3_mprintf("PRAGMA '%q'.table_xinfo('%q')", zDb, zThis);
}
if( !zPragma ){
return SQLITE_NOMEM;
}
rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
sqlite3_free(zPragma);
if( rc!=SQLITE_OK ){
return rc;
}
nByte = nThis + 1;
bRowid = (pbRowid!=0);
while( SQLITE_ROW==sqlite3_step(pStmt) ){
nByte += sqlite3_column_bytes(pStmt, 1); /* name */
nByte += sqlite3_column_bytes(pStmt, 4); /* dflt_value */
if( sqlite3_column_int(pStmt, 6)==0 ){ /* !hidden */
nDbCol++;
}
if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; /* pk */
}
if( nDbCol==0 ) bRowid = 0;
nDbCol += bRowid;
nByte += strlen(SESSIONS_ROWID);
rc = sqlite3_reset(pStmt);
if( rc==SQLITE_OK ){
nByte += nDbCol * (sizeof(const char *)*2 +sizeof(int)+sizeof(u8) + 1 + 1);
pAlloc = sessionMalloc64(pSession, nByte);
if( pAlloc==0 ){
rc = SQLITE_NOMEM;
}else{
memset(pAlloc, 0, nByte);
}
}
if( rc==SQLITE_OK ){
azCol = (char **)pAlloc;
azDflt = (char**)&azCol[nDbCol];
aiIdx = (int*)&azDflt[nDbCol];
abPK = (u8 *)&aiIdx[nDbCol];
pAlloc = &abPK[nDbCol];
if( pzTab ){
memcpy(pAlloc, zThis, nThis+1);
*pzTab = (char *)pAlloc;
pAlloc += nThis+1;
}
i = 0;
if( bRowid ){
size_t nName = strlen(SESSIONS_ROWID);
memcpy(pAlloc, SESSIONS_ROWID, nName+1);
azCol[i] = (char*)pAlloc;
pAlloc += nName+1;
abPK[i] = 1;
aiIdx[i] = -1;
i++;
}
while( SQLITE_ROW==sqlite3_step(pStmt) ){
if( sqlite3_column_int(pStmt, 6)==0 ){ /* !hidden */
int nName = sqlite3_column_bytes(pStmt, 1);
int nDflt = sqlite3_column_bytes(pStmt, 4);
const unsigned char *zName = sqlite3_column_text(pStmt, 1);
const unsigned char *zDflt = sqlite3_column_text(pStmt, 4);
if( zName==0 ) break;
memcpy(pAlloc, zName, nName+1);
azCol[i] = (char *)pAlloc;
pAlloc += nName+1;
if( zDflt ){
memcpy(pAlloc, zDflt, nDflt+1);
azDflt[i] = (char *)pAlloc;
pAlloc += nDflt+1;
}else{
azDflt[i] = 0;
}
abPK[i] = sqlite3_column_int(pStmt, 5);
aiIdx[i] = sqlite3_column_int(pStmt, 0);
i++;
}
if( pnTotalCol ) (*pnTotalCol)++;
}
rc = sqlite3_reset(pStmt);
}
/* If successful, populate the output variables. Otherwise, zero them and
** free any allocation made. An error code will be returned in this case.
*/
if( rc==SQLITE_OK ){
*pazCol = (const char**)azCol;
if( pazDflt ) *pazDflt = (const char**)azDflt;
*pabPK = abPK;
*pnCol = nDbCol;
if( paiIdx ) *paiIdx = aiIdx;
}else{
sessionFree(pSession, azCol);
}
if( pbRowid ) *pbRowid = bRowid;
sqlite3_finalize(pStmt);
return rc;
}
|
| ︙ | ︙ | |||
227627 227628 227629 227630 227631 227632 227633 |
){
int rc = SQLITE_OK;
if( pTab->nCol==0 ){
u8 *abPK;
assert( pTab->azCol==0 || pTab->abPK==0 );
rc = sessionTableInfo(pSession, db, zDb,
| | > | 227814 227815 227816 227817 227818 227819 227820 227821 227822 227823 227824 227825 227826 227827 227828 227829 |
){
int rc = SQLITE_OK;
if( pTab->nCol==0 ){
u8 *abPK;
assert( pTab->azCol==0 || pTab->abPK==0 );
rc = sessionTableInfo(pSession, db, zDb,
pTab->zName, &pTab->nCol, &pTab->nTotalCol, 0, &pTab->azCol,
&pTab->azDflt, &pTab->aiIdx, &abPK,
((pSession==0 || pSession->bImplicitPK) ? &pTab->bRowid : 0)
);
if( rc==SQLITE_OK ){
int i;
for(i=0; i<pTab->nCol; i++){
if( abPK[i] ){
pTab->abPK = abPK;
|
| ︙ | ︙ | |||
227662 227663 227664 227665 227666 227667 227668 227669 227670 227671 227672 227673 227674 227675 227676 |
}
/*
** Re-initialize table object pTab.
*/
static int sessionReinitTable(sqlite3_session *pSession, SessionTable *pTab){
int nCol = 0;
const char **azCol = 0;
const char **azDflt = 0;
u8 *abPK = 0;
int bRowid = 0;
assert( pSession->rc==SQLITE_OK );
pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb,
| > > | | 227850 227851 227852 227853 227854 227855 227856 227857 227858 227859 227860 227861 227862 227863 227864 227865 227866 227867 227868 227869 227870 227871 227872 227873 227874 |
}
/*
** Re-initialize table object pTab.
*/
static int sessionReinitTable(sqlite3_session *pSession, SessionTable *pTab){
int nCol = 0;
int nTotalCol = 0;
const char **azCol = 0;
const char **azDflt = 0;
int *aiIdx = 0;
u8 *abPK = 0;
int bRowid = 0;
assert( pSession->rc==SQLITE_OK );
pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb,
pTab->zName, &nCol, &nTotalCol, 0, &azCol, &azDflt, &aiIdx, &abPK,
(pSession->bImplicitPK ? &bRowid : 0)
);
if( pSession->rc==SQLITE_OK ){
if( pTab->nCol>nCol || pTab->bRowid!=bRowid ){
pSession->rc = SQLITE_SCHEMA;
}else{
int ii;
|
| ︙ | ︙ | |||
227693 227694 227695 227696 227697 227698 227699 227700 227701 227702 227703 227704 227705 227706 227707 227708 |
}
}
if( pSession->rc==SQLITE_OK ){
const char **a = pTab->azCol;
pTab->azCol = azCol;
pTab->nCol = nCol;
pTab->azDflt = azDflt;
pTab->abPK = abPK;
azCol = a;
}
if( pSession->bEnableSize ){
pSession->nMaxChangesetSize += (nCol - nOldCol);
pSession->nMaxChangesetSize += sessionVarintLen(nCol);
pSession->nMaxChangesetSize -= sessionVarintLen(nOldCol);
}
| > > | 227883 227884 227885 227886 227887 227888 227889 227890 227891 227892 227893 227894 227895 227896 227897 227898 227899 227900 |
}
}
if( pSession->rc==SQLITE_OK ){
const char **a = pTab->azCol;
pTab->azCol = azCol;
pTab->nCol = nCol;
pTab->nTotalCol = nTotalCol;
pTab->azDflt = azDflt;
pTab->abPK = abPK;
pTab->aiIdx = aiIdx;
azCol = a;
}
if( pSession->bEnableSize ){
pSession->nMaxChangesetSize += (nCol - nOldCol);
pSession->nMaxChangesetSize += sessionVarintLen(nCol);
pSession->nMaxChangesetSize -= sessionVarintLen(nOldCol);
}
|
| ︙ | ︙ | |||
228012 228013 228014 228015 228016 228017 228018 |
i64 nNew = 2;
if( pC->op==SQLITE_INSERT ){
if( pTab->bRowid ) nNew += 9;
if( op!=SQLITE_DELETE ){
int ii;
for(ii=0; ii<pTab->nCol; ii++){
sqlite3_value *p = 0;
| | > | | 228204 228205 228206 228207 228208 228209 228210 228211 228212 228213 228214 228215 228216 228217 228218 228219 228220 228221 228222 228223 228224 228225 228226 228227 228228 228229 228230 228231 228232 228233 228234 228235 228236 228237 228238 228239 228240 |
i64 nNew = 2;
if( pC->op==SQLITE_INSERT ){
if( pTab->bRowid ) nNew += 9;
if( op!=SQLITE_DELETE ){
int ii;
for(ii=0; ii<pTab->nCol; ii++){
sqlite3_value *p = 0;
pSession->hook.xNew(pSession->hook.pCtx, pTab->aiIdx[ii], &p);
sessionSerializeValue(0, p, &nNew);
}
}
}else if( op==SQLITE_DELETE ){
nNew += pC->nRecord;
if( sqlite3_preupdate_blobwrite(pSession->db)>=0 ){
nNew += pC->nRecord;
}
}else{
int ii;
u8 *pCsr = pC->aRecord;
if( pTab->bRowid ){
nNew += 9 + 1;
pCsr += 9;
}
for(ii=pTab->bRowid; ii<pTab->nCol; ii++){
int bChanged = 1;
int nOld = 0;
int eType;
int iIdx = pTab->aiIdx[ii];
sqlite3_value *p = 0;
pSession->hook.xNew(pSession->hook.pCtx, iIdx, &p);
if( p==0 ){
return SQLITE_NOMEM;
}
eType = *pCsr++;
switch( eType ){
case SQLITE_NULL:
|
| ︙ | ︙ | |||
228130 228131 228132 228133 228134 228135 228136 | /* Load table details if required */ if( sessionInitTable(pSession, pTab, pSession->db, pSession->zDb) ) return; /* Check the number of columns in this xPreUpdate call matches the ** number of columns in the table. */ nExpect = pSession->hook.xCount(pSession->hook.pCtx); | | | | 228323 228324 228325 228326 228327 228328 228329 228330 228331 228332 228333 228334 228335 228336 228337 228338 228339 228340 228341 |
/* Load table details if required */
if( sessionInitTable(pSession, pTab, pSession->db, pSession->zDb) ) return;
/* Check the number of columns in this xPreUpdate call matches the
** number of columns in the table. */
nExpect = pSession->hook.xCount(pSession->hook.pCtx);
if( pTab->nTotalCol<nExpect ){
if( sessionReinitTable(pSession, pTab) ) return;
if( sessionUpdateChanges(pSession, pTab) ) return;
}
if( pTab->nTotalCol!=nExpect ){
pSession->rc = SQLITE_SCHEMA;
return;
}
/* Grow the hash table if required */
if( sessionGrowHash(pSession, 0, pTab) ){
pSession->rc = SQLITE_NOMEM;
|
| ︙ | ︙ | |||
228191 228192 228193 228194 228195 228196 228197 |
int i; /* Used to iterate through columns */
assert( rc==SQLITE_OK );
pTab->nEntry++;
/* Figure out how large an allocation is required */
nByte = sizeof(SessionChange);
| | > | | | 228384 228385 228386 228387 228388 228389 228390 228391 228392 228393 228394 228395 228396 228397 228398 228399 228400 228401 228402 228403 228404 228405 228406 |
int i; /* Used to iterate through columns */
assert( rc==SQLITE_OK );
pTab->nEntry++;
/* Figure out how large an allocation is required */
nByte = sizeof(SessionChange);
for(i=pTab->bRowid; i<pTab->nCol; i++){
int iIdx = pTab->aiIdx[i];
sqlite3_value *p = 0;
if( op!=SQLITE_INSERT ){
/* This may fail if the column has a non-NULL default and was added
** using ALTER TABLE ADD COLUMN after this record was created. */
rc = pSession->hook.xOld(pSession->hook.pCtx, iIdx, &p);
}else if( pTab->abPK[i] ){
TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx,iIdx,&p);
assert( trc==SQLITE_OK );
}
if( rc==SQLITE_OK ){
/* This may fail if SQLite value p contains a utf-16 string that must
** be converted to utf-8 and an OOM error occurs while doing so. */
rc = sessionSerializeValue(0, p, &nByte);
|
| ︙ | ︙ | |||
228233 228234 228235 228236 228237 228238 228239 |
** It is not possible for an OOM to occur in this block. */
nByte = 0;
if( pTab->bRowid ){
pC->aRecord[0] = SQLITE_INTEGER;
sessionPutI64(&pC->aRecord[1], iRowid);
nByte = 9;
}
| | > | | | 228427 228428 228429 228430 228431 228432 228433 228434 228435 228436 228437 228438 228439 228440 228441 228442 228443 228444 228445 228446 228447 |
** It is not possible for an OOM to occur in this block. */
nByte = 0;
if( pTab->bRowid ){
pC->aRecord[0] = SQLITE_INTEGER;
sessionPutI64(&pC->aRecord[1], iRowid);
nByte = 9;
}
for(i=pTab->bRowid; i<pTab->nCol; i++){
sqlite3_value *p = 0;
int iIdx = pTab->aiIdx[i];
if( op!=SQLITE_INSERT ){
pSession->hook.xOld(pSession->hook.pCtx, iIdx, &p);
}else if( pTab->abPK[i] ){
pSession->hook.xNew(pSession->hook.pCtx, iIdx, &p);
}
sessionSerializeValue(&pC->aRecord[nByte], p, &nByte);
}
/* Add the change to the hash-table */
if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){
pC->bIndirect = 1;
|
| ︙ | ︙ | |||
228640 228641 228642 228643 228644 228645 228646 |
if( rc==SQLITE_OK ){
int bHasPk = 0;
int bMismatch = 0;
int nCol; /* Columns in zFrom.zTbl */
int bRowid = 0;
u8 *abPK;
const char **azCol = 0;
| | > | 228835 228836 228837 228838 228839 228840 228841 228842 228843 228844 228845 228846 228847 228848 228849 228850 |
if( rc==SQLITE_OK ){
int bHasPk = 0;
int bMismatch = 0;
int nCol; /* Columns in zFrom.zTbl */
int bRowid = 0;
u8 *abPK;
const char **azCol = 0;
rc = sessionTableInfo(0, db, zFrom, zTbl,
&nCol, 0, 0, &azCol, 0, 0, &abPK,
pSession->bImplicitPK ? &bRowid : 0
);
if( rc==SQLITE_OK ){
if( pTo->nCol!=nCol ){
bMismatch = 1;
}else{
int i;
|
| ︙ | ︙ | |||
229217 229218 229219 229220 229221 229222 229223 |
const char **azCol, /* Names of table columns */
u8 *abPK, /* PRIMARY KEY array */
sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
){
int rc = SQLITE_OK;
char *zSql = 0;
const char *zSep = "";
| < > | > > > > > > > | | 229413 229414 229415 229416 229417 229418 229419 229420 229421 229422 229423 229424 229425 229426 229427 229428 229429 229430 229431 229432 229433 229434 229435 229436 229437 229438 229439 229440 229441 229442 229443 229444 229445 229446 229447 229448 229449 229450 229451 229452 229453 229454 229455 229456 229457 229458 229459 229460 229461 229462 229463 229464 229465 229466 229467 229468 229469 229470 |
const char **azCol, /* Names of table columns */
u8 *abPK, /* PRIMARY KEY array */
sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
){
int rc = SQLITE_OK;
char *zSql = 0;
const char *zSep = "";
int nSql = -1;
int i;
SessionBuffer cols = {0, 0, 0};
SessionBuffer nooptest = {0, 0, 0};
SessionBuffer pkfield = {0, 0, 0};
SessionBuffer pkvar = {0, 0, 0};
sessionAppendStr(&nooptest, ", 1", &rc);
if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
sessionAppendStr(&nooptest, " AND (?6 OR ?3 IS stat)", &rc);
sessionAppendStr(&pkfield, "tbl, idx", &rc);
sessionAppendStr(&pkvar,
"?1, (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", &rc
);
sessionAppendStr(&cols, "tbl, ?2, stat", &rc);
}else{
#if 0
if( bRowid ){
sessionAppendStr(&cols, SESSIONS_ROWID, &rc);
}
#endif
for(i=0; i<nCol; i++){
if( cols.nBuf ) sessionAppendStr(&cols, ", ", &rc);
sessionAppendIdent(&cols, azCol[i], &rc);
if( abPK[i] ){
sessionAppendStr(&pkfield, zSep, &rc);
sessionAppendStr(&pkvar, zSep, &rc);
zSep = ", ";
sessionAppendIdent(&pkfield, azCol[i], &rc);
sessionAppendPrintf(&pkvar, &rc, "?%d", i+1);
}else{
sessionAppendPrintf(&nooptest, &rc,
" AND (?%d OR ?%d IS %w.%w)", i+1+nCol, i+1, zTab, azCol[i]
);
}
}
}
if( rc==SQLITE_OK ){
zSql = sqlite3_mprintf(
"SELECT %s%s FROM %Q.%Q WHERE (%s) IS (%s)",
(char*)cols.aBuf, (bIgnoreNoop ? (char*)nooptest.aBuf : ""),
zDb, zTab, (char*)pkfield.aBuf, (char*)pkvar.aBuf
);
if( zSql==0 ) rc = SQLITE_NOMEM;
}
#if 0
if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
|
| ︙ | ︙ | |||
229296 229297 229298 229299 229300 229301 229302 229303 229304 229305 229306 229307 229308 229309 |
if( rc==SQLITE_OK ){
rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
}
sqlite3_free(zSql);
sqlite3_free(nooptest.aBuf);
sqlite3_free(pkfield.aBuf);
sqlite3_free(pkvar.aBuf);
return rc;
}
/*
** Bind the PRIMARY KEY values from the change passed in argument pChange
** to the SELECT statement passed as the first argument. The SELECT statement
** is as prepared by function sessionSelectStmt().
| > | 229499 229500 229501 229502 229503 229504 229505 229506 229507 229508 229509 229510 229511 229512 229513 |
if( rc==SQLITE_OK ){
rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
}
sqlite3_free(zSql);
sqlite3_free(nooptest.aBuf);
sqlite3_free(pkfield.aBuf);
sqlite3_free(pkvar.aBuf);
sqlite3_free(cols.aBuf);
return rc;
}
/*
** Bind the PRIMARY KEY values from the change passed in argument pChange
** to the SELECT statement passed as the first argument. The SELECT statement
** is as prepared by function sessionSelectStmt().
|
| ︙ | ︙ | |||
231636 231637 231638 231639 231640 231641 231642 |
sApply.azCol = (const char **)zTab;
}else{
int nMinCol = 0;
int i;
sqlite3changeset_pk(pIter, &abPK, 0);
rc = sessionTableInfo(0, db, "main", zNew,
| > | | 231840 231841 231842 231843 231844 231845 231846 231847 231848 231849 231850 231851 231852 231853 231854 231855 |
sApply.azCol = (const char **)zTab;
}else{
int nMinCol = 0;
int i;
sqlite3changeset_pk(pIter, &abPK, 0);
rc = sessionTableInfo(0, db, "main", zNew,
&sApply.nCol, 0, &zTab, &sApply.azCol, 0, 0,
&sApply.abPK, &sApply.bRowid
);
if( rc!=SQLITE_OK ) break;
for(i=0; i<sApply.nCol; i++){
if( sApply.abPK[i] ) nMinCol = i+1;
}
if( sApply.nCol==0 ){
|
| ︙ | ︙ | |||
231716 231717 231718 231719 231720 231721 231722 231723 231724 231725 231726 231727 231728 231729 |
sIter.nCol = nFk;
res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter);
if( res!=SQLITE_CHANGESET_OMIT ){
rc = SQLITE_CONSTRAINT;
}
}
}
if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
if( rc==SQLITE_OK ){
rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
}
if( rc!=SQLITE_OK ){
sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
| > > > > > | 231921 231922 231923 231924 231925 231926 231927 231928 231929 231930 231931 231932 231933 231934 231935 231936 231937 231938 231939 |
sIter.nCol = nFk;
res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter);
if( res!=SQLITE_CHANGESET_OMIT ){
rc = SQLITE_CONSTRAINT;
}
}
}
{
int rc2 = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0);
if( rc==SQLITE_OK ) rc = rc2;
}
if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
if( rc==SQLITE_OK ){
rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
}
if( rc!=SQLITE_OK ){
sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
|
| ︙ | ︙ | |||
243228 243229 243230 243231 243232 243233 243234 | fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret); return ret; } /* ** Close the read-only blob handle, if it is open. */ | | > | > | 243438 243439 243440 243441 243442 243443 243444 243445 243446 243447 243448 243449 243450 243451 243452 243453 243454 243455 243456 243457 243458 |
fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret);
return ret;
}
/*
** Close the read-only blob handle, if it is open.
*/
static void fts5IndexCloseReader(Fts5Index *p){
if( p->pReader ){
int rc;
sqlite3_blob *pReader = p->pReader;
p->pReader = 0;
rc = sqlite3_blob_close(pReader);
if( p->rc==SQLITE_OK ) p->rc = rc;
}
}
/*
** Retrieve a record from the %_data table.
**
** If an error occurs, NULL is returned and an error left in the
|
| ︙ | ︙ | |||
243257 243258 243259 243260 243261 243262 243263 |
** is required. */
sqlite3_blob *pBlob = p->pReader;
p->pReader = 0;
rc = sqlite3_blob_reopen(pBlob, iRowid);
assert( p->pReader==0 );
p->pReader = pBlob;
if( rc!=SQLITE_OK ){
| | | 243469 243470 243471 243472 243473 243474 243475 243476 243477 243478 243479 243480 243481 243482 243483 |
** is required. */
sqlite3_blob *pBlob = p->pReader;
p->pReader = 0;
rc = sqlite3_blob_reopen(pBlob, iRowid);
assert( p->pReader==0 );
p->pReader = pBlob;
if( rc!=SQLITE_OK ){
fts5IndexCloseReader(p);
}
if( rc==SQLITE_ABORT ) rc = SQLITE_OK;
}
/* If the blob handle is not open at this point, open it and seek
** to the requested entry. */
if( p->pReader==0 && rc==SQLITE_OK ){
|
| ︙ | ︙ | |||
247458 247459 247460 247461 247462 247463 247464 247465 247466 247467 247468 247469 247470 247471 |
}
static int fts5IndexReturn(Fts5Index *p){
int rc = p->rc;
p->rc = SQLITE_OK;
return rc;
}
typedef struct Fts5FlushCtx Fts5FlushCtx;
struct Fts5FlushCtx {
Fts5Index *pIdx;
Fts5SegWriter writer;
};
| > > > > > > > > | 247670 247671 247672 247673 247674 247675 247676 247677 247678 247679 247680 247681 247682 247683 247684 247685 247686 247687 247688 247689 247690 247691 |
}
static int fts5IndexReturn(Fts5Index *p){
int rc = p->rc;
p->rc = SQLITE_OK;
return rc;
}
/*
** Close the read-only blob handle, if it is open.
*/
static void sqlite3Fts5IndexCloseReader(Fts5Index *p){
fts5IndexCloseReader(p);
fts5IndexReturn(p);
}
typedef struct Fts5FlushCtx Fts5FlushCtx;
struct Fts5FlushCtx {
Fts5Index *pIdx;
Fts5SegWriter writer;
};
|
| ︙ | ︙ | |||
249180 249181 249182 249183 249184 249185 249186 |
/*
** Commit data to disk.
*/
static int sqlite3Fts5IndexSync(Fts5Index *p){
assert( p->rc==SQLITE_OK );
fts5IndexFlush(p);
| | | < | | 249400 249401 249402 249403 249404 249405 249406 249407 249408 249409 249410 249411 249412 249413 249414 249415 249416 249417 249418 249419 249420 249421 249422 249423 249424 249425 249426 249427 249428 |
/*
** Commit data to disk.
*/
static int sqlite3Fts5IndexSync(Fts5Index *p){
assert( p->rc==SQLITE_OK );
fts5IndexFlush(p);
fts5IndexCloseReader(p);
return fts5IndexReturn(p);
}
/*
** Discard any data stored in the in-memory hash tables. Do not write it
** to the database. Additionally, assume that the contents of the %_data
** table may have changed on disk. So any in-memory caches of %_data
** records must be invalidated.
*/
static int sqlite3Fts5IndexRollback(Fts5Index *p){
fts5IndexCloseReader(p);
fts5IndexDiscardData(p);
fts5StructureInvalidate(p);
return fts5IndexReturn(p);
}
/*
** The %_data table is completely empty when this function is called. This
** function populates it with the initial structure objects for each index,
** and the initial version of the "averages" record (a zero-byte blob).
*/
|
| ︙ | ︙ | |||
249395 249396 249397 249398 249399 249400 249401 249402 249403 249404 249405 249406 249407 249408 |
/*
** Ensure the segment-iterator passed as the only argument points to EOF.
*/
static void fts5SegIterSetEOF(Fts5SegIter *pSeg){
fts5DataRelease(pSeg->pLeaf);
pSeg->pLeaf = 0;
}
/*
** This function appends iterator pAppend to Fts5TokenDataIter pIn and
** returns the result.
*/
static Fts5TokenDataIter *fts5AppendTokendataIter(
Fts5Index *p, /* Index object (for error code) */
| > > > > > > > > > > | 249614 249615 249616 249617 249618 249619 249620 249621 249622 249623 249624 249625 249626 249627 249628 249629 249630 249631 249632 249633 249634 249635 249636 249637 |
/*
** Ensure the segment-iterator passed as the only argument points to EOF.
*/
static void fts5SegIterSetEOF(Fts5SegIter *pSeg){
fts5DataRelease(pSeg->pLeaf);
pSeg->pLeaf = 0;
}
static void fts5IterClose(Fts5IndexIter *pIndexIter){
if( pIndexIter ){
Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
Fts5Index *pIndex = pIter->pIndex;
fts5TokendataIterDelete(pIter->pTokenDataIter);
fts5MultiIterFree(pIter);
fts5IndexCloseReader(pIndex);
}
}
/*
** This function appends iterator pAppend to Fts5TokenDataIter pIn and
** returns the result.
*/
static Fts5TokenDataIter *fts5AppendTokendataIter(
Fts5Index *p, /* Index object (for error code) */
|
| ︙ | ︙ | |||
249423 249424 249425 249426 249427 249428 249429 |
if( pIn==0 ) memset(pNew, 0, nByte);
pRet = pNew;
pNew->nIterAlloc = nAlloc;
}
}
}
if( p->rc ){
| | | 249652 249653 249654 249655 249656 249657 249658 249659 249660 249661 249662 249663 249664 249665 249666 |
if( pIn==0 ) memset(pNew, 0, nByte);
pRet = pNew;
pNew->nIterAlloc = nAlloc;
}
}
}
if( p->rc ){
fts5IterClose((Fts5IndexIter*)pAppend);
}else{
pRet->apIter[pRet->nIter++] = pAppend;
}
assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc );
return pRet;
}
|
| ︙ | ︙ | |||
249636 249637 249638 249639 249640 249641 249642 |
if( pSmall ){
fts5BufferSet(&p->rc, &bSeek, pSmall->n, pSmall->p);
fts5BufferAppendBlob(&p->rc, &bSeek, 1, (const u8*)"\0");
}else{
fts5BufferSet(&p->rc, &bSeek, nToken, pToken);
}
if( p->rc ){
| | | 249865 249866 249867 249868 249869 249870 249871 249872 249873 249874 249875 249876 249877 249878 249879 |
if( pSmall ){
fts5BufferSet(&p->rc, &bSeek, pSmall->n, pSmall->p);
fts5BufferAppendBlob(&p->rc, &bSeek, 1, (const u8*)"\0");
}else{
fts5BufferSet(&p->rc, &bSeek, nToken, pToken);
}
if( p->rc ){
fts5IterClose((Fts5IndexIter*)pNew);
break;
}
pNewIter = &pNew->aSeg[0];
pPrevIter = (pPrev ? &pPrev->aSeg[0] : 0);
for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){
|
| ︙ | ︙ | |||
249701 249702 249703 249704 249705 249706 249707 |
}
}
/* If pSmall is still NULL at this point, then the new iterator does
** not point to any terms that match the query. So delete it and break
** out of the loop - all required iterators have been collected. */
if( pSmall==0 ){
| | | 249930 249931 249932 249933 249934 249935 249936 249937 249938 249939 249940 249941 249942 249943 249944 |
}
}
/* If pSmall is still NULL at this point, then the new iterator does
** not point to any terms that match the query. So delete it and break
** out of the loop - all required iterators have been collected. */
if( pSmall==0 ){
fts5IterClose((Fts5IndexIter*)pNew);
break;
}
/* Append this iterator to the set and continue. */
pSet = fts5AppendTokendataIter(p, pSet, pNew);
}
|
| ︙ | ︙ | |||
249830 249831 249832 249833 249834 249835 249836 |
Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
}
}
}
if( p->rc ){
| | | | 250059 250060 250061 250062 250063 250064 250065 250066 250067 250068 250069 250070 250071 250072 250073 250074 250075 |
Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
}
}
}
if( p->rc ){
fts5IterClose((Fts5IndexIter*)pRet);
pRet = 0;
fts5IndexCloseReader(p);
}
*ppIter = (Fts5IndexIter*)pRet;
sqlite3Fts5BufferFree(&buf);
}
return fts5IndexReturn(p);
}
|
| ︙ | ︙ | |||
250082 250083 250084 250085 250086 250087 250088 |
}
/*
** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
*/
static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
if( pIndexIter ){
| < | < | | | 250311 250312 250313 250314 250315 250316 250317 250318 250319 250320 250321 250322 250323 250324 250325 250326 250327 |
}
/*
** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
*/
static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
if( pIndexIter ){
Fts5Index *pIndex = ((Fts5Iter*)pIndexIter)->pIndex;
fts5IterClose(pIndexIter);
fts5IndexReturn(pIndex);
}
}
/*
** Read and decode the "averages" record from the database.
**
** Parameter anSize must point to an array of size nCol, where nCol is
|
| ︙ | ︙ | |||
250616 250617 250618 250619 250620 250621 250622 |
cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
}
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IterNext(pIter);
}
}
| | | 250843 250844 250845 250846 250847 250848 250849 250850 250851 250852 250853 250854 250855 250856 250857 |
cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
}
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IterNext(pIter);
}
}
fts5IterClose(pIter);
*pCksum = cksum;
return rc;
}
/*
** Check if buffer z[], size n bytes, contains as series of valid utf-8
|
| ︙ | ︙ | |||
255460 255461 255462 255463 255464 255465 255466 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
| | | 255687 255688 255689 255690 255691 255692 255693 255694 255695 255696 255697 255698 255699 255700 255701 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2025-01-29 18:53:19 d7c07581203a0a88456588e49e51b40a8341b0e7121809f75be0ee882d91650f", -1, SQLITE_TRANSIENT);
}
/*
** Implementation of fts5_locale(LOCALE, TEXT) function.
**
** If parameter LOCALE is NULL, or a zero-length string, then a copy of
** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as
|
| ︙ | ︙ |
Changes to extsrc/sqlite3.h.
| ︙ | ︙ | |||
142 143 144 145 146 147 148 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.49.0" #define SQLITE_VERSION_NUMBER 3049000 #define SQLITE_SOURCE_ID "2025-01-29 18:53:19 d7c07581203a0a88456588e49e51b40a8341b0e7121809f75be0ee882d91650f" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
10744 10745 10746 10747 10748 10749 10750 | ** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Serialize a database ** | | | > | 10744 10745 10746 10747 10748 10749 10750 10751 10752 10753 10754 10755 10756 10757 10758 10759 10760 | ** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Serialize a database ** ** The sqlite3_serialize(D,S,P,F) interface returns a pointer to ** memory that is a serialization of the S database on ** [database connection] D. If S is a NULL pointer, the main database is used. ** If P is not a NULL pointer, then the size of the database in bytes ** is written into *P. ** ** For an ordinary on-disk database file, the serialization is just a ** copy of the disk file. For an in-memory database or a "TEMP" database, ** the serialization is the same sequence of bytes which would be written ** to disk if that database where backed up to disk. |
| ︙ | ︙ |
Changes to src/main.mk.
| ︙ | ︙ | |||
646 647 648 649 650 651 652 653 654 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
| > | | | 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP
# Setup the options used to compile the included SQLite shell.
|
| ︙ | ︙ | |||
671 672 673 674 675 676 677 678 679 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
| > | | | 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-Dmain=sqlite3_shell \
-DSQLITE_SHELL_IS_UTF8=1 \
|
| ︙ | ︙ |
Changes to tools/makemake.tcl.
| ︙ | ︙ | |||
238 239 240 241 242 243 244 245 246 | -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 | > | | | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP } #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1 |
| ︙ | ︙ |
Changes to win/Makefile.dmc.
| ︙ | ︙ | |||
24 25 26 27 28 29 30 | SSL = CFLAGS = -o BCC = $(DMDIR)\bin\dmc $(CFLAGS) TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi | | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | SSL = CFLAGS = -o BCC = $(DMDIR)\bin\dmc $(CFLAGS) TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen PIKCHR_OPTIONS = -DPIKCHR_TOKEN_LIMIT=10000 SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c chat_.c checkin_.c checkout_.c clearsign_.c clone_.c color_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c interwiki_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c match_.c md5_.c merge_.c merge3_.c moderate_.c name_.c patch_.c path_.c piechart_.c pikchrshow_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c zip_.c OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\chat$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\color$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\interwiki$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\match$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\patch$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pikchrshow$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O |
| ︙ | ︙ |
Changes to win/Makefile.mingw.
| ︙ | ︙ | |||
2526 2527 2528 2529 2530 2531 2532 2533 2534 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
| > | | | 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-DSQLITE_WIN32_NO_ANSI \
$(MINGW_OPTIONS) \
|
| ︙ | ︙ | |||
2554 2555 2556 2557 2558 2559 2560 2561 2562 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
| > | | | 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-Dmain=sqlite3_shell \
-DSQLITE_SHELL_IS_UTF8=1 \
|
| ︙ | ︙ |
Changes to win/Makefile.msc.
| ︙ | ︙ | |||
309 310 311 312 313 314 315 316 317 |
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_OMIT_PROGRESS_CALLBACK \
/DSQLITE_OMIT_SHARED_CACHE \
/DSQLITE_OMIT_LOAD_EXTENSION \
/DSQLITE_MAX_EXPR_DEPTH=0 \
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
| > | | | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_OMIT_PROGRESS_CALLBACK \
/DSQLITE_OMIT_SHARED_CACHE \
/DSQLITE_OMIT_LOAD_EXTENSION \
/DSQLITE_MAX_EXPR_DEPTH=0 \
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_DBSTAT_VTAB \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
/DSQLITE_ENABLE_FTS5 \
/DSQLITE_ENABLE_MATH_FUNCTIONS \
/DSQLITE_ENABLE_STMTVTAB \
/DSQLITE_HAVE_ZLIB \
/DSQLITE_ENABLE_DBPAGE_VTAB \
/DSQLITE_TRUSTED_SCHEMA=0 \
/DHAVE_USLEEP \
/DSQLITE_WIN32_NO_ANSI
|
| ︙ | ︙ | |||
334 335 336 337 338 339 340 341 342 |
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_OMIT_PROGRESS_CALLBACK \
/DSQLITE_OMIT_SHARED_CACHE \
/DSQLITE_OMIT_LOAD_EXTENSION \
/DSQLITE_MAX_EXPR_DEPTH=0 \
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
| > | | | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_OMIT_PROGRESS_CALLBACK \
/DSQLITE_OMIT_SHARED_CACHE \
/DSQLITE_OMIT_LOAD_EXTENSION \
/DSQLITE_MAX_EXPR_DEPTH=0 \
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_DBSTAT_VTAB \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
/DSQLITE_ENABLE_FTS5 \
/DSQLITE_ENABLE_MATH_FUNCTIONS \
/DSQLITE_ENABLE_STMTVTAB \
/DSQLITE_HAVE_ZLIB \
/DSQLITE_ENABLE_DBPAGE_VTAB \
/DSQLITE_TRUSTED_SCHEMA=0 \
/DHAVE_USLEEP \
/Dmain=sqlite3_shell \
/DSQLITE_SHELL_IS_UTF8=1 \
|
| ︙ | ︙ |