Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge in latest changes from trunk. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | check-in-edit |
Files: | files | file ages | folders |
SHA1: |
ee463a39be9ed5037ebc74229689443c |
User & Date: | andybradford 2015-07-25 17:02:22.744 |
Context
2015-07-26
| ||
22:58 | Fix typo in comment. ... (check-in: 57f19bf5 user: mistachkin tags: check-in-edit) | |
2015-07-25
| ||
17:02 | Merge in latest changes from trunk. ... (check-in: ee463a39 user: andybradford tags: check-in-edit) | |
17:01 | Add support for comment file via -M so the prompt message is not confusing when it mentions the use of -M. ... (check-in: 37aeb1c4 user: andybradford tags: check-in-edit) | |
14:53 | Adjust the "lndebug()" macro in linenoise so that it works on older compilers that do not support varargs macros. ... (check-in: acab077c user: drh tags: trunk) | |
Changes
Changes to src/db.c.
︙ | ︙ | |||
1972 1973 1974 1975 1976 1977 1978 | ){ /* There's a versioned setting, and a non-versioned setting. Tell ** the user about the conflict */ fossil_warning( "setting %s has both versioned and non-versioned values: using " "versioned value from file .fossil-settings/%s (to silence this " "warning, either create an empty file named " | | > | | 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 | ){ /* There's a versioned setting, and a non-versioned setting. Tell ** the user about the conflict */ fossil_warning( "setting %s has both versioned and non-versioned values: using " "versioned value from file .fossil-settings/%s (to silence this " "warning, either create an empty file named " ".fossil-settings/%s.no-warn in the check-out root, " "or delete the non-versioned setting " "with \"fossil unset %s\")", zName, zName, zName, zName ); } /* Prefer the versioned setting */ return ( zVersionedSetting!=0 ) ? zVersionedSetting : zNonVersionedSetting; } |
︙ | ︙ | |||
2460 2461 2462 2463 2464 2465 2466 | ** %fossil unset PROPERTY ?OPTIONS? ** ** The "settings" command with no arguments lists all properties and their ** values. With just a property name it shows the value of that property. ** With a value argument it changes the property for the current repository. ** ** Settings marked as versionable are overridden by the contents of the | | | 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 | ** %fossil unset PROPERTY ?OPTIONS? ** ** The "settings" command with no arguments lists all properties and their ** values. With just a property name it shows the value of that property. ** With a value argument it changes the property for the current repository. ** ** Settings marked as versionable are overridden by the contents of the ** file named .fossil-settings/PROPERTY in the check-out root, if that ** file exists. ** ** The "unset" command clears a property setting. ** ** ** access-log If enabled, record successful and failed login attempts ** in the "accesslog" table. Default: off |
︙ | ︙ |
Changes to src/linenoise.c.
︙ | ︙ | |||
174 175 176 177 178 179 180 | static void linenoiseAtExit(void); int linenoiseHistoryAdd(const char *line); static void refreshLine(struct linenoiseState *l); /* Debugging macro. */ #if 0 FILE *lndebug_fp = NULL; | | | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | static void linenoiseAtExit(void); int linenoiseHistoryAdd(const char *line); static void refreshLine(struct linenoiseState *l); /* Debugging macro. */ #if 0 FILE *lndebug_fp = NULL; #define lndebug(fmt, arg1) \ do { \ if (lndebug_fp == NULL) { \ lndebug_fp = fopen("/tmp/lndebug.txt","a"); \ fprintf(lndebug_fp, \ "[%d %d %d] p: %d, rows: %d, rpos: %d, max: %d, oldmax: %d\n", \ (int)l->len,(int)l->pos,(int)l->oldpos,plen,rows,rpos, \ (int)l->maxrows,old_rows); \ } \ fprintf(lndebug_fp, ", " fmt, arg1); \ fflush(lndebug_fp); \ } while (0) #else #define lndebug(fmt, arg1) #endif /* ======================= Low level terminal handling ====================== */ /* Set if to use or not the multi line mode. */ void linenoiseSetMultiLine(int ml) { mlmode = ml; |
︙ | ︙ | |||
524 525 526 527 528 529 530 | lndebug("go down %d", old_rows-rpos); snprintf(seq,64,"\x1b[%dB", old_rows-rpos); abAppend(&ab,seq,strlen(seq)); } /* Now for every row clear it, go up. */ for (j = 0; j < old_rows-1; j++) { | | | | | 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 | lndebug("go down %d", old_rows-rpos); snprintf(seq,64,"\x1b[%dB", old_rows-rpos); abAppend(&ab,seq,strlen(seq)); } /* Now for every row clear it, go up. */ for (j = 0; j < old_rows-1; j++) { lndebug("clear+up", 0); snprintf(seq,64,"\r\x1b[0K\x1b[1A"); abAppend(&ab,seq,strlen(seq)); } /* Clean the top line. */ lndebug("clear", 0); snprintf(seq,64,"\r\x1b[0K"); abAppend(&ab,seq,strlen(seq)); /* Write the prompt and the current buffer content */ abAppend(&ab,l->prompt,strlen(l->prompt)); abAppend(&ab,l->buf,l->len); /* If we are at the very end of the screen with our prompt, we need to * emit a newline and move the prompt to the first column. */ if (l->pos && l->pos == l->len && (l->pos+plen) % l->cols == 0) { lndebug("<newline>", 0); abAppend(&ab,"\n",1); snprintf(seq,64,"\r"); abAppend(&ab,seq,strlen(seq)); rows++; if (rows > (int)l->maxrows) l->maxrows = rows; } |
︙ | ︙ | |||
572 573 574 575 576 577 578 | lndebug("set col %d", 1+col); if (col) snprintf(seq,64,"\r\x1b[%dC", col); else snprintf(seq,64,"\r"); abAppend(&ab,seq,strlen(seq)); | | | 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 | lndebug("set col %d", 1+col); if (col) snprintf(seq,64,"\r\x1b[%dC", col); else snprintf(seq,64,"\r"); abAppend(&ab,seq,strlen(seq)); lndebug("\n", 0); l->oldpos = l->pos; if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */ abFree(&ab); } /* Calls the two low level functions refreshSingleLine() or |
︙ | ︙ |
Changes to src/setup.c.
︙ | ︙ | |||
1470 1471 1472 1473 1474 1475 1476 | (char*)pSet->def, hasVersionableValue); @<br /> } } @ </td></tr></table> @ </div></form> @ <p>Settings marked with (v) are 'versionable' and will be overridden | | > | 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 | (char*)pSet->def, hasVersionableValue); @<br /> } } @ </td></tr></table> @ </div></form> @ <p>Settings marked with (v) are 'versionable' and will be overridden @ by the contents of files named <tt>.fossil-settings/PROPERTY</tt> @ in the check-out root. @ If such a file is present, the corresponding field above is not @ editable.</p><hr /><p> @ These settings work in the same way, as the <kbd>set</kbd> @ commandline:<br /> @ </p><pre>%s(zHelp_setting_cmd)</pre> db_end_transaction(0); style_footer(); |
︙ | ︙ |
Changes to src/sqlite3.c.
︙ | ︙ | |||
323 324 325 326 327 328 329 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.11" #define SQLITE_VERSION_NUMBER 3008011 | | | 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.11" #define SQLITE_VERSION_NUMBER 3008011 #define SQLITE_SOURCE_ID "2015-07-23 20:44:49 017c5019e1ce042025d4f327e50ec50af49f9fa4" /* ** 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 |
︙ | ︙ | |||
1177 1178 1179 1180 1181 1182 1183 | ** circumstances in order to fix a problem with priority inversion. ** Applications should <em>not</em> use this file-control. ** ** <li>[[SQLITE_FCNTL_ZIPVFS]] ** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other ** VFS should return SQLITE_NOTFOUND for this opcode. ** | | | | | 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 | ** circumstances in order to fix a problem with priority inversion. ** Applications should <em>not</em> use this file-control. ** ** <li>[[SQLITE_FCNTL_ZIPVFS]] ** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other ** VFS should return SQLITE_NOTFOUND for this opcode. ** ** <li>[[SQLITE_FCNTL_RBU]] ** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by ** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for ** this opcode. ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 #define SQLITE_FCNTL_LAST_ERRNO 4 |
︙ | ︙ | |||
1207 1208 1209 1210 1211 1212 1213 | #define SQLITE_FCNTL_TRACE 19 #define SQLITE_FCNTL_HAS_MOVED 20 #define SQLITE_FCNTL_SYNC 21 #define SQLITE_FCNTL_COMMIT_PHASETWO 22 #define SQLITE_FCNTL_WIN32_SET_HANDLE 23 #define SQLITE_FCNTL_WAL_BLOCK 24 #define SQLITE_FCNTL_ZIPVFS 25 | | | 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 | #define SQLITE_FCNTL_TRACE 19 #define SQLITE_FCNTL_HAS_MOVED 20 #define SQLITE_FCNTL_SYNC 21 #define SQLITE_FCNTL_COMMIT_PHASETWO 22 #define SQLITE_FCNTL_WIN32_SET_HANDLE 23 #define SQLITE_FCNTL_WAL_BLOCK 24 #define SQLITE_FCNTL_ZIPVFS 25 #define SQLITE_FCNTL_RBU 26 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO |
︙ | ︙ | |||
8359 8360 8361 8362 8363 8364 8365 | # define SQLITE_NOINLINE #endif /* ** Make sure that the compiler intrinsics we desire are enabled when ** compiling with an appropriate version of MSVC. */ | | | 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 | # define SQLITE_NOINLINE #endif /* ** Make sure that the compiler intrinsics we desire are enabled when ** compiling with an appropriate version of MSVC. */ #if defined(_MSC_VER) && _MSC_VER>=1300 && !defined(_WIN32_WCE) # include <intrin.h> # pragma intrinsic(_byteswap_ushort) # pragma intrinsic(_byteswap_ulong) #endif /* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. |
︙ | ︙ | |||
9187 9188 9189 9190 9191 9192 9193 | # define SQLITE_MAX_MMAP_SIZE 0 # endif #endif #ifndef SQLITE_MAX_MMAP_SIZE # if defined(__linux__) \ || defined(_WIN32) \ || (defined(__APPLE__) && defined(__MACH__)) \ | | > > | 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 | # define SQLITE_MAX_MMAP_SIZE 0 # endif #endif #ifndef SQLITE_MAX_MMAP_SIZE # if defined(__linux__) \ || defined(_WIN32) \ || (defined(__APPLE__) && defined(__MACH__)) \ || defined(__sun) \ || defined(__FreeBSD__) \ || defined(__DragonFly__) # define SQLITE_MAX_MMAP_SIZE 0x7fff0000 /* 2147418112 */ # else # define SQLITE_MAX_MMAP_SIZE 0 # endif # define SQLITE_MAX_MMAP_SIZE_xc 1 /* exclude from ctime.c */ #endif |
︙ | ︙ | |||
13881 13882 13883 13884 13885 13886 13887 13888 13889 13890 13891 13892 13893 13894 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains definitions of global variables and constants. */ /* An array to map all upper-case characters into their corresponding ** lower-case character. ** ** SQLite only considers US-ASCII (or EBCDIC) characters. We do not ** handle case conversions for the UTF character set since the tables ** involved are nearly as big or bigger than SQLite itself. | > | 13883 13884 13885 13886 13887 13888 13889 13890 13891 13892 13893 13894 13895 13896 13897 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains definitions of global variables and constants. */ /* #include "sqliteInt.h" */ /* An array to map all upper-case characters into their corresponding ** lower-case character. ** ** SQLite only considers US-ASCII (or EBCDIC) characters. We do not ** handle case conversions for the UTF character set since the tables ** involved are nearly as big or bigger than SQLite itself. |
︙ | ︙ | |||
14120 14121 14122 14123 14124 14125 14126 14127 14128 14129 14130 14131 14132 14133 | ** Changing the pending byte during operation will result in undefined ** and incorrect behavior. */ #ifndef SQLITE_OMIT_WSD SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000; #endif /* ** Properties of opcodes. The OPFLG_INITIALIZER macro is ** created by mkopcodeh.awk during compilation. Data is obtained ** from the comments following the "case OP_xxxx:" statements in ** the vdbe.c file. */ SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; | > | 14123 14124 14125 14126 14127 14128 14129 14130 14131 14132 14133 14134 14135 14136 14137 | ** Changing the pending byte during operation will result in undefined ** and incorrect behavior. */ #ifndef SQLITE_OMIT_WSD SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000; #endif /* #include "opcodes.h" */ /* ** Properties of opcodes. The OPFLG_INITIALIZER macro is ** created by mkopcodeh.awk during compilation. Data is obtained ** from the comments following the "case OP_xxxx:" statements in ** the vdbe.c file. */ SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; |
︙ | ︙ | |||
14148 14149 14150 14151 14152 14153 14154 14155 14156 14157 14158 14159 14160 14161 | ** ** This file implements routines used to report what compile-time options ** SQLite was built with. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS /* ** An array of names of all compile-time options. This array should ** be sorted A-Z. ** ** This array looks large, but in a typical installation actually uses ** only a handful of compile-time options, so most times this array is usually | > | 14152 14153 14154 14155 14156 14157 14158 14159 14160 14161 14162 14163 14164 14165 14166 | ** ** This file implements routines used to report what compile-time options ** SQLite was built with. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS /* #include "sqliteInt.h" */ /* ** An array of names of all compile-time options. This array should ** be sorted A-Z. ** ** This array looks large, but in a typical installation actually uses ** only a handful of compile-time options, so most times this array is usually |
︙ | ︙ | |||
14577 14578 14579 14580 14581 14582 14583 14584 14585 14586 14587 14588 14589 14590 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This module implements the sqlite3_status() interface and related ** functionality. */ /************** Include vdbeInt.h in the middle of status.c ******************/ /************** Begin file vdbeInt.h *****************************************/ /* ** 2003 September 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: | > | 14582 14583 14584 14585 14586 14587 14588 14589 14590 14591 14592 14593 14594 14595 14596 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This module implements the sqlite3_status() interface and related ** functionality. */ /* #include "sqliteInt.h" */ /************** Include vdbeInt.h in the middle of status.c ******************/ /************** Begin file vdbeInt.h *****************************************/ /* ** 2003 September 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: |
︙ | ︙ | |||
15460 15461 15462 15463 15464 15465 15466 15467 15468 15469 15470 15471 15472 15473 | ** ** Jean Meeus ** Astronomical Algorithms, 2nd Edition, 1998 ** ISBM 0-943396-61-1 ** Willmann-Bell, Inc ** Richmond, Virginia (USA) */ /* #include <stdlib.h> */ /* #include <assert.h> */ #include <time.h> #ifndef SQLITE_OMIT_DATETIME_FUNCS | > | 15466 15467 15468 15469 15470 15471 15472 15473 15474 15475 15476 15477 15478 15479 15480 | ** ** Jean Meeus ** Astronomical Algorithms, 2nd Edition, 1998 ** ISBM 0-943396-61-1 ** Willmann-Bell, Inc ** Richmond, Virginia (USA) */ /* #include "sqliteInt.h" */ /* #include <stdlib.h> */ /* #include <assert.h> */ #include <time.h> #ifndef SQLITE_OMIT_DATETIME_FUNCS |
︙ | ︙ | |||
15771 15772 15773 15774 15775 15776 15777 | p->D = 1; }else{ Z = (int)((p->iJD + 43200000)/86400000); A = (int)((Z - 1867216.25)/36524.25); A = Z + 1 + A - (A/4); B = A + 1524; C = (int)((B - 122.1)/365.25); | | | 15778 15779 15780 15781 15782 15783 15784 15785 15786 15787 15788 15789 15790 15791 15792 | p->D = 1; }else{ Z = (int)((p->iJD + 43200000)/86400000); A = (int)((Z - 1867216.25)/36524.25); A = Z + 1 + A - (A/4); B = A + 1524; C = (int)((B - 122.1)/365.25); D = (36525*(C&32767))/100; E = (int)((B-D)/30.6001); X1 = (int)(30.6001*E); p->D = B - D - X1; p->M = E<14 ? E-1 : E-13; p->Y = p->M>2 ? C - 4716 : C - 4715; } p->validYMD = 1; |
︙ | ︙ | |||
16572 16573 16574 16575 16576 16577 16578 16579 16580 16581 16582 16583 16584 16585 | ** ****************************************************************************** ** ** This file contains OS interface code that is common to all ** architectures. */ #define _SQLITE_OS_C_ 1 #undef _SQLITE_OS_C_ /* ** The default SQLite sqlite3_vfs implementations do not allocate ** memory (actually, os_unix.c allocates a small amount of memory ** from within OsOpen()), but some third-party implementations may. ** So we test the effects of a malloc() failing and the sqlite3OsXXX() | > | 16579 16580 16581 16582 16583 16584 16585 16586 16587 16588 16589 16590 16591 16592 16593 | ** ****************************************************************************** ** ** This file contains OS interface code that is common to all ** architectures. */ #define _SQLITE_OS_C_ 1 /* #include "sqliteInt.h" */ #undef _SQLITE_OS_C_ /* ** The default SQLite sqlite3_vfs implementations do not allocate ** memory (actually, os_unix.c allocates a small amount of memory ** from within OsOpen()), but some third-party implementations may. ** So we test the effects of a malloc() failing and the sqlite3OsXXX() |
︙ | ︙ | |||
16978 16979 16980 16981 16982 16983 16984 16985 16986 16987 16988 16989 16990 16991 | ** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily ** fatal. For example, if a malloc fails while resizing a hash table, this ** is completely recoverable simply by not carrying out the resize. The ** hash table will continue to function normally. So a malloc failure ** during a hash table resize is a benign fault. */ #ifndef SQLITE_OMIT_BUILTIN_TEST /* ** Global variables. */ typedef struct BenignMallocHooks BenignMallocHooks; | > | 16986 16987 16988 16989 16990 16991 16992 16993 16994 16995 16996 16997 16998 16999 17000 | ** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily ** fatal. For example, if a malloc fails while resizing a hash table, this ** is completely recoverable simply by not carrying out the resize. The ** hash table will continue to function normally. So a malloc failure ** during a hash table resize is a benign fault. */ /* #include "sqliteInt.h" */ #ifndef SQLITE_OMIT_BUILTIN_TEST /* ** Global variables. */ typedef struct BenignMallocHooks BenignMallocHooks; |
︙ | ︙ | |||
17059 17060 17061 17062 17063 17064 17065 17066 17067 17068 17069 17070 17071 17072 | ** ** This file contains a no-op memory allocation drivers for use when ** SQLITE_ZERO_MALLOC is defined. The allocation drivers implemented ** here always fail. SQLite will not operate with these drivers. These ** are merely placeholders. Real drivers must be substituted using ** sqlite3_config() before SQLite will operate. */ /* ** This version of the memory allocator is the default. It is ** used when no other memory allocator is specified using compile-time ** macros. */ #ifdef SQLITE_ZERO_MALLOC | > | 17068 17069 17070 17071 17072 17073 17074 17075 17076 17077 17078 17079 17080 17081 17082 | ** ** This file contains a no-op memory allocation drivers for use when ** SQLITE_ZERO_MALLOC is defined. The allocation drivers implemented ** here always fail. SQLite will not operate with these drivers. These ** are merely placeholders. Real drivers must be substituted using ** sqlite3_config() before SQLite will operate. */ /* #include "sqliteInt.h" */ /* ** This version of the memory allocator is the default. It is ** used when no other memory allocator is specified using compile-time ** macros. */ #ifdef SQLITE_ZERO_MALLOC |
︙ | ︙ | |||
17145 17146 17147 17148 17149 17150 17151 17152 17153 17154 17155 17156 17157 17158 | ** building on older macs. ** ** SQLITE_WITHOUT_MSIZE Set this symbol to disable the use of ** _msize() on windows systems. This might ** be necessary when compiling for Delphi, ** for example. */ /* ** This version of the memory allocator is the default. It is ** used when no other memory allocator is specified using compile-time ** macros. */ #ifdef SQLITE_SYSTEM_MALLOC | > | 17155 17156 17157 17158 17159 17160 17161 17162 17163 17164 17165 17166 17167 17168 17169 | ** building on older macs. ** ** SQLITE_WITHOUT_MSIZE Set this symbol to disable the use of ** _msize() on windows systems. This might ** be necessary when compiling for Delphi, ** for example. */ /* #include "sqliteInt.h" */ /* ** This version of the memory allocator is the default. It is ** used when no other memory allocator is specified using compile-time ** macros. */ #ifdef SQLITE_SYSTEM_MALLOC |
︙ | ︙ | |||
17420 17421 17422 17423 17424 17425 17426 17427 17428 17429 17430 17431 17432 17433 | ** to obtain the memory it needs while adding lots of additional debugging ** information to each allocation in order to help detect and fix memory ** leaks and memory usage errors. ** ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. */ /* ** This version of the memory allocator is used only if the ** SQLITE_MEMDEBUG macro is defined */ #ifdef SQLITE_MEMDEBUG | > | 17431 17432 17433 17434 17435 17436 17437 17438 17439 17440 17441 17442 17443 17444 17445 | ** to obtain the memory it needs while adding lots of additional debugging ** information to each allocation in order to help detect and fix memory ** leaks and memory usage errors. ** ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. */ /* #include "sqliteInt.h" */ /* ** This version of the memory allocator is used only if the ** SQLITE_MEMDEBUG macro is defined */ #ifdef SQLITE_MEMDEBUG |
︙ | ︙ | |||
17954 17955 17956 17957 17958 17959 17960 17961 17962 17963 17964 17965 17966 17967 | ** implementations. Once sqlite3_initialize() has been called, ** the amount of memory available to SQLite is fixed and cannot ** be changed. ** ** This version of the memory allocation subsystem is included ** in the build only if SQLITE_ENABLE_MEMSYS3 is defined. */ /* ** This version of the memory allocator is only built into the library ** SQLITE_ENABLE_MEMSYS3 is defined. Defining this symbol does not ** mean that the library will use a memory-pool by default, just that ** it is available. The mempool allocator is activated by calling ** sqlite3_config(). | > | 17966 17967 17968 17969 17970 17971 17972 17973 17974 17975 17976 17977 17978 17979 17980 | ** implementations. Once sqlite3_initialize() has been called, ** the amount of memory available to SQLite is fixed and cannot ** be changed. ** ** This version of the memory allocation subsystem is included ** in the build only if SQLITE_ENABLE_MEMSYS3 is defined. */ /* #include "sqliteInt.h" */ /* ** This version of the memory allocator is only built into the library ** SQLITE_ENABLE_MEMSYS3 is defined. Defining this symbol does not ** mean that the library will use a memory-pool by default, just that ** it is available. The mempool allocator is activated by calling ** sqlite3_config(). |
︙ | ︙ | |||
18668 18669 18670 18671 18672 18673 18674 18675 18676 18677 18678 18679 18680 18681 | ** fragmentation as long as the following constraint holds: ** ** N >= M*(1 + log2(n)/2) - n + 1 ** ** The sqlite3_status() logic tracks the maximum values of n and M so ** that an application can, at any time, verify this constraint. */ /* ** This version of the memory allocator is used only when ** SQLITE_ENABLE_MEMSYS5 is defined. */ #ifdef SQLITE_ENABLE_MEMSYS5 | > | 18681 18682 18683 18684 18685 18686 18687 18688 18689 18690 18691 18692 18693 18694 18695 | ** fragmentation as long as the following constraint holds: ** ** N >= M*(1 + log2(n)/2) - n + 1 ** ** The sqlite3_status() logic tracks the maximum values of n and M so ** that an application can, at any time, verify this constraint. */ /* #include "sqliteInt.h" */ /* ** This version of the memory allocator is used only when ** SQLITE_ENABLE_MEMSYS5 is defined. */ #ifdef SQLITE_ENABLE_MEMSYS5 |
︙ | ︙ | |||
19211 19212 19213 19214 19215 19216 19217 19218 19219 19220 19221 19222 19223 19224 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement mutexes. ** ** This file contains code that is common across all mutex implementations. */ #if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT) /* ** For debugging purposes, record when the mutex subsystem is initialized ** and uninitialized so that we can assert() if there is an attempt to ** allocate a mutex while the system is uninitialized. */ | > | 19225 19226 19227 19228 19229 19230 19231 19232 19233 19234 19235 19236 19237 19238 19239 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement mutexes. ** ** This file contains code that is common across all mutex implementations. */ /* #include "sqliteInt.h" */ #if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT) /* ** For debugging purposes, record when the mutex subsystem is initialized ** and uninitialized so that we can assert() if there is an attempt to ** allocate a mutex while the system is uninitialized. */ |
︙ | ︙ | |||
19384 19385 19386 19387 19388 19389 19390 19391 19392 19393 19394 19395 19396 19397 | ** ** interface. ** ** If compiled with SQLITE_DEBUG, then additional logic is inserted ** that does error checking on mutexes to make sure they are being ** called correctly. */ #ifndef SQLITE_MUTEX_OMIT #ifndef SQLITE_DEBUG /* ** Stub routines for all mutex methods. ** | > | 19399 19400 19401 19402 19403 19404 19405 19406 19407 19408 19409 19410 19411 19412 19413 | ** ** interface. ** ** If compiled with SQLITE_DEBUG, then additional logic is inserted ** that does error checking on mutexes to make sure they are being ** called correctly. */ /* #include "sqliteInt.h" */ #ifndef SQLITE_MUTEX_OMIT #ifndef SQLITE_DEBUG /* ** Stub routines for all mutex methods. ** |
︙ | ︙ | |||
19587 19588 19589 19590 19591 19592 19593 19594 19595 19596 19597 19598 19599 19600 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement mutexes for pthreads */ /* ** The code in this file is only used if we are compiling threadsafe ** under unix with pthreads. ** ** Note that this implementation requires a version of pthreads that ** supports recursive mutexes. | > | 19603 19604 19605 19606 19607 19608 19609 19610 19611 19612 19613 19614 19615 19616 19617 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement mutexes for pthreads */ /* #include "sqliteInt.h" */ /* ** The code in this file is only used if we are compiling threadsafe ** under unix with pthreads. ** ** Note that this implementation requires a version of pthreads that ** supports recursive mutexes. |
︙ | ︙ | |||
19961 19962 19963 19964 19965 19966 19967 19968 19969 19970 19971 19972 19973 19974 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement mutexes for Win32. */ #if SQLITE_OS_WIN /* ** Include code that is common to all os_*.c files */ /************** Include os_common.h in the middle of mutex_w32.c *************/ /************** Begin file os_common.h ***************************************/ | > | 19978 19979 19980 19981 19982 19983 19984 19985 19986 19987 19988 19989 19990 19991 19992 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement mutexes for Win32. */ /* #include "sqliteInt.h" */ #if SQLITE_OS_WIN /* ** Include code that is common to all os_*.c files */ /************** Include os_common.h in the middle of mutex_w32.c *************/ /************** Begin file os_common.h ***************************************/ |
︙ | ︙ | |||
20636 20637 20638 20639 20640 20641 20642 20643 20644 20645 20646 20647 20648 20649 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** Memory allocation functions used throughout sqlite. */ /* #include <stdarg.h> */ /* ** Attempt to release up to n bytes of non-essential memory currently ** held by SQLite. An example of non-essential memory is memory used to ** cache database pages that are not currently in use. */ | > | 20654 20655 20656 20657 20658 20659 20660 20661 20662 20663 20664 20665 20666 20667 20668 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** Memory allocation functions used throughout sqlite. */ /* #include "sqliteInt.h" */ /* #include <stdarg.h> */ /* ** Attempt to release up to n bytes of non-essential memory currently ** held by SQLite. An example of non-essential memory is memory used to ** cache database pages that are not currently in use. */ |
︙ | ︙ | |||
21447 21448 21449 21450 21451 21452 21453 21454 21455 21456 21457 21458 21459 21460 | ************************************************************************** ** ** This file contains code for a set of "printf"-like routines. These ** routines format strings much like the printf() from the standard C ** library, though the implementation here has enhancements to support ** SQLite. */ /* ** Conversion types fall into various categories as defined by the ** following enumeration. */ #define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ #define etFLOAT 2 /* Floating point. %f */ | > | 21466 21467 21468 21469 21470 21471 21472 21473 21474 21475 21476 21477 21478 21479 21480 | ************************************************************************** ** ** This file contains code for a set of "printf"-like routines. These ** routines format strings much like the printf() from the standard C ** library, though the implementation here has enhancements to support ** SQLite. */ /* #include "sqliteInt.h" */ /* ** Conversion types fall into various categories as defined by the ** following enumeration. */ #define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */ #define etFLOAT 2 /* Floating point. %f */ |
︙ | ︙ | |||
22449 22450 22451 22452 22453 22454 22455 22456 22457 22458 22459 22460 22461 22462 | ** This is the routine that actually formats the sqlite3_log() message. ** We house it in a separate routine from sqlite3_log() to avoid using ** stack space on small-stack systems when logging is disabled. ** ** sqlite3_log() must render into a static buffer. It cannot dynamically ** allocate memory because it might be called while the memory allocator ** mutex is held. */ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ StrAccum acc; /* String accumulator */ char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); sqlite3VXPrintf(&acc, 0, zFormat, ap); | > > > > > | 22469 22470 22471 22472 22473 22474 22475 22476 22477 22478 22479 22480 22481 22482 22483 22484 22485 22486 22487 | ** This is the routine that actually formats the sqlite3_log() message. ** We house it in a separate routine from sqlite3_log() to avoid using ** stack space on small-stack systems when logging is disabled. ** ** sqlite3_log() must render into a static buffer. It cannot dynamically ** allocate memory because it might be called while the memory allocator ** mutex is held. ** ** sqlite3VXPrintf() might ask for *temporary* memory allocations for ** certain format characters (%q) or for very large precisions or widths. ** Care must be taken that any sqlite3_log() calls that occur while the ** memory mutex is held do not use these mechanisms. */ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ StrAccum acc; /* String accumulator */ char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); sqlite3VXPrintf(&acc, 0, zFormat, ap); |
︙ | ︙ | |||
22524 22525 22526 22527 22528 22529 22530 22531 22532 22533 22534 22535 22536 22537 | ** This file contains C code to implement the TreeView debugging routines. ** These routines print a parse tree to standard output for debugging and ** analysis. ** ** The interfaces in this file is only available when compiling ** with SQLITE_DEBUG. */ #ifdef SQLITE_DEBUG /* ** Add a new subitem to the tree. The moreToFollow flag indicates that this ** is not the last item in the tree. */ static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ | > | 22549 22550 22551 22552 22553 22554 22555 22556 22557 22558 22559 22560 22561 22562 22563 | ** This file contains C code to implement the TreeView debugging routines. ** These routines print a parse tree to standard output for debugging and ** analysis. ** ** The interfaces in this file is only available when compiling ** with SQLITE_DEBUG. */ /* #include "sqliteInt.h" */ #ifdef SQLITE_DEBUG /* ** Add a new subitem to the tree. The moreToFollow flag indicates that this ** is not the last item in the tree. */ static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ |
︙ | ︙ | |||
22955 22956 22957 22958 22959 22960 22961 22962 22963 22964 22965 22966 22967 22968 | ************************************************************************* ** This file contains code to implement a pseudo-random number ** generator (PRNG) for SQLite. ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. */ /* All threads share a single random number generator. ** This structure is the current state of the generator. */ static SQLITE_WSD struct sqlite3PrngType { unsigned char isInit; /* True if initialized */ | > | 22981 22982 22983 22984 22985 22986 22987 22988 22989 22990 22991 22992 22993 22994 22995 | ************************************************************************* ** This file contains code to implement a pseudo-random number ** generator (PRNG) for SQLite. ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. */ /* #include "sqliteInt.h" */ /* All threads share a single random number generator. ** This structure is the current state of the generator. */ static SQLITE_WSD struct sqlite3PrngType { unsigned char isInit; /* True if initialized */ |
︙ | ︙ | |||
23101 23102 23103 23104 23105 23106 23107 23108 23109 23110 23111 23112 23113 23114 23115 | ** "thread" is done by the main thread at either the sqlite3ThreadCreate() ** or sqlite3ThreadJoin() call. This is, in fact, what happens in ** single threaded systems. Nothing in SQLite requires multiple threads. ** This interface exists so that applications that want to take advantage ** of multiple cores can do so, while also allowing applications to stay ** single-threaded if desired. */ #if SQLITE_OS_WIN #endif #if SQLITE_MAX_WORKER_THREADS>0 /********************************* Unix Pthreads ****************************/ #if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0 | > > | 23128 23129 23130 23131 23132 23133 23134 23135 23136 23137 23138 23139 23140 23141 23142 23143 23144 | ** "thread" is done by the main thread at either the sqlite3ThreadCreate() ** or sqlite3ThreadJoin() call. This is, in fact, what happens in ** single threaded systems. Nothing in SQLite requires multiple threads. ** This interface exists so that applications that want to take advantage ** of multiple cores can do so, while also allowing applications to stay ** single-threaded if desired. */ /* #include "sqliteInt.h" */ #if SQLITE_OS_WIN /* # include "os_win.h" */ #endif #if SQLITE_MAX_WORKER_THREADS>0 /********************************* Unix Pthreads ****************************/ #if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0 |
︙ | ︙ | |||
23375 23376 23377 23378 23379 23380 23381 23382 23383 23384 23385 23386 23387 23388 23389 | ** ** ** BOM or Byte Order Mark: ** 0xff 0xfe little-endian utf-16 follows ** 0xfe 0xff big-endian utf-16 follows ** */ /* #include <assert.h> */ #ifndef SQLITE_AMALGAMATION /* ** The following constant value is used by the SQLITE_BIGENDIAN and ** SQLITE_LITTLEENDIAN macros. */ SQLITE_PRIVATE const int sqlite3one = 1; | > > | 23404 23405 23406 23407 23408 23409 23410 23411 23412 23413 23414 23415 23416 23417 23418 23419 23420 | ** ** ** BOM or Byte Order Mark: ** 0xff 0xfe little-endian utf-16 follows ** 0xfe 0xff big-endian utf-16 follows ** */ /* #include "sqliteInt.h" */ /* #include <assert.h> */ /* #include "vdbeInt.h" */ #ifndef SQLITE_AMALGAMATION /* ** The following constant value is used by the SQLITE_BIGENDIAN and ** SQLITE_LITTLEENDIAN macros. */ SQLITE_PRIVATE const int sqlite3one = 1; |
︙ | ︙ | |||
23888 23889 23890 23891 23892 23893 23894 23895 23896 23897 23898 23899 23900 23901 | ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** */ /* #include <stdarg.h> */ #if HAVE_ISNAN || SQLITE_HAVE_ISNAN # include <math.h> #endif /* ** Routine needed to support the testcase() macro. | > | 23919 23920 23921 23922 23923 23924 23925 23926 23927 23928 23929 23930 23931 23932 23933 | ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** */ /* #include "sqliteInt.h" */ /* #include <stdarg.h> */ #if HAVE_ISNAN || SQLITE_HAVE_ISNAN # include <math.h> #endif /* ** Routine needed to support the testcase() macro. |
︙ | ︙ | |||
25284 25285 25286 25287 25288 25289 25290 25291 25292 25293 25294 25295 25296 25297 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This is the implementation of generic hash-tables ** used in SQLite. */ /* #include <assert.h> */ /* Turn bulk memory into a hash table object by initializing the ** fields of the Hash structure. ** ** "pNew" is a pointer to the hash table that is to be initialized. */ | > | 25316 25317 25318 25319 25320 25321 25322 25323 25324 25325 25326 25327 25328 25329 25330 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This is the implementation of generic hash-tables ** used in SQLite. */ /* #include "sqliteInt.h" */ /* #include <assert.h> */ /* Turn bulk memory into a hash table object by initializing the ** fields of the Hash structure. ** ** "pNew" is a pointer to the hash table that is to be initialized. */ |
︙ | ︙ | |||
25761 25762 25763 25764 25765 25766 25767 25768 25769 25770 25771 25772 25773 25774 | ** * Definitions of sqlite3_io_methods objects for all locking ** methods plus "finder" functions for each locking method. ** * sqlite3_vfs method implementations. ** * Locking primitives for the proxy uber-locking-method. (MacOSX only) ** * Definitions of sqlite3_vfs objects for all locking methods ** plus implementations of sqlite3_os_init() and sqlite3_os_end(). */ #if SQLITE_OS_UNIX /* This file is used on unix only */ /* ** There are various methods for file locking used for concurrency ** control: ** ** 1. POSIX locking (the default), | > | 25794 25795 25796 25797 25798 25799 25800 25801 25802 25803 25804 25805 25806 25807 25808 | ** * Definitions of sqlite3_io_methods objects for all locking ** methods plus "finder" functions for each locking method. ** * sqlite3_vfs method implementations. ** * Locking primitives for the proxy uber-locking-method. (MacOSX only) ** * Definitions of sqlite3_vfs objects for all locking methods ** plus implementations of sqlite3_os_init() and sqlite3_os_end(). */ /* #include "sqliteInt.h" */ #if SQLITE_OS_UNIX /* This file is used on unix only */ /* ** There are various methods for file locking used for concurrency ** control: ** ** 1. POSIX locking (the default), |
︙ | ︙ | |||
33495 33496 33497 33498 33499 33500 33501 33502 33503 33504 33505 33506 33507 33508 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This file contains code that is specific to Windows. */ #if SQLITE_OS_WIN /* This file is used for Windows only */ /* ** Include code that is common to all os_*.c files */ /************** Include os_common.h in the middle of os_win.c ****************/ /************** Begin file os_common.h ***************************************/ | > | 33529 33530 33531 33532 33533 33534 33535 33536 33537 33538 33539 33540 33541 33542 33543 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This file contains code that is specific to Windows. */ /* #include "sqliteInt.h" */ #if SQLITE_OS_WIN /* This file is used for Windows only */ /* ** Include code that is common to all os_*.c files */ /************** Include os_common.h in the middle of os_win.c ****************/ /************** Begin file os_common.h ***************************************/ |
︙ | ︙ | |||
33703 33704 33705 33706 33707 33708 33709 33710 33711 33712 33713 33714 33715 33716 | /************** End of os_common.h *******************************************/ /************** Continuing where we left off in os_win.c *********************/ /* ** Include the header file for the Windows VFS. */ /* ** Compiling and using WAL mode requires several APIs that are only ** available in Windows platforms based on the NT kernel. */ #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) # error "WAL mode requires support from the Windows NT kernel, compile\ | > | 33738 33739 33740 33741 33742 33743 33744 33745 33746 33747 33748 33749 33750 33751 33752 | /************** End of os_common.h *******************************************/ /************** Continuing where we left off in os_win.c *********************/ /* ** Include the header file for the Windows VFS. */ /* #include "os_win.h" */ /* ** Compiling and using WAL mode requires several APIs that are only ** available in Windows platforms based on the NT kernel. */ #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) # error "WAL mode requires support from the Windows NT kernel, compile\ |
︙ | ︙ | |||
39356 39357 39358 39359 39360 39361 39362 39363 39364 39365 39366 39367 39368 39369 | ** Clear operations are exceedingly rare. There are usually between ** 5 and 500 set operations per Bitvec object, though the number of sets can ** sometimes grow into tens of thousands or larger. The size of the ** Bitvec object is the number of pages in the database file at the ** start of a transaction, and is thus usually less than a few thousand, ** but can be as large as 2 billion for a really big database. */ /* Size of the Bitvec structure in bytes. */ #define BITVEC_SZ 512 /* Round the union size down to the nearest pointer boundary, since that's how ** it will be aligned within the Bitvec struct. */ #define BITVEC_USIZE (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*)) | > | 39392 39393 39394 39395 39396 39397 39398 39399 39400 39401 39402 39403 39404 39405 39406 | ** Clear operations are exceedingly rare. There are usually between ** 5 and 500 set operations per Bitvec object, though the number of sets can ** sometimes grow into tens of thousands or larger. The size of the ** Bitvec object is the number of pages in the database file at the ** start of a transaction, and is thus usually less than a few thousand, ** but can be as large as 2 billion for a really big database. */ /* #include "sqliteInt.h" */ /* Size of the Bitvec structure in bytes. */ #define BITVEC_SZ 512 /* Round the union size down to the nearest pointer boundary, since that's how ** it will be aligned within the Bitvec struct. */ #define BITVEC_USIZE (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*)) |
︙ | ︙ | |||
39745 39746 39747 39748 39749 39750 39751 39752 39753 39754 39755 39756 39757 39758 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file implements that page cache. */ /* ** A complete page cache is an instance of this structure. */ struct PCache { PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ PgHdr *pSynced; /* Last synced page in dirty page list */ | > | 39782 39783 39784 39785 39786 39787 39788 39789 39790 39791 39792 39793 39794 39795 39796 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file implements that page cache. */ /* #include "sqliteInt.h" */ /* ** A complete page cache is an instance of this structure. */ struct PCache { PgHdr *pDirty, *pDirtyTail; /* List of dirty pages in LRU order */ PgHdr *pSynced; /* Last synced page in dirty page list */ |
︙ | ︙ | |||
40486 40487 40488 40489 40490 40491 40492 40493 40494 40495 40496 40497 40498 40499 | ** (3) is exhausted, subsequent allocations fail over to the general-purpose ** memory allocator (1). ** ** Earlier versions of SQLite used only methods (1) and (2). But experiments ** show that method (3) with N==100 provides about a 5% performance boost for ** common workloads. */ typedef struct PCache1 PCache1; typedef struct PgHdr1 PgHdr1; typedef struct PgFreeslot PgFreeslot; typedef struct PGroup PGroup; /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set | > | 40524 40525 40526 40527 40528 40529 40530 40531 40532 40533 40534 40535 40536 40537 40538 | ** (3) is exhausted, subsequent allocations fail over to the general-purpose ** memory allocator (1). ** ** Earlier versions of SQLite used only methods (1) and (2). But experiments ** show that method (3) with N==100 provides about a 5% performance boost for ** common workloads. */ /* #include "sqliteInt.h" */ typedef struct PCache1 PCache1; typedef struct PgHdr1 PgHdr1; typedef struct PgFreeslot PgFreeslot; typedef struct PGroup PGroup; /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set |
︙ | ︙ | |||
40596 40597 40598 40599 40600 40601 40602 40603 40604 40605 40606 40607 40608 40609 | /* Variables related to SQLITE_CONFIG_PAGECACHE settings. The ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all ** fixed at sqlite3_initialize() time and do not require mutex protection. ** The nFreeSlot and pFree values do require mutex protection. */ int isInit; /* True if initialized */ int separateCache; /* Use a new PGroup for each PCache */ int szSlot; /* Size of each free slot */ int nSlot; /* The number of pcache slots */ int nReserve; /* Try to keep nFreeSlot above this */ void *pStart, *pEnd; /* Bounds of global page cache memory */ /* Above requires no mutex. Use mutex below for variable that follow. */ sqlite3_mutex *mutex; /* Mutex for accessing the following: */ PgFreeslot *pFree; /* Free page blocks */ | > | 40635 40636 40637 40638 40639 40640 40641 40642 40643 40644 40645 40646 40647 40648 40649 | /* Variables related to SQLITE_CONFIG_PAGECACHE settings. The ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all ** fixed at sqlite3_initialize() time and do not require mutex protection. ** The nFreeSlot and pFree values do require mutex protection. */ int isInit; /* True if initialized */ int separateCache; /* Use a new PGroup for each PCache */ int nInitPage; /* Initial bulk allocation size */ int szSlot; /* Size of each free slot */ int nSlot; /* The number of pcache slots */ int nReserve; /* Try to keep nFreeSlot above this */ void *pStart, *pEnd; /* Bounds of global page cache memory */ /* Above requires no mutex. Use mutex below for variable that follow. */ sqlite3_mutex *mutex; /* Mutex for accessing the following: */ PgFreeslot *pFree; /* Free page blocks */ |
︙ | ︙ | |||
40663 40664 40665 40666 40667 40668 40669 40670 40671 40672 40673 40674 40675 40676 | p->pNext = pcache1.pFree; pcache1.pFree = p; pBuf = (void*)&((char*)pBuf)[sz]; } pcache1.pEnd = pBuf; } } /* ** Malloc function used within this file to allocate space from the buffer ** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no ** such buffer exists or there is no space left in it, this function falls ** back to sqlite3Malloc(). ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 40703 40704 40705 40706 40707 40708 40709 40710 40711 40712 40713 40714 40715 40716 40717 40718 40719 40720 40721 40722 40723 40724 40725 40726 40727 40728 40729 40730 40731 40732 40733 40734 40735 40736 40737 40738 40739 40740 40741 40742 40743 40744 40745 40746 40747 40748 40749 40750 40751 40752 40753 | p->pNext = pcache1.pFree; pcache1.pFree = p; pBuf = (void*)&((char*)pBuf)[sz]; } pcache1.pEnd = pBuf; } } /* ** Try to initialize the pCache->pFree and pCache->pBulk fields. Return ** true if pCache->pFree ends up containing one or more free pages. */ static int pcache1InitBulk(PCache1 *pCache){ i64 szBulk; char *zBulk; if( pcache1.nInitPage==0 ) return 0; /* Do not bother with a bulk allocation if the cache size very small */ if( pCache->nMax<3 ) return 0; sqlite3BeginBenignMalloc(); if( pcache1.nInitPage>0 ){ szBulk = pCache->szAlloc * (i64)pcache1.nInitPage; }else{ szBulk = -1024 * (i64)pcache1.nInitPage; } if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){ szBulk = pCache->szAlloc*pCache->nMax; } zBulk = pCache->pBulk = sqlite3Malloc( szBulk ); sqlite3EndBenignMalloc(); if( zBulk ){ int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc; int i; for(i=0; i<nBulk; i++){ PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; pX->page.pBuf = zBulk; pX->page.pExtra = &pX[1]; pX->isBulkLocal = 1; pX->pNext = pCache->pFree; pCache->pFree = pX; zBulk += pCache->szAlloc; } } return pCache->pFree!=0; } /* ** Malloc function used within this file to allocate space from the buffer ** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no ** such buffer exists or there is no space left in it, this function falls ** back to sqlite3Malloc(). ** |
︙ | ︙ | |||
40764 40765 40766 40767 40768 40769 40770 | ** Allocate a new page object initially associated with cache pCache. */ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){ PgHdr1 *p = 0; void *pPg; assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); | | | 40841 40842 40843 40844 40845 40846 40847 40848 40849 40850 40851 40852 40853 40854 40855 | ** Allocate a new page object initially associated with cache pCache. */ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){ PgHdr1 *p = 0; void *pPg; assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){ p = pCache->pFree; pCache->pFree = p->pNext; p->pNext = 0; }else{ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* The group mutex must be released before pcache1Alloc() is called. This ** is because it might call sqlite3_release_memory(), which assumes that |
︙ | ︙ | |||
40968 40969 40970 40971 40972 40973 40974 | if( freeFlag ) pcache1FreePage(pPage); } /* ** If there are currently more than nMaxPage pages allocated, try ** to recycle pages to reduce the number allocated to nMaxPage. */ | | > > > > > | 41045 41046 41047 41048 41049 41050 41051 41052 41053 41054 41055 41056 41057 41058 41059 41060 41061 41062 41063 41064 41065 41066 41067 41068 41069 41070 41071 | if( freeFlag ) pcache1FreePage(pPage); } /* ** If there are currently more than nMaxPage pages allocated, try ** to recycle pages to reduce the number allocated to nMaxPage. */ static void pcache1EnforceMaxPage(PCache1 *pCache){ PGroup *pGroup = pCache->pGroup; assert( sqlite3_mutex_held(pGroup->mutex) ); while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){ PgHdr1 *p = pGroup->pLruTail; assert( p->pCache->pGroup==pGroup ); assert( p->isPinned==0 ); pcache1PinPage(p); pcache1RemoveFromHash(p, 1); } if( pCache->nPage==0 && pCache->pBulk ){ sqlite3_free(pCache->pBulk); pCache->pBulk = pCache->pFree = 0; } } /* ** Discard all pages from cache pCache with a page number (key value) ** greater than or equal to iLimit. Any pinned pages that meet this ** criteria are unpinned before they are discarded. |
︙ | ︙ | |||
41052 41053 41054 41055 41056 41057 41058 41059 41060 41061 41062 41063 41064 41065 | #if SQLITE_THREADSAFE if( sqlite3GlobalConfig.bCoreMutex ){ pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU); pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM); } #endif pcache1.grp.mxPinned = 10; pcache1.isInit = 1; return SQLITE_OK; } /* ** Implementation of the sqlite3_pcache.xShutdown method. | > > > > > > > > | 41134 41135 41136 41137 41138 41139 41140 41141 41142 41143 41144 41145 41146 41147 41148 41149 41150 41151 41152 41153 41154 41155 | #if SQLITE_THREADSAFE if( sqlite3GlobalConfig.bCoreMutex ){ pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU); pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM); } #endif if( pcache1.separateCache && sqlite3GlobalConfig.nPage!=0 && sqlite3GlobalConfig.pPage==0 ){ pcache1.nInitPage = sqlite3GlobalConfig.nPage; }else{ pcache1.nInitPage = 0; } pcache1.grp.mxPinned = 10; pcache1.isInit = 1; return SQLITE_OK; } /* ** Implementation of the sqlite3_pcache.xShutdown method. |
︙ | ︙ | |||
41106 41107 41108 41109 41110 41111 41112 | pcache1ResizeHash(pCache); if( bPurgeable ){ pCache->nMin = 10; pGroup->nMinPage += pCache->nMin; pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; } pcache1LeaveMutex(pGroup); | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 41196 41197 41198 41199 41200 41201 41202 41203 41204 41205 41206 41207 41208 41209 | pcache1ResizeHash(pCache); if( bPurgeable ){ pCache->nMin = 10; pGroup->nMinPage += pCache->nMin; pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; } pcache1LeaveMutex(pGroup); if( pCache->nHash==0 ){ pcache1Destroy((sqlite3_pcache*)pCache); pCache = 0; } } return (sqlite3_pcache *)pCache; } |
︙ | ︙ | |||
41158 41159 41160 41161 41162 41163 41164 | if( pCache->bPurgeable ){ PGroup *pGroup = pCache->pGroup; pcache1EnterMutex(pGroup); pGroup->nMaxPage += (nMax - pCache->nMax); pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; pCache->nMax = nMax; pCache->n90pct = pCache->nMax*9/10; | | | | 41218 41219 41220 41221 41222 41223 41224 41225 41226 41227 41228 41229 41230 41231 41232 41233 41234 41235 41236 41237 41238 41239 41240 41241 41242 41243 41244 41245 41246 41247 41248 41249 41250 | if( pCache->bPurgeable ){ PGroup *pGroup = pCache->pGroup; pcache1EnterMutex(pGroup); pGroup->nMaxPage += (nMax - pCache->nMax); pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; pCache->nMax = nMax; pCache->n90pct = pCache->nMax*9/10; pcache1EnforceMaxPage(pCache); pcache1LeaveMutex(pGroup); } } /* ** Implementation of the sqlite3_pcache.xShrink method. ** ** Free up as much memory as possible. */ static void pcache1Shrink(sqlite3_pcache *p){ PCache1 *pCache = (PCache1*)p; if( pCache->bPurgeable ){ PGroup *pGroup = pCache->pGroup; int savedMaxPage; pcache1EnterMutex(pGroup); savedMaxPage = pGroup->nMaxPage; pGroup->nMaxPage = 0; pcache1EnforceMaxPage(pCache); pGroup->nMaxPage = savedMaxPage; pcache1LeaveMutex(pGroup); } } /* ** Implementation of the sqlite3_pcache.xPagecount method. |
︙ | ︙ | |||
41513 41514 41515 41516 41517 41518 41519 | pcache1EnterMutex(pGroup); pcache1TruncateUnsafe(pCache, 0); assert( pGroup->nMaxPage >= pCache->nMax ); pGroup->nMaxPage -= pCache->nMax; assert( pGroup->nMinPage >= pCache->nMin ); pGroup->nMinPage -= pCache->nMin; pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; | | | 41573 41574 41575 41576 41577 41578 41579 41580 41581 41582 41583 41584 41585 41586 41587 | pcache1EnterMutex(pGroup); pcache1TruncateUnsafe(pCache, 0); assert( pGroup->nMaxPage >= pCache->nMax ); pGroup->nMaxPage -= pCache->nMax; assert( pGroup->nMinPage >= pCache->nMin ); pGroup->nMinPage -= pCache->nMin; pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; pcache1EnforceMaxPage(pCache); pcache1LeaveMutex(pGroup); sqlite3_free(pCache->pBulk); sqlite3_free(pCache->apHash); sqlite3_free(pCache); } /* |
︙ | ︙ | |||
41677 41678 41679 41680 41681 41682 41683 41684 41685 41686 41687 41688 41689 41690 | ** The cost of a TEST using the same batch number is O(logN). The cost ** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST ** primitives are constant time. The cost of DESTROY is O(N). ** ** There is an added cost of O(N) when switching between TEST and ** SMALLEST primitives. */ /* ** Target size for allocation chunks. */ #define ROWSET_ALLOCATION_SIZE 1024 | > | 41737 41738 41739 41740 41741 41742 41743 41744 41745 41746 41747 41748 41749 41750 41751 | ** The cost of a TEST using the same batch number is O(logN). The cost ** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST ** primitives are constant time. The cost of DESTROY is O(N). ** ** There is an added cost of O(N) when switching between TEST and ** SMALLEST primitives. */ /* #include "sqliteInt.h" */ /* ** Target size for allocation chunks. */ #define ROWSET_ALLOCATION_SIZE 1024 |
︙ | ︙ | |||
42146 42147 42148 42149 42150 42151 42152 42153 42154 42155 42156 42157 42158 42159 | ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. */ #ifndef SQLITE_OMIT_DISKIO /************** Include wal.h in the middle of pager.c ***********************/ /************** Begin file wal.h *********************************************/ /* ** 2010 February 1 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: | > | 42207 42208 42209 42210 42211 42212 42213 42214 42215 42216 42217 42218 42219 42220 42221 | ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. */ #ifndef SQLITE_OMIT_DISKIO /* #include "sqliteInt.h" */ /************** Include wal.h in the middle of pager.c ***********************/ /************** Begin file wal.h *********************************************/ /* ** 2010 February 1 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: |
︙ | ︙ | |||
42167 42168 42169 42170 42171 42172 42173 42174 42175 42176 42177 42178 42179 42180 | ** system. Refer to the comments below and the header comment attached to ** the implementation of each function in log.c for further details. */ #ifndef _WAL_H_ #define _WAL_H_ /* Additional values that can be added to the sync_flags argument of ** sqlite3WalFrames(): */ #define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ #define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ | > | 42229 42230 42231 42232 42233 42234 42235 42236 42237 42238 42239 42240 42241 42242 42243 | ** system. Refer to the comments below and the header comment attached to ** the implementation of each function in log.c for further details. */ #ifndef _WAL_H_ #define _WAL_H_ /* #include "sqliteInt.h" */ /* Additional values that can be added to the sync_flags argument of ** sqlite3WalFrames(): */ #define WAL_SYNC_TRANSACTIONS 0x20 /* Sync at the end of each transaction */ #define SQLITE_SYNC_MASK 0x13 /* Mask off the SQLITE_SYNC_* values */ |
︙ | ︙ | |||
49781 49782 49783 49784 49785 49786 49787 49788 49789 49790 49791 49792 49793 49794 | ** ** When a rollback occurs, the value of K is decreased. Hash table entries ** that correspond to frames greater than the new K value are removed ** from the hash table at this point. */ #ifndef SQLITE_OMIT_WAL /* ** Trace output macros */ #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) SQLITE_PRIVATE int sqlite3WalTrace = 0; # define WALTRACE(X) if(sqlite3WalTrace) sqlite3DebugPrintf X | > | 49844 49845 49846 49847 49848 49849 49850 49851 49852 49853 49854 49855 49856 49857 49858 | ** ** When a rollback occurs, the value of K is decreased. Hash table entries ** that correspond to frames greater than the new K value are removed ** from the hash table at this point. */ #ifndef SQLITE_OMIT_WAL /* #include "wal.h" */ /* ** Trace output macros */ #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) SQLITE_PRIVATE int sqlite3WalTrace = 0; # define WALTRACE(X) if(sqlite3WalTrace) sqlite3DebugPrintf X |
︙ | ︙ | |||
50186 50187 50188 50189 50190 50191 50192 | volatile WalIndexHdr *aHdr = walIndexHdr(pWal); const int nCksum = offsetof(WalIndexHdr, aCksum); assert( pWal->writeLock ); pWal->hdr.isInit = 1; pWal->hdr.iVersion = WALINDEX_MAX_VERSION; walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum); | | | | 50250 50251 50252 50253 50254 50255 50256 50257 50258 50259 50260 50261 50262 50263 50264 50265 50266 | volatile WalIndexHdr *aHdr = walIndexHdr(pWal); const int nCksum = offsetof(WalIndexHdr, aCksum); assert( pWal->writeLock ); pWal->hdr.isInit = 1; pWal->hdr.iVersion = WALINDEX_MAX_VERSION; walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum); memcpy((void*)&aHdr[1], (const void*)&pWal->hdr, sizeof(WalIndexHdr)); walShmBarrier(pWal); memcpy((void*)&aHdr[0], (const void*)&pWal->hdr, sizeof(WalIndexHdr)); } /* ** This function encodes a single frame header and writes it to a buffer ** supplied by the caller. A frame-header is made up of a series of ** 4-byte big-endian integers, as follows: ** |
︙ | ︙ | |||
50490 50491 50492 50493 50494 50495 50496 | memset((void *)&aPgno[iLimit+1], 0, nByte); #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT /* Verify that the every entry in the mapping region is still reachable ** via the hash table even after the cleanup. */ if( iLimit ){ | | | | | | | 50554 50555 50556 50557 50558 50559 50560 50561 50562 50563 50564 50565 50566 50567 50568 50569 50570 50571 50572 50573 50574 | memset((void *)&aPgno[iLimit+1], 0, nByte); #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT /* Verify that the every entry in the mapping region is still reachable ** via the hash table even after the cleanup. */ if( iLimit ){ int j; /* Loop counter */ int iKey; /* Hash key */ for(j=1; j<=iLimit; j++){ for(iKey=walHash(aPgno[j]); aHash[iKey]; iKey=walNextHash(iKey)){ if( aHash[iKey]==j ) break; } assert( aHash[iKey]==j ); } } #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */ } /* |
︙ | ︙ | |||
50998 50999 51000 51001 51002 51003 51004 | ht_slot *aList; /* Pointer to sub-list content */ }; const int nList = *pnList; /* Size of input list */ int nMerge = 0; /* Number of elements in list aMerge */ ht_slot *aMerge = 0; /* List to be merged */ int iList; /* Index into input list */ | | | > > | > > | 51062 51063 51064 51065 51066 51067 51068 51069 51070 51071 51072 51073 51074 51075 51076 51077 51078 51079 51080 51081 51082 51083 51084 51085 51086 51087 51088 51089 51090 51091 51092 51093 51094 51095 51096 51097 51098 51099 51100 51101 51102 | ht_slot *aList; /* Pointer to sub-list content */ }; const int nList = *pnList; /* Size of input list */ int nMerge = 0; /* Number of elements in list aMerge */ ht_slot *aMerge = 0; /* List to be merged */ int iList; /* Index into input list */ u32 iSub = 0; /* Index into aSub array */ struct Sublist aSub[13]; /* Array of sub-lists */ memset(aSub, 0, sizeof(aSub)); assert( nList<=HASHTABLE_NPAGE && nList>0 ); assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) ); for(iList=0; iList<nList; iList++){ nMerge = 1; aMerge = &aList[iList]; for(iSub=0; iList & (1<<iSub); iSub++){ struct Sublist *p; assert( iSub<ArraySize(aSub) ); p = &aSub[iSub]; assert( p->aList && p->nList<=(1<<iSub) ); assert( p->aList==&aList[iList&~((2<<iSub)-1)] ); walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer); } aSub[iSub].aList = aMerge; aSub[iSub].nList = nMerge; } for(iSub++; iSub<ArraySize(aSub); iSub++){ if( nList & (1<<iSub) ){ struct Sublist *p; assert( iSub<ArraySize(aSub) ); p = &aSub[iSub]; assert( p->nList<=(1<<iSub) ); assert( p->aList==&aList[nList&~((2<<iSub)-1)] ); walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer); } } assert( aMerge==aList ); *pnList = nMerge; |
︙ | ︙ | |||
52931 52932 52933 52934 52935 52936 52937 52938 52939 52940 52941 52942 52943 52944 | ** unspecified. A trunk page looks like this: ** ** SIZE DESCRIPTION ** 4 Page number of next trunk page ** 4 Number of leaf pointers on this page ** * zero or more pages numbers of leaves */ /* The following value is the maximum cell size assuming a maximum page ** size give above. */ #define MX_CELL_SIZE(pBt) ((int)(pBt->pageSize-8)) | > | 52999 53000 53001 53002 53003 53004 53005 53006 53007 53008 53009 53010 53011 53012 53013 | ** unspecified. A trunk page looks like this: ** ** SIZE DESCRIPTION ** 4 Page number of next trunk page ** 4 Number of leaf pointers on this page ** * zero or more pages numbers of leaves */ /* #include "sqliteInt.h" */ /* The following value is the maximum cell size assuming a maximum page ** size give above. */ #define MX_CELL_SIZE(pBt) ((int)(pBt->pageSize-8)) |
︙ | ︙ | |||
53728 53729 53730 53731 53732 53733 53734 53735 53736 53737 53738 53739 53740 53741 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file implements an external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ /* ** The header string that appears at the beginning of every ** SQLite database. */ static const char zMagicHeader[] = SQLITE_FILE_HEADER; | > | 53797 53798 53799 53800 53801 53802 53803 53804 53805 53806 53807 53808 53809 53810 53811 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file implements an external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ /* #include "btreeInt.h" */ /* ** The header string that appears at the beginning of every ** SQLite database. */ static const char zMagicHeader[] = SQLITE_FILE_HEADER; |
︙ | ︙ | |||
62673 62674 62675 62676 62677 62678 62679 | u32 usableSize; /* Usable size of the page */ u32 contentOffset; /* Offset to the start of the cell content area */ u32 *heap = 0; /* Min-heap used for checking cell coverage */ u32 x, prev = 0; /* Next and previous entry on the min-heap */ const char *saved_zPfx = pCheck->zPfx; int saved_v1 = pCheck->v1; int saved_v2 = pCheck->v2; | | | 62743 62744 62745 62746 62747 62748 62749 62750 62751 62752 62753 62754 62755 62756 62757 | u32 usableSize; /* Usable size of the page */ u32 contentOffset; /* Offset to the start of the cell content area */ u32 *heap = 0; /* Min-heap used for checking cell coverage */ u32 x, prev = 0; /* Next and previous entry on the min-heap */ const char *saved_zPfx = pCheck->zPfx; int saved_v1 = pCheck->v1; int saved_v2 = pCheck->v2; u8 savedIsInit = 0; /* Check that the page exists */ pBt = pCheck->pBt; usableSize = pBt->usableSize; if( iPage==0 ) return 0; if( checkRef(pCheck, iPage) ) return 0; |
︙ | ︙ | |||
63309 63310 63311 63312 63313 63314 63315 63316 63317 63318 63319 63320 63321 63322 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_backup_XXX() ** API functions and the related features. */ /* ** Structure allocated for each backup operation. */ struct sqlite3_backup { sqlite3* pDestDb; /* Destination database handle */ Btree *pDest; /* Destination b-tree file */ | > > | 63379 63380 63381 63382 63383 63384 63385 63386 63387 63388 63389 63390 63391 63392 63393 63394 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_backup_XXX() ** API functions and the related features. */ /* #include "sqliteInt.h" */ /* #include "btreeInt.h" */ /* ** Structure allocated for each backup operation. */ struct sqlite3_backup { sqlite3* pDestDb; /* Destination database handle */ Btree *pDest; /* Destination b-tree file */ |
︙ | ︙ | |||
64107 64108 64109 64110 64111 64112 64113 64114 64115 64116 64117 64118 64119 64120 | ************************************************************************* ** ** This file contains code use to manipulate "Mem" structure. A "Mem" ** stores a single value in the VDBE. Mem is an opaque structure visible ** only within the VDBE. Interface routines refer to a Mem using the ** name sqlite_value */ #ifdef SQLITE_DEBUG /* ** Check invariants on a Mem object. ** ** This routine is intended for use inside of assert() statements, like ** this: assert( sqlite3VdbeCheckMemInvariants(pMem) ); | > > | 64179 64180 64181 64182 64183 64184 64185 64186 64187 64188 64189 64190 64191 64192 64193 64194 | ************************************************************************* ** ** This file contains code use to manipulate "Mem" structure. A "Mem" ** stores a single value in the VDBE. Mem is an opaque structure visible ** only within the VDBE. Interface routines refer to a Mem using the ** name sqlite_value */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ #ifdef SQLITE_DEBUG /* ** Check invariants on a Mem object. ** ** This routine is intended for use inside of assert() statements, like ** this: assert( sqlite3VdbeCheckMemInvariants(pMem) ); |
︙ | ︙ | |||
65824 65825 65826 65827 65828 65829 65830 65831 65832 65833 65834 65835 65836 65837 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) */ /* ** Create a new virtual database engine. */ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ sqlite3 *db = pParse->db; Vdbe *p; | > > | 65898 65899 65900 65901 65902 65903 65904 65905 65906 65907 65908 65909 65910 65911 65912 65913 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ /* ** Create a new virtual database engine. */ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ sqlite3 *db = pParse->db; Vdbe *p; |
︙ | ︙ | |||
70072 70073 70074 70075 70076 70077 70078 70079 70080 70081 70082 70083 70084 70085 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. */ #ifndef SQLITE_OMIT_DEPRECATED /* ** Return TRUE (non-zero) of the statement supplied as an argument needs ** to be recompiled. A statement needs to be recompiled whenever the ** execution environment changes in a way that would alter the program ** that sqlite3_prepare() generates. For example, if new functions or | > > | 70148 70149 70150 70151 70152 70153 70154 70155 70156 70157 70158 70159 70160 70161 70162 70163 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ #ifndef SQLITE_OMIT_DEPRECATED /* ** Return TRUE (non-zero) of the statement supplied as an argument needs ** to be recompiled. A statement needs to be recompiled whenever the ** execution environment changes in a way that would alter the program ** that sqlite3_prepare() generates. For example, if new functions or |
︙ | ︙ | |||
70110 70111 70112 70113 70114 70115 70116 70117 70118 70119 70120 70121 70122 70123 70124 70125 70126 70127 70128 70129 70130 70131 70132 70133 70134 70135 70136 70137 70138 70139 70140 70141 70142 70143 | sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement"); return 1; }else{ return vdbeSafety(p); } } /* ** The following routine destroys a virtual machine that is created by ** the sqlite3_compile() routine. The integer returned is an SQLITE_ ** success/failure code that describes the result of executing the virtual ** machine. ** ** This routine sets the error code and string returned by ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL ** pointer is a harmless no-op. */ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; sqlite3_mutex_enter(db->mutex); rc = sqlite3VdbeFinalize(v); rc = sqlite3ApiExit(db, rc); sqlite3LeaveMutexAndCloseZombie(db); } return rc; } | > > > > > > > > > > > > > > > > > > > > > > > > > > | 70188 70189 70190 70191 70192 70193 70194 70195 70196 70197 70198 70199 70200 70201 70202 70203 70204 70205 70206 70207 70208 70209 70210 70211 70212 70213 70214 70215 70216 70217 70218 70219 70220 70221 70222 70223 70224 70225 70226 70227 70228 70229 70230 70231 70232 70233 70234 70235 70236 70237 70238 70239 70240 70241 70242 70243 70244 70245 70246 70247 | sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement"); return 1; }else{ return vdbeSafety(p); } } #ifndef SQLITE_OMIT_TRACE /* ** Invoke the profile callback. This routine is only called if we already ** know that the profile callback is defined and needs to be invoked. */ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){ sqlite3_int64 iNow; assert( p->startTime>0 ); assert( db->xProfile!=0 ); assert( db->init.busy==0 ); assert( p->zSql!=0 ); sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000); p->startTime = 0; } /* ** The checkProfileCallback(DB,P) macro checks to see if a profile callback ** is needed, and it invokes the callback if it is needed. */ # define checkProfileCallback(DB,P) \ if( ((P)->startTime)>0 ){ invokeProfileCallback(DB,P); } #else # define checkProfileCallback(DB,P) /*no-op*/ #endif /* ** The following routine destroys a virtual machine that is created by ** the sqlite3_compile() routine. The integer returned is an SQLITE_ ** success/failure code that describes the result of executing the virtual ** machine. ** ** This routine sets the error code and string returned by ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL ** pointer is a harmless no-op. */ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; sqlite3_mutex_enter(db->mutex); checkProfileCallback(db, v); rc = sqlite3VdbeFinalize(v); rc = sqlite3ApiExit(db, rc); sqlite3LeaveMutexAndCloseZombie(db); } return rc; } |
︙ | ︙ | |||
70151 70152 70153 70154 70155 70156 70157 | */ SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; | > | > | | | | 70255 70256 70257 70258 70259 70260 70261 70262 70263 70264 70265 70266 70267 70268 70269 70270 70271 70272 70273 70274 70275 70276 | */ SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; sqlite3_mutex_enter(db->mutex); checkProfileCallback(db, v); rc = sqlite3VdbeReset(v); sqlite3VdbeRewind(v); assert( (rc & (db->errMask))==rc ); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); } return rc; } /* ** Set all the parameters in the compiled SQL statement to NULL. */ |
︙ | ︙ | |||
70506 70507 70508 70509 70510 70511 70512 70513 70514 70515 70516 70517 70518 70519 | rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry); } } } #endif return rc; } /* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. ** ** This routine implements the bulk of the logic behind the sqlite_step() ** API. The only thing omitted is the automatic recompile if a | > | 70612 70613 70614 70615 70616 70617 70618 70619 70620 70621 70622 70623 70624 70625 70626 | rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry); } } } #endif return rc; } /* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. ** ** This routine implements the bulk of the logic behind the sqlite_step() ** API. The only thing omitted is the automatic recompile if a |
︙ | ︙ | |||
70575 70576 70577 70578 70579 70580 70581 | } assert( db->nVdbeWrite>0 || db->autoCommit==0 || (db->nDeferredCons==0 && db->nDeferredImmCons==0) ); #ifndef SQLITE_OMIT_TRACE | | > > | 70682 70683 70684 70685 70686 70687 70688 70689 70690 70691 70692 70693 70694 70695 70696 70697 70698 70699 | } assert( db->nVdbeWrite>0 || db->autoCommit==0 || (db->nDeferredCons==0 && db->nDeferredImmCons==0) ); #ifndef SQLITE_OMIT_TRACE if( db->xProfile && !db->init.busy && p->zSql ){ sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); }else{ assert( p->startTime==0 ); } #endif db->nVdbeActive++; if( p->readOnly==0 ) db->nVdbeWrite++; if( p->bIsReader ) db->nVdbeRead++; p->pc = 0; |
︙ | ︙ | |||
70600 70601 70602 70603 70604 70605 70606 | { db->nVdbeExec++; rc = sqlite3VdbeExec(p); db->nVdbeExec--; } #ifndef SQLITE_OMIT_TRACE | | < | < < < < | 70709 70710 70711 70712 70713 70714 70715 70716 70717 70718 70719 70720 70721 70722 70723 70724 | { db->nVdbeExec++; rc = sqlite3VdbeExec(p); db->nVdbeExec--; } #ifndef SQLITE_OMIT_TRACE /* If the statement completed successfully, invoke the profile callback */ if( rc!=SQLITE_ROW ) checkProfileCallback(db, p); #endif if( rc==SQLITE_DONE ){ assert( p->rc==SQLITE_OK ); p->rc = doWalCallbacks(db); if( p->rc!=SQLITE_OK ){ rc = SQLITE_ERROR; |
︙ | ︙ | |||
71683 71684 71685 71686 71687 71688 71689 71690 71691 71692 71693 71694 71695 71696 | ************************************************************************* ** ** This file contains code used to insert the values of host parameters ** (aka "wildcards") into the SQL text output by sqlite3_trace(). ** ** The Vdbe parse-tree explainer is also found here. */ #ifndef SQLITE_OMIT_TRACE /* ** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of ** bytes in this text up to but excluding the first character in ** a host parameter. If the text contains no host parameters, return | > > | 71787 71788 71789 71790 71791 71792 71793 71794 71795 71796 71797 71798 71799 71800 71801 71802 | ************************************************************************* ** ** This file contains code used to insert the values of host parameters ** (aka "wildcards") into the SQL text output by sqlite3_trace(). ** ** The Vdbe parse-tree explainer is also found here. */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ #ifndef SQLITE_OMIT_TRACE /* ** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of ** bytes in this text up to but excluding the first character in ** a host parameter. If the text contains no host parameters, return |
︙ | ︙ | |||
71875 71876 71877 71878 71879 71880 71881 71882 71883 71884 71885 71886 71887 71888 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. */ /* ** Invoke this macro on memory cells just prior to changing the ** value of the cell. This macro verifies that shallow copies are ** not misused. A shallow copy of a string or blob just copies a ** pointer to the string or blob, not the content. If the original ** is changed while the copy is still in use, the string or blob might | > > | 71981 71982 71983 71984 71985 71986 71987 71988 71989 71990 71991 71992 71993 71994 71995 71996 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ /* ** Invoke this macro on memory cells just prior to changing the ** value of the cell. This macro verifies that shallow copies are ** not misused. A shallow copy of a string or blob just copies a ** pointer to the string or blob, not the content. If the original ** is changed while the copy is still in use, the string or blob might |
︙ | ︙ | |||
78633 78634 78635 78636 78637 78638 78639 78640 78641 78642 78643 78644 78645 78646 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code used to implement incremental BLOB I/O. */ #ifndef SQLITE_OMIT_INCRBLOB /* ** Valid sqlite3_blob* handles point to Incrblob structures. */ typedef struct Incrblob Incrblob; | > > | 78741 78742 78743 78744 78745 78746 78747 78748 78749 78750 78751 78752 78753 78754 78755 78756 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code used to implement incremental BLOB I/O. */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ #ifndef SQLITE_OMIT_INCRBLOB /* ** Valid sqlite3_blob* handles point to Incrblob structures. */ typedef struct Incrblob Incrblob; |
︙ | ︙ | |||
79231 79232 79233 79234 79235 79236 79237 79238 79239 79240 79241 79242 79243 79244 | ** If running in multi-threaded mode and there are more than ** SORTER_MAX_MERGE_COUNT PMAs on disk when Rewind() is called, then more ** than one background thread may be created. Specifically, there may be ** one background thread for each temporary file on disk, and one background ** thread to merge the output of each of the others to a single PMA for ** the main thread to read from. */ /* ** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various ** messages to stderr that may be helpful in understanding the performance ** characteristics of the sorter in multi-threaded mode. */ #if 0 | > > | 79341 79342 79343 79344 79345 79346 79347 79348 79349 79350 79351 79352 79353 79354 79355 79356 | ** If running in multi-threaded mode and there are more than ** SORTER_MAX_MERGE_COUNT PMAs on disk when Rewind() is called, then more ** than one background thread may be created. Specifically, there may be ** one background thread for each temporary file on disk, and one background ** thread to merge the output of each of the others to a single PMA for ** the main thread to read from. */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ /* ** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various ** messages to stderr that may be helpful in understanding the performance ** characteristics of the sorter in multi-threaded mode. */ #if 0 |
︙ | ︙ | |||
81847 81848 81849 81850 81851 81852 81853 81854 81855 81856 81857 81858 81859 81860 | ** on disk is not created or populated until either: ** ** 1) The in-memory representation grows too large for the allocated ** buffer, or ** 2) The sqlite3JournalCreate() function is called. */ #ifdef SQLITE_ENABLE_ATOMIC_WRITE /* ** A JournalFile object is a subclass of sqlite3_file used by ** as an open file handle for journal files. */ struct JournalFile { | > | 81959 81960 81961 81962 81963 81964 81965 81966 81967 81968 81969 81970 81971 81972 81973 | ** on disk is not created or populated until either: ** ** 1) The in-memory representation grows too large for the allocated ** buffer, or ** 2) The sqlite3JournalCreate() function is called. */ #ifdef SQLITE_ENABLE_ATOMIC_WRITE /* #include "sqliteInt.h" */ /* ** A JournalFile object is a subclass of sqlite3_file used by ** as an open file handle for journal files. */ struct JournalFile { |
︙ | ︙ | |||
82094 82095 82096 82097 82098 82099 82100 82101 82102 82103 82104 82105 82106 82107 | ** ************************************************************************* ** ** This file contains code use to implement an in-memory rollback journal. ** The in-memory rollback journal is used to journal transactions for ** ":memory:" databases and when the journal_mode=MEMORY pragma is used. */ /* Forward references to internal structures */ typedef struct MemJournal MemJournal; typedef struct FilePoint FilePoint; typedef struct FileChunk FileChunk; /* Space to hold the rollback journal is allocated in increments of | > | 82207 82208 82209 82210 82211 82212 82213 82214 82215 82216 82217 82218 82219 82220 82221 | ** ************************************************************************* ** ** This file contains code use to implement an in-memory rollback journal. ** The in-memory rollback journal is used to journal transactions for ** ":memory:" databases and when the journal_mode=MEMORY pragma is used. */ /* #include "sqliteInt.h" */ /* Forward references to internal structures */ typedef struct MemJournal MemJournal; typedef struct FilePoint FilePoint; typedef struct FileChunk FileChunk; /* Space to hold the rollback journal is allocated in increments of |
︙ | ︙ | |||
82349 82350 82351 82352 82353 82354 82355 82356 82357 82358 82359 82360 82361 82362 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for walking the parser tree for ** an SQL statement. */ /* #include <stdlib.h> */ /* #include <string.h> */ /* ** Walk an expression tree. Invoke the callback once for each node ** of the expression, while descending. (In other words, the callback | > | 82463 82464 82465 82466 82467 82468 82469 82470 82471 82472 82473 82474 82475 82476 82477 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for walking the parser tree for ** an SQL statement. */ /* #include "sqliteInt.h" */ /* #include <stdlib.h> */ /* #include <string.h> */ /* ** Walk an expression tree. Invoke the callback once for each node ** of the expression, while descending. (In other words, the callback |
︙ | ︙ | |||
82507 82508 82509 82510 82511 82512 82513 82514 82515 82516 82517 82518 82519 82520 | ** ************************************************************************* ** ** This file contains routines used for walking the parser tree and ** resolve all identifiers by associating them with a particular ** table and column. */ /* #include <stdlib.h> */ /* #include <string.h> */ /* ** Walk the expression tree pExpr and increase the aggregate function ** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node. ** This needs to occur when copying a TK_AGG_FUNCTION node from an | > | 82622 82623 82624 82625 82626 82627 82628 82629 82630 82631 82632 82633 82634 82635 82636 | ** ************************************************************************* ** ** This file contains routines used for walking the parser tree and ** resolve all identifiers by associating them with a particular ** table and column. */ /* #include "sqliteInt.h" */ /* #include <stdlib.h> */ /* #include <string.h> */ /* ** Walk the expression tree pExpr and increase the aggregate function ** depth (the Expr.op2 field) by N on every TK_AGG_FUNCTION node. ** This needs to occur when copying a TK_AGG_FUNCTION node from an |
︙ | ︙ | |||
84019 84020 84021 84022 84023 84024 84025 84026 84027 84028 84029 84030 84031 84032 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. */ /* ** Return the 'affinity' of the expression pExpr if any. ** ** If pExpr is a column, a reference to a column via an 'AS' alias, ** or a sub-select with a column as the return value, then the ** affinity of that column is returned. Otherwise, 0x00 is returned, | > | 84135 84136 84137 84138 84139 84140 84141 84142 84143 84144 84145 84146 84147 84148 84149 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. */ /* #include "sqliteInt.h" */ /* ** Return the 'affinity' of the expression pExpr if any. ** ** If pExpr is a column, a reference to a column via an 'AS' alias, ** or a sub-select with a column as the return value, then the ** affinity of that column is returned. Otherwise, 0x00 is returned, |
︙ | ︙ | |||
88181 88182 88183 88184 88185 88186 88187 88188 88189 88190 88191 88192 88193 88194 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that used to generate VDBE code ** that implements the ALTER TABLE command. */ /* ** The code in this file only exists if we are not omitting the ** ALTER TABLE logic from the build. */ #ifndef SQLITE_OMIT_ALTERTABLE | > | 88298 88299 88300 88301 88302 88303 88304 88305 88306 88307 88308 88309 88310 88311 88312 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that used to generate VDBE code ** that implements the ALTER TABLE command. */ /* #include "sqliteInt.h" */ /* ** The code in this file only exists if we are not omitting the ** ALTER TABLE logic from the build. */ #ifndef SQLITE_OMIT_ALTERTABLE |
︙ | ︙ | |||
89143 89144 89145 89146 89147 89148 89149 89150 89151 89152 89153 89154 89155 89156 | ** column contains the actual value of the left-most column instead ** of a blob encoding of the complete index key as is found in ** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3 ** all contain just a single integer which is the same as the first ** integer in the equivalent columns in sqlite_stat4. */ #ifndef SQLITE_OMIT_ANALYZE #if defined(SQLITE_ENABLE_STAT4) # define IsStat4 1 # define IsStat3 0 #elif defined(SQLITE_ENABLE_STAT3) # define IsStat4 0 # define IsStat3 1 | > | 89261 89262 89263 89264 89265 89266 89267 89268 89269 89270 89271 89272 89273 89274 89275 | ** column contains the actual value of the left-most column instead ** of a blob encoding of the complete index key as is found in ** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3 ** all contain just a single integer which is the same as the first ** integer in the equivalent columns in sqlite_stat4. */ #ifndef SQLITE_OMIT_ANALYZE /* #include "sqliteInt.h" */ #if defined(SQLITE_ENABLE_STAT4) # define IsStat4 1 # define IsStat3 0 #elif defined(SQLITE_ENABLE_STAT3) # define IsStat4 0 # define IsStat3 1 |
︙ | ︙ | |||
90908 90909 90910 90911 90912 90913 90914 90915 90916 90917 90918 90919 90920 90921 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. */ #ifndef SQLITE_OMIT_ATTACH /* ** Resolve an expression that was part of an ATTACH or DETACH statement. This ** is slightly different from resolving a normal SQL expression, because simple ** identifiers are treated as strings, not possible column names or aliases. ** | > | 91027 91028 91029 91030 91031 91032 91033 91034 91035 91036 91037 91038 91039 91040 91041 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. */ /* #include "sqliteInt.h" */ #ifndef SQLITE_OMIT_ATTACH /* ** Resolve an expression that was part of an ATTACH or DETACH statement. This ** is slightly different from resolving a normal SQL expression, because simple ** identifiers are treated as strings, not possible column names or aliases. ** |
︙ | ︙ | |||
91497 91498 91499 91500 91501 91502 91503 91504 91505 91506 91507 91508 91509 91510 | ** ************************************************************************* ** This file contains code used to implement the sqlite3_set_authorizer() ** API. This facility is an optional feature of the library. Embedded ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 */ /* ** All of the code in this file may be omitted by defining a single ** macro. */ #ifndef SQLITE_OMIT_AUTHORIZATION | > | 91617 91618 91619 91620 91621 91622 91623 91624 91625 91626 91627 91628 91629 91630 91631 | ** ************************************************************************* ** This file contains code used to implement the sqlite3_set_authorizer() ** API. This facility is an optional feature of the library. Embedded ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 */ /* #include "sqliteInt.h" */ /* ** All of the code in this file may be omitted by defining a single ** macro. */ #ifndef SQLITE_OMIT_AUTHORIZATION |
︙ | ︙ | |||
91767 91768 91769 91770 91771 91772 91773 91774 91775 91776 91777 91778 91779 91780 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK */ /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. */ SQLITE_PRIVATE void sqlite3BeginParse(Parse *pParse, int explainFlag){ pParse->explain = (u8)explainFlag; | > | 91888 91889 91890 91891 91892 91893 91894 91895 91896 91897 91898 91899 91900 91901 91902 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK */ /* #include "sqliteInt.h" */ /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Initialize the pParse structure as needed. */ SQLITE_PRIVATE void sqlite3BeginParse(Parse *pParse, int explainFlag){ pParse->explain = (u8)explainFlag; |
︙ | ︙ | |||
96087 96088 96089 96090 96091 96092 96093 96094 96095 96096 96097 96098 96099 96100 | ** ************************************************************************* ** ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. */ /* ** Invoke the 'collation needed' callback to request a collation sequence ** in the encoding enc of name zName, length nName. */ static void callCollNeeded(sqlite3 *db, int enc, const char *zName){ assert( !db->xCollNeeded || !db->xCollNeeded16 ); | > | 96209 96210 96211 96212 96213 96214 96215 96216 96217 96218 96219 96220 96221 96222 96223 | ** ************************************************************************* ** ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. */ /* #include "sqliteInt.h" */ /* ** Invoke the 'collation needed' callback to request a collation sequence ** in the encoding enc of name zName, length nName. */ static void callCollNeeded(sqlite3 *db, int enc, const char *zName){ assert( !db->xCollNeeded || !db->xCollNeeded16 ); |
︙ | ︙ | |||
96564 96565 96566 96567 96568 96569 96570 96571 96572 96573 96574 96575 96576 96577 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. */ /* ** While a SrcList can in general represent multiple tables and subqueries ** (as in the FROM clause of a SELECT statement) in this case it contains ** the name of a single table, as one might find in an INSERT, DELETE, ** or UPDATE statement. Look up that table in the symbol table and ** return a pointer. Set an error message and return NULL if the table | > | 96687 96688 96689 96690 96691 96692 96693 96694 96695 96696 96697 96698 96699 96700 96701 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. */ /* #include "sqliteInt.h" */ /* ** While a SrcList can in general represent multiple tables and subqueries ** (as in the FROM clause of a SELECT statement) in this case it contains ** the name of a single table, as one might find in an INSERT, DELETE, ** or UPDATE statement. Look up that table in the symbol table and ** return a pointer. Set an error message and return NULL if the table |
︙ | ︙ | |||
97406 97407 97408 97409 97410 97411 97412 97413 97414 97415 97416 97417 97418 97419 97420 97421 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C-language implementations for many of the SQL ** functions of SQLite. (Some function, and in particular the date and ** time functions, are implemented separately.) */ /* #include <stdlib.h> */ /* #include <assert.h> */ /* ** Return the collating function associated with a function. */ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ VdbeOp *pOp; assert( context->pVdbe!=0 ); | > > | 97530 97531 97532 97533 97534 97535 97536 97537 97538 97539 97540 97541 97542 97543 97544 97545 97546 97547 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C-language implementations for many of the SQL ** functions of SQLite. (Some function, and in particular the date and ** time functions, are implemented separately.) */ /* #include "sqliteInt.h" */ /* #include <stdlib.h> */ /* #include <assert.h> */ /* #include "vdbeInt.h" */ /* ** Return the collating function associated with a function. */ static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ VdbeOp *pOp; assert( context->pVdbe!=0 ); |
︙ | ︙ | |||
99203 99204 99205 99206 99207 99208 99209 99210 99211 99212 99213 99214 99215 99216 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used by the compiler to add foreign key ** support to compiled SQL statements. */ #ifndef SQLITE_OMIT_FOREIGN_KEY #ifndef SQLITE_OMIT_TRIGGER /* ** Deferred and Immediate FKs ** -------------------------- | > | 99329 99330 99331 99332 99333 99334 99335 99336 99337 99338 99339 99340 99341 99342 99343 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used by the compiler to add foreign key ** support to compiled SQL statements. */ /* #include "sqliteInt.h" */ #ifndef SQLITE_OMIT_FOREIGN_KEY #ifndef SQLITE_OMIT_TRIGGER /* ** Deferred and Immediate FKs ** -------------------------- |
︙ | ︙ | |||
100607 100608 100609 100610 100611 100612 100613 100614 100615 100616 100617 100618 100619 100620 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. */ /* ** Generate code that will ** ** (1) acquire a lock for table pTab then ** (2) open pTab as cursor iCur. ** | > | 100734 100735 100736 100737 100738 100739 100740 100741 100742 100743 100744 100745 100746 100747 100748 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. */ /* #include "sqliteInt.h" */ /* ** Generate code that will ** ** (1) acquire a lock for table pTab then ** (2) open pTab as cursor iCur. ** |
︙ | ︙ | |||
102669 102670 102671 102672 102673 102674 102675 102676 102677 102678 102679 102680 102681 102682 | ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. */ /* ** Execute SQL code. Return one of the SQLITE_ success/failure ** codes. Also write an error message into memory obtained from ** malloc() and make *pzErrMsg point to that message. ** ** If the SQL is a query, then for each row in the query result | > | 102797 102798 102799 102800 102801 102802 102803 102804 102805 102806 102807 102808 102809 102810 102811 | ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. */ /* #include "sqliteInt.h" */ /* ** Execute SQL code. Return one of the SQLITE_ success/failure ** codes. Also write an error message into memory obtained from ** malloc() and make *pzErrMsg point to that message. ** ** If the SQL is a query, then for each row in the query result |
︙ | ︙ | |||
102837 102838 102839 102840 102841 102842 102843 102844 102845 102846 102847 102848 102849 102850 | ** shared libraries that want to be imported as extensions into ** an SQLite instance. Shared libraries that intend to be loaded ** as extensions by SQLite should #include this file instead of ** sqlite3.h. */ #ifndef _SQLITE3EXT_H_ #define _SQLITE3EXT_H_ typedef struct sqlite3_api_routines sqlite3_api_routines; /* ** The following structure holds pointers to all of the SQLite API ** routines. ** | > | 102966 102967 102968 102969 102970 102971 102972 102973 102974 102975 102976 102977 102978 102979 102980 | ** shared libraries that want to be imported as extensions into ** an SQLite instance. Shared libraries that intend to be loaded ** as extensions by SQLite should #include this file instead of ** sqlite3.h. */ #ifndef _SQLITE3EXT_H_ #define _SQLITE3EXT_H_ /* #include "sqlite3.h" */ typedef struct sqlite3_api_routines sqlite3_api_routines; /* ** The following structure holds pointers to all of the SQLite API ** routines. ** |
︙ | ︙ | |||
103343 103344 103345 103346 103347 103348 103349 103350 103351 103352 103353 103354 103355 103356 | # define SQLITE_EXTENSION_INIT3 /*no-op*/ #endif #endif /* _SQLITE3EXT_H_ */ /************** End of sqlite3ext.h ******************************************/ /************** Continuing where we left off in loadext.c ********************/ /* #include <string.h> */ #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Some API routines are omitted when various features are ** excluded from a build of SQLite. Substitute a NULL pointer | > | 103473 103474 103475 103476 103477 103478 103479 103480 103481 103482 103483 103484 103485 103486 103487 | # define SQLITE_EXTENSION_INIT3 /*no-op*/ #endif #endif /* _SQLITE3EXT_H_ */ /************** End of sqlite3ext.h ******************************************/ /************** Continuing where we left off in loadext.c ********************/ /* #include "sqliteInt.h" */ /* #include <string.h> */ #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Some API routines are omitted when various features are ** excluded from a build of SQLite. Substitute a NULL pointer |
︙ | ︙ | |||
104112 104113 104114 104115 104116 104117 104118 104119 104120 104121 104122 104123 104124 104125 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. */ #if !defined(SQLITE_ENABLE_LOCKING_STYLE) # if defined(__APPLE__) # define SQLITE_ENABLE_LOCKING_STYLE 1 # else # define SQLITE_ENABLE_LOCKING_STYLE 0 # endif | > | 104243 104244 104245 104246 104247 104248 104249 104250 104251 104252 104253 104254 104255 104256 104257 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. */ /* #include "sqliteInt.h" */ #if !defined(SQLITE_ENABLE_LOCKING_STYLE) # if defined(__APPLE__) # define SQLITE_ENABLE_LOCKING_STYLE 1 # else # define SQLITE_ENABLE_LOCKING_STYLE 0 # endif |
︙ | ︙ | |||
104218 104219 104220 104221 104222 104223 104224 | { /* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlag: */ 0, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) { /* zName: */ "cache_size", /* ePragTyp: */ PragTyp_CACHE_SIZE, | | | 104350 104351 104352 104353 104354 104355 104356 104357 104358 104359 104360 104361 104362 104363 104364 | { /* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlag: */ 0, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) { /* zName: */ "cache_size", /* ePragTyp: */ PragTyp_CACHE_SIZE, /* ePragFlag: */ 0, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) { /* zName: */ "cache_spill", /* ePragTyp: */ PragTyp_FLAG, /* ePragFlag: */ 0, /* iArg: */ SQLITE_CacheSpill }, |
︙ | ︙ | |||
105288 105289 105290 105291 105292 105293 105294 105295 105296 105297 105298 105299 105300 105301 | ** number of pages in the cache. If N is negative, then the ** number of pages is adjusted so that the cache uses -N kibibytes ** of memory. */ case PragTyp_CACHE_SIZE: { assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !zRight ){ returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); }else{ int size = sqlite3Atoi(zRight); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } break; | > | 105420 105421 105422 105423 105424 105425 105426 105427 105428 105429 105430 105431 105432 105433 105434 | ** number of pages in the cache. If N is negative, then the ** number of pages is adjusted so that the cache uses -N kibibytes ** of memory. */ case PragTyp_CACHE_SIZE: { assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !zRight ){ if( sqlite3ReadSchema(pParse) ) goto pragma_out; returnSingleInt(pParse, "cache_size", pDb->pSchema->cache_size); }else{ int size = sqlite3Atoi(zRight); pDb->pSchema->cache_size = size; sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } break; |
︙ | ︙ | |||
106563 106564 106565 106566 106567 106568 106569 106570 106571 106572 106573 106574 106575 106576 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. */ /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. */ static void corruptSchema( InitData *pData, /* Initialization context */ | > | 106696 106697 106698 106699 106700 106701 106702 106703 106704 106705 106706 106707 106708 106709 106710 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. */ /* #include "sqliteInt.h" */ /* ** Fill the InitData structure with an error message that indicates ** that the database is corrupt. */ static void corruptSchema( InitData *pData, /* Initialization context */ |
︙ | ︙ | |||
107457 107458 107459 107460 107461 107462 107463 107464 107465 107466 107467 107468 107469 107470 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. */ /* ** Trace output macros */ #if SELECTTRACE_ENABLED /***/ int sqlite3SelectTrace = 0; # define SELECTTRACE(K,P,S,X) \ | > | 107591 107592 107593 107594 107595 107596 107597 107598 107599 107600 107601 107602 107603 107604 107605 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. */ /* #include "sqliteInt.h" */ /* ** Trace output macros */ #if SELECTTRACE_ENABLED /***/ int sqlite3SelectTrace = 0; # define SELECTTRACE(K,P,S,X) \ |
︙ | ︙ | |||
108526 108527 108528 108529 108530 108531 108532 | pInfo->aColl[i-iStart] = pColl; pInfo->aSortOrder[i-iStart] = pItem->sortOrder; } } return pInfo; } | < < | 108661 108662 108663 108664 108665 108666 108667 108668 108669 108670 108671 108672 108673 108674 108675 108676 108677 108678 108679 108680 108681 108682 108683 108684 108685 108686 108687 | pInfo->aColl[i-iStart] = pColl; pInfo->aSortOrder[i-iStart] = pItem->sortOrder; } } return pInfo; } /* ** Name of the connection operator, used for error messages. */ static const char *selectOpName(int id){ char *z; switch( id ){ case TK_ALL: z = "UNION ALL"; break; case TK_INTERSECT: z = "INTERSECT"; break; case TK_EXCEPT: z = "EXCEPT"; break; default: z = "UNION"; break; } return z; } #ifndef SQLITE_OMIT_EXPLAIN /* ** Unless an "EXPLAIN QUERY PLAN" command is being processed, this function ** is a no-op. Otherwise, it adds a single row of output to the EQP result, ** where the caption is of the form: ** |
︙ | ︙ | |||
109543 109544 109545 109546 109547 109548 109549 | /* Forward references */ static int multiSelectOrderBy( Parse *pParse, /* Parsing context */ Select *p, /* The right-most of SELECTs to be coded */ SelectDest *pDest /* What to do with query results */ ); | < < < < < < < < < < < < < | 109676 109677 109678 109679 109680 109681 109682 109683 109684 109685 109686 109687 109688 109689 | /* Forward references */ static int multiSelectOrderBy( Parse *pParse, /* Parsing context */ Select *p, /* The right-most of SELECTs to be coded */ SelectDest *pDest /* What to do with query results */ ); /* ** Handle the special case of a compound-select that originates from a ** VALUES clause. By handling this as a special case, we avoid deep ** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT ** on a VALUES clause. ** ** Because the Select object originates from a VALUES clause: |
︙ | ︙ | |||
109981 109982 109983 109984 109985 109986 109987 109988 109989 109990 109991 109992 109993 109994 | multi_select_end: pDest->iSdst = dest.iSdst; pDest->nSdst = dest.nSdst; sqlite3SelectDelete(db, pDelete); return rc; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ /* ** Code an output subroutine for a coroutine implementation of a ** SELECT statment. ** ** The data to be output is contained in pIn->iSdst. There are ** pIn->nSdst columns to be output. pDest is where the output should | > > > > > > > > > > > > > | 110101 110102 110103 110104 110105 110106 110107 110108 110109 110110 110111 110112 110113 110114 110115 110116 110117 110118 110119 110120 110121 110122 110123 110124 110125 110126 110127 | multi_select_end: pDest->iSdst = dest.iSdst; pDest->nSdst = dest.nSdst; sqlite3SelectDelete(db, pDelete); return rc; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ /* ** Error message for when two or more terms of a compound select have different ** size result sets. */ SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ if( p->selFlags & SF_Values ){ sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); }else{ sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" " do not have the same number of result columns", selectOpName(p->op)); } } /* ** Code an output subroutine for a coroutine implementation of a ** SELECT statment. ** ** The data to be output is contained in pIn->iSdst. There are ** pIn->nSdst columns to be output. pDest is where the output should |
︙ | ︙ | |||
113075 113076 113077 113078 113079 113080 113081 113082 113083 113084 113085 113086 113087 113088 | ** This file contains the sqlite3_get_table() and sqlite3_free_table() ** interface routines. These are just wrappers around the main ** interface routine of sqlite3_exec(). ** ** These routines are in a separate files so that they will not be linked ** if they are not used. */ /* #include <stdlib.h> */ /* #include <string.h> */ #ifndef SQLITE_OMIT_GET_TABLE /* ** This structure is used to pass data from sqlite3_get_table() through | > | 113208 113209 113210 113211 113212 113213 113214 113215 113216 113217 113218 113219 113220 113221 113222 | ** This file contains the sqlite3_get_table() and sqlite3_free_table() ** interface routines. These are just wrappers around the main ** interface routine of sqlite3_exec(). ** ** These routines are in a separate files so that they will not be linked ** if they are not used. */ /* #include "sqliteInt.h" */ /* #include <stdlib.h> */ /* #include <string.h> */ #ifndef SQLITE_OMIT_GET_TABLE /* ** This structure is used to pass data from sqlite3_get_table() through |
︙ | ︙ | |||
113271 113272 113273 113274 113275 113276 113277 113278 113279 113280 113281 113282 113283 113284 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation for TRIGGERs */ #ifndef SQLITE_OMIT_TRIGGER /* ** Delete a linked list of TriggerStep structures. */ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){ while( pTriggerStep ){ | > | 113405 113406 113407 113408 113409 113410 113411 113412 113413 113414 113415 113416 113417 113418 113419 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the implementation for TRIGGERs */ /* #include "sqliteInt.h" */ #ifndef SQLITE_OMIT_TRIGGER /* ** Delete a linked list of TriggerStep structures. */ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerStep){ while( pTriggerStep ){ |
︙ | ︙ | |||
114394 114395 114396 114397 114398 114399 114400 114401 114402 114403 114404 114405 114406 114407 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ static void updateVirtualTable( Parse *pParse, /* The parsing context */ SrcList *pSrc, /* The virtual table to be modified */ Table *pTab, /* The virtual table */ | > | 114529 114530 114531 114532 114533 114534 114535 114536 114537 114538 114539 114540 114541 114542 114543 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. */ /* #include "sqliteInt.h" */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Forward declaration */ static void updateVirtualTable( Parse *pParse, /* The parsing context */ SrcList *pSrc, /* The virtual table to be modified */ Table *pTab, /* The virtual table */ |
︙ | ︙ | |||
115170 115171 115172 115173 115174 115175 115176 115177 115178 115179 115180 115181 115182 115183 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. */ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) /* ** Finalize a prepared statement. If there was an error, store the ** text of the error message in *pzErrMsg. Return the result code. */ static int vacuumFinalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){ | > > | 115306 115307 115308 115309 115310 115311 115312 115313 115314 115315 115316 115317 115318 115319 115320 115321 | ** ************************************************************************* ** This file contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) /* ** Finalize a prepared statement. If there was an error, store the ** text of the error message in *pzErrMsg. Return the result code. */ static int vacuumFinalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){ |
︙ | ︙ | |||
115542 115543 115544 115545 115546 115547 115548 115549 115550 115551 115552 115553 115554 115555 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to help implement virtual tables. */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Before a virtual table xCreate() or xConnect() method is invoked, the ** sqlite3.pVtabCtx member variable is set to point to an instance of ** this struct allocated on the stack. It is used by the implementation of ** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which ** are invoked only from within xCreate and xConnect methods. | > | 115680 115681 115682 115683 115684 115685 115686 115687 115688 115689 115690 115691 115692 115693 115694 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to help implement virtual tables. */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* #include "sqliteInt.h" */ /* ** Before a virtual table xCreate() or xConnect() method is invoked, the ** sqlite3.pVtabCtx member variable is set to point to an instance of ** this struct allocated on the stack. It is used by the implementation of ** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which ** are invoked only from within xCreate and xConnect methods. |
︙ | ︙ | |||
116700 116701 116702 116703 116704 116705 116706 116707 116708 116709 116710 116711 116712 116713 | ** the WHERE clause of SQL statements. ** ** This file was split off from where.c on 2015-06-06 in order to reduce the ** size of where.c and make it easier to edit. This file contains the routines ** that actually generate the bulk of the WHERE loop code. The original where.c ** file retains the code that does query planning and analysis. */ /************** Include whereInt.h in the middle of wherecode.c **************/ /************** Begin file whereInt.h ****************************************/ /* ** 2013-11-12 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: | > | 116839 116840 116841 116842 116843 116844 116845 116846 116847 116848 116849 116850 116851 116852 116853 | ** the WHERE clause of SQL statements. ** ** This file was split off from where.c on 2015-06-06 in order to reduce the ** size of where.c and make it easier to edit. This file contains the routines ** that actually generate the bulk of the WHERE loop code. The original where.c ** file retains the code that does query planning and analysis. */ /* #include "sqliteInt.h" */ /************** Include whereInt.h in the middle of wherecode.c **************/ /************** Begin file whereInt.h ****************************************/ /* ** 2013-11-12 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: |
︙ | ︙ | |||
118511 118512 118513 118514 118515 118516 118517 | int nPk = pPk->nKeyCol; int iPk; /* Read the PK into an array of temp registers. */ r = sqlite3GetTempRange(pParse, nPk); for(iPk=0; iPk<nPk; iPk++){ int iCol = pPk->aiColumn[iPk]; | > | > > > | 118651 118652 118653 118654 118655 118656 118657 118658 118659 118660 118661 118662 118663 118664 118665 118666 118667 118668 118669 | int nPk = pPk->nKeyCol; int iPk; /* Read the PK into an array of temp registers. */ r = sqlite3GetTempRange(pParse, nPk); for(iPk=0; iPk<nPk; iPk++){ int iCol = pPk->aiColumn[iPk]; int rx; rx = sqlite3ExprCodeGetColumn(pParse, pTab, iCol, iCur,r+iPk,0); if( rx!=r+iPk ){ sqlite3VdbeAddOp2(v, OP_SCopy, rx, r+iPk); } } /* Check if the temp table already contains this key. If so, ** the row has already been included in the result set and ** can be ignored (by jumping past the Gosub below). Otherwise, ** insert the key into the temp table and proceed with processing ** the row. |
︙ | ︙ | |||
118735 118736 118737 118738 118739 118740 118741 118742 118743 118744 118745 118746 118747 118748 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** ** This file was originally part of where.c but was split out to improve ** readability and editabiliity. This file contains utility routines for ** analyzing Expr objects in the WHERE clause. */ /* Forward declarations */ static void exprAnalyze(SrcList*, WhereClause*, int); /* ** Deallocate all memory associated with a WhereOrInfo object. */ | > > | 118879 118880 118881 118882 118883 118884 118885 118886 118887 118888 118889 118890 118891 118892 118893 118894 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** ** This file was originally part of where.c but was split out to improve ** readability and editabiliity. This file contains utility routines for ** analyzing Expr objects in the WHERE clause. */ /* #include "sqliteInt.h" */ /* #include "whereInt.h" */ /* Forward declarations */ static void exprAnalyze(SrcList*, WhereClause*, int); /* ** Deallocate all memory associated with a WhereOrInfo object. */ |
︙ | ︙ | |||
119985 119986 119987 119988 119989 119990 119991 119992 119993 119994 119995 119996 119997 119998 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is responsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". */ /* Forward declaration of methods */ static int whereLoopResize(sqlite3*, WhereLoop*, int); /* Test variable that can be set to enable WHERE tracing */ #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) /***/ int sqlite3WhereTrace = 0; | > > | 120131 120132 120133 120134 120135 120136 120137 120138 120139 120140 120141 120142 120143 120144 120145 120146 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is responsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". */ /* #include "sqliteInt.h" */ /* #include "whereInt.h" */ /* Forward declaration of methods */ static int whereLoopResize(sqlite3*, WhereLoop*, int); /* Test variable that can be set to enable WHERE tracing */ #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) /***/ int sqlite3WhereTrace = 0; |
︙ | ︙ | |||
124484 124485 124486 124487 124488 124489 124490 124491 124492 124493 124494 124495 124496 124497 | ** LALR(1) grammar but which are always false in the ** specific grammar used by SQLite. */ /* First off, code is included that follows the "include" declaration ** in the input grammar file. */ /* #include <stdio.h> */ /* ** Disable all error recovery processing in the parser push-down ** automaton. */ #define YYNOERRORRECOVERY 1 | > | 124632 124633 124634 124635 124636 124637 124638 124639 124640 124641 124642 124643 124644 124645 124646 | ** LALR(1) grammar but which are always false in the ** specific grammar used by SQLite. */ /* First off, code is included that follows the "include" declaration ** in the input grammar file. */ /* #include <stdio.h> */ /* #include "sqliteInt.h" */ /* ** Disable all error recovery processing in the parser push-down ** automaton. */ #define YYNOERRORRECOVERY 1 |
︙ | ︙ | |||
128069 128070 128071 128072 128073 128074 128075 128076 128077 128078 128079 128080 128081 128082 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. */ /* #include <stdlib.h> */ /* ** The charMap() macro maps alphabetic characters into their ** lower-case ASCII equivalent. On ASCII machines, this is just ** an upper-to-lower case map. On EBCDIC machines we also need ** to adjust the encoding. Only alphabetic characters and underscores | > | 128218 128219 128220 128221 128222 128223 128224 128225 128226 128227 128228 128229 128230 128231 128232 | ************************************************************************* ** An tokenizer for SQL ** ** This file contains C code that splits an SQL input string up into ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. */ /* #include "sqliteInt.h" */ /* #include <stdlib.h> */ /* ** The charMap() macro maps alphabetic characters into their ** lower-case ASCII equivalent. On ASCII machines, this is just ** an upper-to-lower case map. On EBCDIC machines we also need ** to adjust the encoding. Only alphabetic characters and underscores |
︙ | ︙ | |||
128878 128879 128880 128881 128882 128883 128884 128885 128886 128887 128888 128889 128890 128891 | ** An tokenizer for SQL ** ** This file contains C code that implements the sqlite3_complete() API. ** This code used to be part of the tokenizer.c source file. But by ** separating it out, the code will be automatically omitted from ** static links that do not use it. */ #ifndef SQLITE_OMIT_COMPLETE /* ** This is defined in tokenize.c. We just have to import the definition. */ #ifndef SQLITE_AMALGAMATION #ifdef SQLITE_ASCII | > | 129028 129029 129030 129031 129032 129033 129034 129035 129036 129037 129038 129039 129040 129041 129042 | ** An tokenizer for SQL ** ** This file contains C code that implements the sqlite3_complete() API. ** This code used to be part of the tokenizer.c source file. But by ** separating it out, the code will be automatically omitted from ** static links that do not use it. */ /* #include "sqliteInt.h" */ #ifndef SQLITE_OMIT_COMPLETE /* ** This is defined in tokenize.c. We just have to import the definition. */ #ifndef SQLITE_AMALGAMATION #ifdef SQLITE_ASCII |
︙ | ︙ | |||
129168 129169 129170 129171 129172 129173 129174 129175 129176 129177 129178 129179 129180 129181 129182 129183 129184 129185 129186 129187 129188 129189 129190 129191 129192 129193 129194 129195 129196 129197 129198 129199 129200 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. */ #ifdef SQLITE_ENABLE_FTS3 /************** Include fts3.h in the middle of main.c ***********************/ /************** Begin file fts3.h ********************************************/ /* ** 2006 Oct 10 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This header file is used by programs that want to link against the ** FTS3 library. All it does is declare the sqlite3Fts3Init() interface. */ #if 0 extern "C" { #endif /* __cplusplus */ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db); | > > | 129319 129320 129321 129322 129323 129324 129325 129326 129327 129328 129329 129330 129331 129332 129333 129334 129335 129336 129337 129338 129339 129340 129341 129342 129343 129344 129345 129346 129347 129348 129349 129350 129351 129352 129353 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. */ /* #include "sqliteInt.h" */ #ifdef SQLITE_ENABLE_FTS3 /************** Include fts3.h in the middle of main.c ***********************/ /************** Begin file fts3.h ********************************************/ /* ** 2006 Oct 10 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This header file is used by programs that want to link against the ** FTS3 library. All it does is declare the sqlite3Fts3Init() interface. */ /* #include "sqlite3.h" */ #if 0 extern "C" { #endif /* __cplusplus */ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db); |
︙ | ︙ | |||
129219 129220 129221 129222 129223 129224 129225 129226 129227 129228 129229 129230 129231 129232 | ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This header file is used by programs that want to link against the ** RTREE library. All it does is declare the sqlite3RtreeInit() interface. */ #if 0 extern "C" { #endif /* __cplusplus */ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db); | > | 129372 129373 129374 129375 129376 129377 129378 129379 129380 129381 129382 129383 129384 129385 129386 | ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This header file is used by programs that want to link against the ** RTREE library. All it does is declare the sqlite3RtreeInit() interface. */ /* #include "sqlite3.h" */ #if 0 extern "C" { #endif /* __cplusplus */ SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db); |
︙ | ︙ | |||
129251 129252 129253 129254 129255 129256 129257 129258 129259 129260 129261 129262 129263 129264 | ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This header file is used by programs that want to link against the ** ICU extension. All it does is declare the sqlite3IcuInit() interface. */ #if 0 extern "C" { #endif /* __cplusplus */ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db); | > | 129405 129406 129407 129408 129409 129410 129411 129412 129413 129414 129415 129416 129417 129418 129419 | ** May you share freely, never taking more than you give. ** ****************************************************************************** ** ** This header file is used by programs that want to link against the ** ICU extension. All it does is declare the sqlite3IcuInit() interface. */ /* #include "sqlite3.h" */ #if 0 extern "C" { #endif /* __cplusplus */ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db); |
︙ | ︙ | |||
129883 129884 129885 129886 129887 129888 129889 129890 129891 129892 129893 129894 129895 129896 | ** The sz parameter is the number of bytes in each lookaside slot. ** The cnt parameter is the number of slots. If pStart is NULL the ** space for the lookaside memory is obtained from sqlite3_malloc(). ** If pStart is not NULL then it is sz*cnt bytes of memory to use for ** the lookaside memory. */ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ void *pStart; if( db->lookaside.nOut ){ return SQLITE_BUSY; } /* Free any existing lookaside buffer for this handle before ** allocating a new one so we don't have to have space for ** both at the same time. | > | 130038 130039 130040 130041 130042 130043 130044 130045 130046 130047 130048 130049 130050 130051 130052 | ** The sz parameter is the number of bytes in each lookaside slot. ** The cnt parameter is the number of slots. If pStart is NULL the ** space for the lookaside memory is obtained from sqlite3_malloc(). ** If pStart is not NULL then it is sz*cnt bytes of memory to use for ** the lookaside memory. */ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ #ifndef SQLITE_OMIT_LOOKASIDE void *pStart; if( db->lookaside.nOut ){ return SQLITE_BUSY; } /* Free any existing lookaside buffer for this handle before ** allocating a new one so we don't have to have space for ** both at the same time. |
︙ | ︙ | |||
129933 129934 129935 129936 129937 129938 129939 129940 129941 129942 129943 129944 129945 129946 | db->lookaside.bMalloced = pBuf==0 ?1:0; }else{ db->lookaside.pStart = db; db->lookaside.pEnd = db; db->lookaside.bEnabled = 0; db->lookaside.bMalloced = 0; } return SQLITE_OK; } /* ** Return the mutex associated with a database connection. */ SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){ | > | 130089 130090 130091 130092 130093 130094 130095 130096 130097 130098 130099 130100 130101 130102 130103 | db->lookaside.bMalloced = pBuf==0 ?1:0; }else{ db->lookaside.pStart = db; db->lookaside.pEnd = db; db->lookaside.bEnabled = 0; db->lookaside.bMalloced = 0; } #endif /* SQLITE_OMIT_LOOKASIDE */ return SQLITE_OK; } /* ** Return the mutex associated with a database connection. */ SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){ |
︙ | ︙ | |||
133043 133044 133045 133046 133047 133048 133049 133050 133051 133052 133053 133054 133055 133056 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains the implementation of the sqlite3_unlock_notify() ** API method and its associated functionality. */ /* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY /* ** Public interfaces: ** | > > | 133200 133201 133202 133203 133204 133205 133206 133207 133208 133209 133210 133211 133212 133213 133214 133215 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains the implementation of the sqlite3_unlock_notify() ** API method and its associated functionality. */ /* #include "sqliteInt.h" */ /* #include "btreeInt.h" */ /* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY /* ** Public interfaces: ** |
︙ | ︙ | |||
133686 133687 133688 133689 133690 133691 133692 133693 133694 133695 133696 133697 133698 133699 133700 133701 133702 | # define SQLITE_ENABLE_FTS3 #endif #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* If not building as part of the core, include sqlite3ext.h. */ #ifndef SQLITE_CORE SQLITE_EXTENSION_INIT3 #endif /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/ /************** Begin file fts3_tokenizer.h **********************************/ /* ** 2006 July 10 ** ** The author disclaims copyright to this source code. ** | > > | 133845 133846 133847 133848 133849 133850 133851 133852 133853 133854 133855 133856 133857 133858 133859 133860 133861 133862 133863 | # define SQLITE_ENABLE_FTS3 #endif #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* If not building as part of the core, include sqlite3ext.h. */ #ifndef SQLITE_CORE /* # include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT3 #endif /* #include "sqlite3.h" */ /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/ /************** Begin file fts3_tokenizer.h **********************************/ /* ** 2006 July 10 ** ** The author disclaims copyright to this source code. ** |
︙ | ︙ | |||
133717 133718 133719 133720 133721 133722 133723 133724 133725 133726 133727 133728 133729 133730 | #ifndef _FTS3_TOKENIZER_H_ #define _FTS3_TOKENIZER_H_ /* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. ** If tokenizers are to be allowed to call sqlite3_*() functions, then ** we will need a way to register the API consistently. */ /* ** Structures used by the tokenizer interface. When a new tokenizer ** implementation is registered, the caller provides a pointer to ** an sqlite3_tokenizer_module containing pointers to the callback ** functions that make up an implementation. ** | > | 133878 133879 133880 133881 133882 133883 133884 133885 133886 133887 133888 133889 133890 133891 133892 | #ifndef _FTS3_TOKENIZER_H_ #define _FTS3_TOKENIZER_H_ /* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. ** If tokenizers are to be allowed to call sqlite3_*() functions, then ** we will need a way to register the API consistently. */ /* #include "sqlite3.h" */ /* ** Structures used by the tokenizer interface. When a new tokenizer ** implementation is registered, the caller provides a pointer to ** an sqlite3_tokenizer_module containing pointers to the callback ** functions that make up an implementation. ** |
︙ | ︙ | |||
134557 134558 134559 134560 134561 134562 134563 134564 134565 134566 134567 134568 134569 134570 134571 | /* #include <assert.h> */ /* #include <stdlib.h> */ /* #include <stddef.h> */ /* #include <stdio.h> */ /* #include <string.h> */ /* #include <stdarg.h> */ #ifndef SQLITE_CORE SQLITE_EXTENSION_INIT1 #endif static int fts3EvalNext(Fts3Cursor *pCsr); static int fts3EvalStart(Fts3Cursor *pCsr); static int fts3TermSegReaderCursor( Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); | > > | 134719 134720 134721 134722 134723 134724 134725 134726 134727 134728 134729 134730 134731 134732 134733 134734 134735 | /* #include <assert.h> */ /* #include <stdlib.h> */ /* #include <stddef.h> */ /* #include <stdio.h> */ /* #include <string.h> */ /* #include <stdarg.h> */ /* #include "fts3.h" */ #ifndef SQLITE_CORE /* # include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #endif static int fts3EvalNext(Fts3Cursor *pCsr); static int fts3EvalStart(Fts3Cursor *pCsr); static int fts3TermSegReaderCursor( Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); |
︙ | ︙ | |||
138604 138605 138606 138607 138608 138609 138610 138611 138612 138613 138614 138615 138616 138617 | assert( !p || (p>=aDoclist && p<=&aDoclist[nDoclist]) ); if( p==0 ){ p = aDoclist; p += sqlite3Fts3GetVarint(p, piDocid); }else{ fts3PoslistCopy(0, &p); if( p>=&aDoclist[nDoclist] ){ *pbEof = 1; }else{ sqlite3_int64 iVar; p += sqlite3Fts3GetVarint(p, &iVar); *piDocid += ((bDescIdx ? -1 : 1) * iVar); } | > | 138768 138769 138770 138771 138772 138773 138774 138775 138776 138777 138778 138779 138780 138781 138782 | assert( !p || (p>=aDoclist && p<=&aDoclist[nDoclist]) ); if( p==0 ){ p = aDoclist; p += sqlite3Fts3GetVarint(p, piDocid); }else{ fts3PoslistCopy(0, &p); while( p<&aDoclist[nDoclist] && *p==0 ) p++; if( p>=&aDoclist[nDoclist] ){ *pbEof = 1; }else{ sqlite3_int64 iVar; p += sqlite3Fts3GetVarint(p, &iVar); *piDocid += ((bDescIdx ? -1 : 1) * iVar); } |
︙ | ︙ | |||
140010 140011 140012 140013 140014 140015 140016 | iDocid = pExpr->iDocid; pIter = pPhrase->doclist.pList; if( iDocid!=pCsr->iPrevId || pExpr->bEof ){ int rc = SQLITE_OK; int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ int bOr = 0; | < > | 140175 140176 140177 140178 140179 140180 140181 140182 140183 140184 140185 140186 140187 140188 140189 140190 140191 140192 | iDocid = pExpr->iDocid; pIter = pPhrase->doclist.pList; if( iDocid!=pCsr->iPrevId || pExpr->bEof ){ int rc = SQLITE_OK; int bDescDoclist = pTab->bDescIdx; /* For DOCID_CMP macro */ int bOr = 0; u8 bTreeEof = 0; Fts3Expr *p; /* Used to iterate from pExpr to root */ Fts3Expr *pNear; /* Most senior NEAR ancestor (or pExpr) */ int bMatch; /* Check if this phrase descends from an OR expression node. If not, ** return NULL. Otherwise, the entry that corresponds to docid ** pCsr->iPrevId may lie earlier in the doclist buffer. Or, if the ** tree that the node is part of has been marked as EOF, but the node ** itself is not EOF, then it may point to an earlier entry. */ pNear = pExpr; |
︙ | ︙ | |||
140047 140048 140049 140050 140051 140052 140053 | if( bTreeEof ){ while( rc==SQLITE_OK && !pNear->bEof ){ fts3EvalNextRow(pCsr, pNear, &rc); } } if( rc!=SQLITE_OK ) return rc; | > > > > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | > | > > > > | > | 140212 140213 140214 140215 140216 140217 140218 140219 140220 140221 140222 140223 140224 140225 140226 140227 140228 140229 140230 140231 140232 140233 140234 140235 140236 140237 140238 140239 140240 140241 140242 140243 140244 140245 140246 140247 140248 140249 140250 140251 140252 140253 140254 140255 140256 140257 140258 140259 140260 140261 140262 140263 140264 140265 140266 | if( bTreeEof ){ while( rc==SQLITE_OK && !pNear->bEof ){ fts3EvalNextRow(pCsr, pNear, &rc); } } if( rc!=SQLITE_OK ) return rc; bMatch = 1; for(p=pNear; p; p=p->pLeft){ u8 bEof = 0; Fts3Expr *pTest = p; Fts3Phrase *pPh; assert( pTest->eType==FTSQUERY_NEAR || pTest->eType==FTSQUERY_PHRASE ); if( pTest->eType==FTSQUERY_NEAR ) pTest = pTest->pRight; assert( pTest->eType==FTSQUERY_PHRASE ); pPh = pTest->pPhrase; pIter = pPh->pOrPoslist; iDocid = pPh->iOrDocid; if( pCsr->bDesc==bDescDoclist ){ bEof = !pPh->doclist.nAll || (pIter >= (pPh->doclist.aAll + pPh->doclist.nAll)); while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ sqlite3Fts3DoclistNext( bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, &pIter, &iDocid, &bEof ); } }else{ bEof = !pPh->doclist.nAll || (pIter && pIter<=pPh->doclist.aAll); while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ int dummy; sqlite3Fts3DoclistPrev( bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, &pIter, &iDocid, &dummy, &bEof ); } } pPh->pOrPoslist = pIter; pPh->iOrDocid = iDocid; if( bEof || iDocid!=pCsr->iPrevId ) bMatch = 0; } if( bMatch ){ pIter = pPhrase->pOrPoslist; }else{ pIter = 0; } } if( pIter==0 ) return SQLITE_OK; if( *pIter==0x01 ){ pIter++; pIter += fts3GetVarint32(pIter, &iThis); }else{ |
︙ | ︙ | |||
140159 140160 140161 140162 140163 140164 140165 140166 140167 140168 140169 140170 140171 140172 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ****************************************************************************** ** */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ typedef struct Fts3auxTable Fts3auxTable; typedef struct Fts3auxCursor Fts3auxCursor; | > | 140340 140341 140342 140343 140344 140345 140346 140347 140348 140349 140350 140351 140352 140353 140354 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ****************************************************************************** ** */ /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ typedef struct Fts3auxTable Fts3auxTable; typedef struct Fts3auxCursor Fts3auxCursor; |
︙ | ︙ | |||
140715 140716 140717 140718 140719 140720 140721 140722 140723 140724 140725 140726 140727 140728 | ****************************************************************************** ** ** This module contains code that implements a parser for fts3 query strings ** (the right-hand argument to the MATCH operator). Because the supported ** syntax is relatively simple, the whole tokenizer/parser system is ** hand-coded. */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* ** By default, this module parses the legacy syntax that has been ** traditionally used by fts3. Or, if SQLITE_ENABLE_FTS3_PARENTHESIS ** is defined, then it uses the new syntax. The differences between ** the new and the old syntaxes are: | > | 140897 140898 140899 140900 140901 140902 140903 140904 140905 140906 140907 140908 140909 140910 140911 | ****************************************************************************** ** ** This module contains code that implements a parser for fts3 query strings ** (the right-hand argument to the MATCH operator). Because the supported ** syntax is relatively simple, the whole tokenizer/parser system is ** hand-coded. */ /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* ** By default, this module parses the legacy syntax that has been ** traditionally used by fts3. Or, if SQLITE_ENABLE_FTS3_PARENTHESIS ** is defined, then it uses the new syntax. The differences between ** the new and the old syntaxes are: |
︙ | ︙ | |||
142008 142009 142010 142011 142012 142013 142014 142015 142016 142017 142018 142019 142020 142021 142022 142023 142024 142025 142026 142027 | ** ** * The FTS3 module is being built as an extension ** (in which case SQLITE_CORE is not defined), or ** ** * The FTS3 module is being built into the core of ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <assert.h> */ /* #include <stdlib.h> */ /* #include <string.h> */ /* ** Malloc and Free functions */ static void *fts3HashMalloc(int n){ void *p = sqlite3_malloc(n); if( p ){ | > > | 142191 142192 142193 142194 142195 142196 142197 142198 142199 142200 142201 142202 142203 142204 142205 142206 142207 142208 142209 142210 142211 142212 | ** ** * The FTS3 module is being built as an extension ** (in which case SQLITE_CORE is not defined), or ** ** * The FTS3 module is being built into the core of ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). */ /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <assert.h> */ /* #include <stdlib.h> */ /* #include <string.h> */ /* #include "fts3_hash.h" */ /* ** Malloc and Free functions */ static void *fts3HashMalloc(int n){ void *p = sqlite3_malloc(n); if( p ){ |
︙ | ︙ | |||
142391 142392 142393 142394 142395 142396 142397 142398 142399 142400 142401 142402 142403 142404 142405 142406 142407 142408 142409 142410 142411 | ** ** * The FTS3 module is being built as an extension ** (in which case SQLITE_CORE is not defined), or ** ** * The FTS3 module is being built into the core of ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <assert.h> */ /* #include <stdlib.h> */ /* #include <stdio.h> */ /* #include <string.h> */ /* ** Class derived from sqlite3_tokenizer */ typedef struct porter_tokenizer { sqlite3_tokenizer base; /* Base class */ } porter_tokenizer; | > > | 142576 142577 142578 142579 142580 142581 142582 142583 142584 142585 142586 142587 142588 142589 142590 142591 142592 142593 142594 142595 142596 142597 142598 | ** ** * The FTS3 module is being built as an extension ** (in which case SQLITE_CORE is not defined), or ** ** * The FTS3 module is being built into the core of ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). */ /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <assert.h> */ /* #include <stdlib.h> */ /* #include <stdio.h> */ /* #include <string.h> */ /* #include "fts3_tokenizer.h" */ /* ** Class derived from sqlite3_tokenizer */ typedef struct porter_tokenizer { sqlite3_tokenizer base; /* Base class */ } porter_tokenizer; |
︙ | ︙ | |||
143055 143056 143057 143058 143059 143060 143061 143062 143063 143064 143065 143066 143067 143068 | ** ** * The FTS3 module is being built as an extension ** (in which case SQLITE_CORE is not defined), or ** ** * The FTS3 module is being built into the core of ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <assert.h> */ /* #include <string.h> */ /* ** Implementation of the SQL scalar function for accessing the underlying | > | 143242 143243 143244 143245 143246 143247 143248 143249 143250 143251 143252 143253 143254 143255 143256 | ** ** * The FTS3 module is being built as an extension ** (in which case SQLITE_CORE is not defined), or ** ** * The FTS3 module is being built into the core of ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). */ /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <assert.h> */ /* #include <string.h> */ /* ** Implementation of the SQL scalar function for accessing the underlying |
︙ | ︙ | |||
143550 143551 143552 143553 143554 143555 143556 143557 143558 143559 143560 143561 143562 143563 143564 143565 143566 143567 143568 143569 143570 | ** ** * The FTS3 module is being built as an extension ** (in which case SQLITE_CORE is not defined), or ** ** * The FTS3 module is being built into the core of ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <assert.h> */ /* #include <stdlib.h> */ /* #include <stdio.h> */ /* #include <string.h> */ typedef struct simple_tokenizer { sqlite3_tokenizer base; char delim[128]; /* flag ASCII delimiters */ } simple_tokenizer; typedef struct simple_tokenizer_cursor { | > > | 143738 143739 143740 143741 143742 143743 143744 143745 143746 143747 143748 143749 143750 143751 143752 143753 143754 143755 143756 143757 143758 143759 143760 | ** ** * The FTS3 module is being built as an extension ** (in which case SQLITE_CORE is not defined), or ** ** * The FTS3 module is being built into the core of ** SQLite (in which case SQLITE_ENABLE_FTS3 is defined). */ /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <assert.h> */ /* #include <stdlib.h> */ /* #include <stdio.h> */ /* #include <string.h> */ /* #include "fts3_tokenizer.h" */ typedef struct simple_tokenizer { sqlite3_tokenizer base; char delim[128]; /* flag ASCII delimiters */ } simple_tokenizer; typedef struct simple_tokenizer_cursor { |
︙ | ︙ | |||
143801 143802 143803 143804 143805 143806 143807 143808 143809 143810 143811 143812 143813 143814 | ** token: A token from the input. ** start: Byte offset of the token within the input <string>. ** end: Byte offset of the byte immediately following the end of the ** token within the input string. ** pos: Token offset of token within input. ** */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ typedef struct Fts3tokTable Fts3tokTable; typedef struct Fts3tokCursor Fts3tokCursor; | > | 143991 143992 143993 143994 143995 143996 143997 143998 143999 144000 144001 144002 144003 144004 144005 | ** token: A token from the input. ** start: Byte offset of the token within the input <string>. ** end: Byte offset of the byte immediately following the end of the ** token within the input string. ** pos: Token offset of token within input. ** */ /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ typedef struct Fts3tokTable Fts3tokTable; typedef struct Fts3tokCursor Fts3tokCursor; |
︙ | ︙ | |||
144236 144237 144238 144239 144240 144241 144242 144243 144244 144245 144246 144247 144248 144249 | ** This file is part of the SQLite FTS3 extension module. Specifically, ** this file contains code to insert, update and delete rows from FTS3 ** tables. It also contains code to merge FTS3 b-tree segments. Some ** of the sub-routines used to merge segments are also used by the query ** code in fts3.c. */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ /* #include <stdlib.h> */ | > | 144427 144428 144429 144430 144431 144432 144433 144434 144435 144436 144437 144438 144439 144440 144441 | ** This file is part of the SQLite FTS3 extension module. Specifically, ** this file contains code to insert, update and delete rows from FTS3 ** tables. It also contains code to merge FTS3 b-tree segments. Some ** of the sub-routines used to merge segments are also used by the query ** code in fts3.c. */ /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ /* #include <stdlib.h> */ |
︙ | ︙ | |||
149896 149897 149898 149899 149900 149901 149902 149903 149904 149905 149906 149907 149908 149909 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ****************************************************************************** */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ /* ** Characters that may appear in the second argument to matchinfo(). | > | 150088 150089 150090 150091 150092 150093 150094 150095 150096 150097 150098 150099 150100 150101 150102 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ****************************************************************************** */ /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ /* ** Characters that may appear in the second argument to matchinfo(). |
︙ | ︙ | |||
151608 151609 151610 151611 151612 151613 151614 151615 151616 151617 151618 151619 151620 151621 151622 151623 151624 151625 151626 151627 151628 | ****************************************************************************** ** ** Implementation of the "unicode" full-text-search tokenizer. */ #ifndef SQLITE_DISABLE_FTS3_UNICODE #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <assert.h> */ /* #include <stdlib.h> */ /* #include <stdio.h> */ /* #include <string.h> */ /* ** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied ** from the sqlite3 source file utf.c. If this file is compiled as part ** of the amalgamation, they are not required. */ #ifndef SQLITE_AMALGAMATION | > > | 151801 151802 151803 151804 151805 151806 151807 151808 151809 151810 151811 151812 151813 151814 151815 151816 151817 151818 151819 151820 151821 151822 151823 | ****************************************************************************** ** ** Implementation of the "unicode" full-text-search tokenizer. */ #ifndef SQLITE_DISABLE_FTS3_UNICODE /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <assert.h> */ /* #include <stdlib.h> */ /* #include <stdio.h> */ /* #include <string.h> */ /* #include "fts3_tokenizer.h" */ /* ** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied ** from the sqlite3 source file utf.c. If this file is compiled as part ** of the amalgamation, they are not required. */ #ifndef SQLITE_AMALGAMATION |
︙ | ︙ | |||
152410 152411 152412 152413 152414 152415 152416 152417 152418 152419 152420 152421 152422 152423 152424 152425 | ** of a record. For internal nodes it is the node number of a ** child page. */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) #ifndef SQLITE_CORE SQLITE_EXTENSION_INIT1 #else #endif /* #include <string.h> */ /* #include <assert.h> */ /* #include <stdio.h> */ #ifndef SQLITE_AMALGAMATION | > > | 152605 152606 152607 152608 152609 152610 152611 152612 152613 152614 152615 152616 152617 152618 152619 152620 152621 152622 | ** of a record. For internal nodes it is the node number of a ** child page. */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) #ifndef SQLITE_CORE /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #else /* #include "sqlite3.h" */ #endif /* #include <string.h> */ /* #include <assert.h> */ /* #include <stdio.h> */ #ifndef SQLITE_AMALGAMATION |
︙ | ︙ | |||
155907 155908 155909 155910 155911 155912 155913 155914 155915 155916 155917 155918 155919 155920 155921 155922 | #include <unicode/uregex.h> #include <unicode/ustring.h> #include <unicode/ucol.h> /* #include <assert.h> */ #ifndef SQLITE_CORE SQLITE_EXTENSION_INIT1 #else #endif /* ** Maximum length (in bytes) of the pattern in a LIKE or GLOB ** operator. */ #ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH | > > | 156104 156105 156106 156107 156108 156109 156110 156111 156112 156113 156114 156115 156116 156117 156118 156119 156120 156121 | #include <unicode/uregex.h> #include <unicode/ustring.h> #include <unicode/ucol.h> /* #include <assert.h> */ #ifndef SQLITE_CORE /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #else /* #include "sqlite3.h" */ #endif /* ** Maximum length (in bytes) of the pattern in a LIKE or GLOB ** operator. */ #ifndef SQLITE_MAX_LIKE_PATTERN_LENGTH |
︙ | ︙ | |||
156384 156385 156386 156387 156388 156389 156390 156391 156392 156393 156394 156395 156396 156397 156398 156399 156400 156401 156402 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file implements a tokenizer for fts3 based on the ICU library. */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) #ifdef SQLITE_ENABLE_ICU /* #include <assert.h> */ /* #include <string.h> */ #include <unicode/ubrk.h> /* #include <unicode/ucol.h> */ /* #include <unicode/ustring.h> */ #include <unicode/utf16.h> typedef struct IcuTokenizer IcuTokenizer; | > > | 156583 156584 156585 156586 156587 156588 156589 156590 156591 156592 156593 156594 156595 156596 156597 156598 156599 156600 156601 156602 156603 | ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file implements a tokenizer for fts3 based on the ICU library. */ /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) #ifdef SQLITE_ENABLE_ICU /* #include <assert.h> */ /* #include <string.h> */ /* #include "fts3_tokenizer.h" */ #include <unicode/ubrk.h> /* #include <unicode/ucol.h> */ /* #include <unicode/ustring.h> */ #include <unicode/utf16.h> typedef struct IcuTokenizer IcuTokenizer; |
︙ | ︙ | |||
156633 156634 156635 156636 156637 156638 156639 | *ppModule = &icuTokenizerModule; } #endif /* defined(SQLITE_ENABLE_ICU) */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ /************** End of fts3_icu.c ********************************************/ | | | | | | | | | | | | | | | | | | | > | | | | | 156834 156835 156836 156837 156838 156839 156840 156841 156842 156843 156844 156845 156846 156847 156848 156849 156850 156851 156852 156853 156854 156855 156856 156857 156858 156859 156860 156861 156862 156863 156864 156865 156866 156867 156868 156869 156870 156871 156872 156873 156874 156875 156876 156877 156878 156879 156880 156881 156882 156883 156884 156885 156886 156887 156888 156889 156890 156891 156892 156893 156894 156895 156896 156897 156898 156899 156900 156901 156902 156903 156904 156905 156906 156907 156908 156909 156910 156911 156912 156913 156914 156915 156916 156917 156918 156919 156920 156921 156922 156923 156924 156925 156926 156927 156928 156929 156930 156931 156932 156933 156934 156935 156936 156937 156938 156939 156940 156941 156942 156943 156944 156945 156946 156947 156948 156949 156950 156951 156952 156953 | *ppModule = &icuTokenizerModule; } #endif /* defined(SQLITE_ENABLE_ICU) */ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ /************** End of fts3_icu.c ********************************************/ /************** Begin file sqlite3rbu.c **************************************/ /* ** 2014 August 30 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** ** OVERVIEW ** ** The RBU extension requires that the RBU update be packaged as an ** SQLite database. The tables it expects to find are described in ** sqlite3rbu.h. Essentially, for each table xyz in the target database ** that the user wishes to write to, a corresponding data_xyz table is ** created in the RBU database and populated with one row for each row to ** update, insert or delete from the target table. ** ** The update proceeds in three stages: ** ** 1) The database is updated. The modified database pages are written ** to a *-oal file. A *-oal file is just like a *-wal file, except ** that it is named "<database>-oal" instead of "<database>-wal". ** Because regular SQLite clients do not look for file named ** "<database>-oal", they go on using the original database in ** rollback mode while the *-oal file is being generated. ** ** During this stage RBU does not update the database by writing ** directly to the target tables. Instead it creates "imposter" ** tables using the SQLITE_TESTCTRL_IMPOSTER interface that it uses ** to update each b-tree individually. All updates required by each ** b-tree are completed before moving on to the next, and all ** updates are done in sorted key order. ** ** 2) The "<database>-oal" file is moved to the equivalent "<database>-wal" ** location using a call to rename(2). Before doing this the RBU ** module takes an EXCLUSIVE lock on the database file, ensuring ** that there are no other active readers. ** ** Once the EXCLUSIVE lock is released, any other database readers ** detect the new *-wal file and read the database in wal mode. At ** this point they see the new version of the database - including ** the updates made as part of the RBU update. ** ** 3) The new *-wal file is checkpointed. This proceeds in the same way ** as a regular database checkpoint, except that a single frame is ** checkpointed each time sqlite3rbu_step() is called. If the RBU ** handle is closed before the entire *-wal file is checkpointed, ** the checkpoint progress is saved in the RBU database and the ** checkpoint can be resumed by another RBU client at some point in ** the future. ** ** POTENTIAL PROBLEMS ** ** The rename() call might not be portable. And RBU is not currently ** syncing the directory after renaming the file. ** ** When state is saved, any commit to the *-oal file and the commit to ** the RBU update database are not atomic. So if the power fails at the ** wrong moment they might get out of sync. As the main database will be ** committed before the RBU update database this will likely either just ** pass unnoticed, or result in SQLITE_CONSTRAINT errors (due to UNIQUE ** constraint violations). ** ** If some client does modify the target database mid RBU update, or some ** other error occurs, the RBU extension will keep throwing errors. It's ** not really clear how to get out of this state. The system could just ** by delete the RBU update database and *-oal file and have the device ** download the update again and start over. ** ** At present, for an UPDATE, both the new.* and old.* records are ** collected in the rbu_xyz table. And for both UPDATEs and DELETEs all ** fields are collected. This means we're probably writing a lot more ** data to disk when saving the state of an ongoing update to the RBU ** update database than is strictly necessary. ** */ /* #include <assert.h> */ /* #include <string.h> */ /* #include <stdio.h> */ /* #include <unistd.h> */ /* #include "sqlite3.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) /************** Include sqlite3rbu.h in the middle of sqlite3rbu.c ***********/ /************** Begin file sqlite3rbu.h **************************************/ /* ** 2014 August 30 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains the public interface for the RBU extension. */ /* ** SUMMARY ** ** Writing a transaction containing a large number of operations on ** b-tree indexes that are collectively larger than the available cache |
︙ | ︙ | |||
156774 156775 156776 156777 156778 156779 156780 | ** guarantee that a single update process will run for long enough to apply ** the entire update, for example because the update is being applied on a ** mobile device that is frequently rebooted. Even after the writer process ** has committed one or more sub-transactions, other database clients continue ** to read from the original database snapshot. In other words, partially ** applied transactions are not visible to other clients. ** | | | | | 156976 156977 156978 156979 156980 156981 156982 156983 156984 156985 156986 156987 156988 156989 156990 156991 156992 156993 156994 156995 156996 156997 | ** guarantee that a single update process will run for long enough to apply ** the entire update, for example because the update is being applied on a ** mobile device that is frequently rebooted. Even after the writer process ** has committed one or more sub-transactions, other database clients continue ** to read from the original database snapshot. In other words, partially ** applied transactions are not visible to other clients. ** ** "RBU" stands for "Over The Air" update. As in a large database update ** transmitted via a wireless network to a mobile device. A transaction ** applied using this extension is hence refered to as an "RBU update". ** ** ** LIMITATIONS ** ** An "RBU update" transaction is subject to the following limitations: ** ** * The transaction must consist of INSERT, UPDATE and DELETE operations ** only. ** ** * INSERT statements may not use any default values. ** ** * UPDATE and DELETE statements must identify their target rows by |
︙ | ︙ | |||
156806 156807 156808 156809 156810 156811 156812 | ** * CHECK constraints are not enforced. ** ** * No constraint handling mode except for "OR ROLLBACK" is supported. ** ** ** PREPARATION ** | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 157008 157009 157010 157011 157012 157013 157014 157015 157016 157017 157018 157019 157020 157021 157022 157023 157024 157025 157026 157027 157028 157029 157030 157031 157032 157033 157034 157035 157036 157037 157038 157039 157040 157041 157042 157043 157044 157045 157046 157047 157048 157049 157050 157051 157052 157053 157054 157055 157056 157057 157058 157059 157060 157061 157062 157063 157064 157065 157066 157067 157068 157069 157070 157071 157072 157073 157074 157075 157076 157077 157078 157079 157080 157081 157082 157083 157084 157085 157086 157087 157088 157089 157090 157091 157092 157093 157094 157095 157096 157097 157098 157099 157100 157101 157102 157103 157104 157105 157106 157107 157108 157109 157110 157111 157112 157113 157114 157115 157116 157117 157118 157119 157120 157121 157122 157123 157124 157125 157126 157127 157128 157129 157130 157131 157132 157133 157134 157135 157136 157137 157138 157139 157140 157141 157142 157143 157144 157145 157146 157147 157148 157149 157150 157151 157152 157153 157154 157155 157156 157157 157158 157159 157160 157161 157162 157163 157164 157165 157166 157167 157168 157169 157170 157171 157172 157173 157174 157175 157176 157177 157178 157179 157180 157181 157182 157183 157184 157185 157186 157187 157188 157189 157190 157191 157192 157193 157194 157195 157196 157197 157198 157199 157200 157201 157202 157203 157204 157205 157206 157207 157208 157209 157210 157211 157212 157213 157214 157215 157216 157217 157218 157219 157220 157221 157222 157223 157224 157225 157226 157227 157228 157229 157230 157231 157232 157233 157234 157235 157236 157237 157238 157239 157240 157241 157242 157243 157244 157245 157246 157247 157248 157249 157250 157251 157252 157253 157254 157255 157256 157257 157258 157259 157260 157261 157262 157263 157264 157265 157266 157267 157268 157269 157270 157271 157272 157273 157274 157275 157276 157277 157278 157279 157280 157281 157282 157283 157284 157285 157286 157287 157288 157289 157290 157291 157292 157293 157294 157295 157296 157297 157298 157299 157300 157301 157302 157303 157304 157305 157306 157307 157308 157309 157310 157311 157312 157313 157314 157315 157316 157317 157318 157319 157320 157321 157322 157323 157324 157325 157326 157327 157328 157329 157330 157331 157332 157333 157334 157335 157336 157337 157338 157339 157340 157341 157342 157343 157344 157345 157346 157347 157348 157349 157350 157351 157352 157353 157354 157355 157356 157357 157358 157359 157360 157361 157362 157363 157364 157365 157366 157367 157368 157369 157370 157371 157372 157373 157374 157375 157376 157377 157378 157379 157380 157381 157382 157383 157384 157385 157386 157387 157388 157389 157390 157391 157392 157393 157394 157395 157396 157397 157398 157399 157400 157401 157402 157403 157404 157405 157406 157407 157408 157409 157410 157411 157412 157413 157414 157415 157416 157417 157418 157419 157420 157421 157422 157423 157424 157425 157426 157427 157428 157429 157430 157431 157432 157433 157434 157435 157436 157437 157438 157439 157440 157441 157442 157443 157444 157445 157446 157447 157448 157449 157450 157451 157452 157453 157454 157455 157456 157457 157458 157459 157460 157461 157462 157463 157464 157465 157466 157467 157468 157469 157470 157471 157472 157473 157474 157475 157476 157477 157478 157479 157480 157481 157482 157483 157484 157485 157486 157487 157488 157489 157490 157491 157492 157493 157494 157495 157496 157497 157498 157499 157500 157501 157502 157503 157504 157505 157506 157507 157508 157509 157510 157511 157512 157513 157514 157515 157516 157517 157518 157519 157520 157521 157522 157523 157524 157525 157526 157527 157528 157529 157530 157531 157532 157533 157534 157535 157536 157537 157538 157539 157540 157541 157542 157543 157544 157545 157546 157547 157548 157549 157550 157551 157552 157553 157554 157555 157556 157557 157558 157559 157560 157561 157562 157563 157564 157565 157566 157567 157568 157569 157570 157571 157572 157573 157574 157575 157576 157577 157578 157579 157580 157581 157582 157583 157584 157585 157586 157587 157588 157589 157590 157591 157592 157593 157594 157595 157596 157597 157598 157599 157600 157601 157602 157603 157604 157605 157606 157607 157608 157609 157610 157611 157612 157613 157614 157615 157616 157617 157618 157619 157620 157621 157622 157623 157624 157625 157626 | ** * CHECK constraints are not enforced. ** ** * No constraint handling mode except for "OR ROLLBACK" is supported. ** ** ** PREPARATION ** ** An "RBU update" is stored as a separate SQLite database. A database ** containing an RBU update is an "RBU database". For each table in the ** target database to be updated, the RBU database should contain a table ** named "data_<target name>" containing the same set of columns as the ** target table, and one more - "rbu_control". The data_% table should ** have no PRIMARY KEY or UNIQUE constraints, but each column should have ** the same type as the corresponding column in the target database. ** The "rbu_control" column should have no type at all. For example, if ** the target database contains: ** ** CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c UNIQUE); ** ** Then the RBU database should contain: ** ** CREATE TABLE data_t1(a INTEGER, b TEXT, c, rbu_control); ** ** The order of the columns in the data_% table does not matter. ** ** If the target database table is a virtual table or a table that has no ** PRIMARY KEY declaration, the data_% table must also contain a column ** named "rbu_rowid". This column is mapped to the tables implicit primary ** key column - "rowid". Virtual tables for which the "rowid" column does ** not function like a primary key value cannot be updated using RBU. For ** example, if the target db contains either of the following: ** ** CREATE VIRTUAL TABLE x1 USING fts3(a, b); ** CREATE TABLE x1(a, b) ** ** then the RBU database should contain: ** ** CREATE TABLE data_x1(a, b, rbu_rowid, rbu_control); ** ** All non-hidden columns (i.e. all columns matched by "SELECT *") of the ** target table must be present in the input table. For virtual tables, ** hidden columns are optional - they are updated by RBU if present in ** the input table, or not otherwise. For example, to write to an fts4 ** table with a hidden languageid column such as: ** ** CREATE VIRTUAL TABLE ft1 USING fts4(a, b, languageid='langid'); ** ** Either of the following input table schemas may be used: ** ** CREATE TABLE data_ft1(a, b, langid, rbu_rowid, rbu_control); ** CREATE TABLE data_ft1(a, b, rbu_rowid, rbu_control); ** ** For each row to INSERT into the target database as part of the RBU ** update, the corresponding data_% table should contain a single record ** with the "rbu_control" column set to contain integer value 0. The ** other columns should be set to the values that make up the new record ** to insert. ** ** If the target database table has an INTEGER PRIMARY KEY, it is not ** possible to insert a NULL value into the IPK column. Attempting to ** do so results in an SQLITE_MISMATCH error. ** ** For each row to DELETE from the target database as part of the RBU ** update, the corresponding data_% table should contain a single record ** with the "rbu_control" column set to contain integer value 1. The ** real primary key values of the row to delete should be stored in the ** corresponding columns of the data_% table. The values stored in the ** other columns are not used. ** ** For each row to UPDATE from the target database as part of the RBU ** update, the corresponding data_% table should contain a single record ** with the "rbu_control" column set to contain a value of type text. ** The real primary key values identifying the row to update should be ** stored in the corresponding columns of the data_% table row, as should ** the new values of all columns being update. The text value in the ** "rbu_control" column must contain the same number of characters as ** there are columns in the target database table, and must consist entirely ** of 'x' and '.' characters (or in some special cases 'd' - see below). For ** each column that is being updated, the corresponding character is set to ** 'x'. For those that remain as they are, the corresponding character of the ** rbu_control value should be set to '.'. For example, given the tables ** above, the update statement: ** ** UPDATE t1 SET c = 'usa' WHERE a = 4; ** ** is represented by the data_t1 row created by: ** ** INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..x'); ** ** Instead of an 'x' character, characters of the rbu_control value specified ** for UPDATEs may also be set to 'd'. In this case, instead of updating the ** target table with the value stored in the corresponding data_% column, the ** user-defined SQL function "rbu_delta()" is invoked and the result stored in ** the target table column. rbu_delta() is invoked with two arguments - the ** original value currently stored in the target table column and the ** value specified in the data_xxx table. ** ** For example, this row: ** ** INSERT INTO data_t1(a, b, c, rbu_control) VALUES(4, NULL, 'usa', '..d'); ** ** is similar to an UPDATE statement such as: ** ** UPDATE t1 SET c = rbu_delta(c, 'usa') WHERE a = 4; ** ** If the target database table is a virtual table or a table with no PRIMARY ** KEY, the rbu_control value should not include a character corresponding ** to the rbu_rowid value. For example, this: ** ** INSERT INTO data_ft1(a, b, rbu_rowid, rbu_control) ** VALUES(NULL, 'usa', 12, '.x'); ** ** causes a result similar to: ** ** UPDATE ft1 SET b = 'usa' WHERE rowid = 12; ** ** The data_xxx tables themselves should have no PRIMARY KEY declarations. ** However, RBU is more efficient if reading the rows in from each data_xxx ** table in "rowid" order is roughly the same as reading them sorted by ** the PRIMARY KEY of the corresponding target database table. In other ** words, rows should be sorted using the destination table PRIMARY KEY ** fields before they are inserted into the data_xxx tables. ** ** USAGE ** ** The API declared below allows an application to apply an RBU update ** stored on disk to an existing target database. Essentially, the ** application: ** ** 1) Opens an RBU handle using the sqlite3rbu_open() function. ** ** 2) Registers any required virtual table modules with the database ** handle returned by sqlite3rbu_db(). Also, if required, register ** the rbu_delta() implementation. ** ** 3) Calls the sqlite3rbu_step() function one or more times on ** the new handle. Each call to sqlite3rbu_step() performs a single ** b-tree operation, so thousands of calls may be required to apply ** a complete update. ** ** 4) Calls sqlite3rbu_close() to close the RBU update handle. If ** sqlite3rbu_step() has been called enough times to completely ** apply the update to the target database, then the RBU database ** is marked as fully applied. Otherwise, the state of the RBU ** update application is saved in the RBU database for later ** resumption. ** ** See comments below for more detail on APIs. ** ** If an update is only partially applied to the target database by the ** time sqlite3rbu_close() is called, various state information is saved ** within the RBU database. This allows subsequent processes to automatically ** resume the RBU update from where it left off. ** ** To remove all RBU extension state information, returning an RBU database ** to its original contents, it is sufficient to drop all tables that begin ** with the prefix "rbu_" ** ** DATABASE LOCKING ** ** An RBU update may not be applied to a database in WAL mode. Attempting ** to do so is an error (SQLITE_ERROR). ** ** While an RBU handle is open, a SHARED lock may be held on the target ** database file. This means it is possible for other clients to read the ** database, but not to write it. ** ** If an RBU update is started and then suspended before it is completed, ** then an external client writes to the database, then attempting to resume ** the suspended RBU update is also an error (SQLITE_BUSY). */ #ifndef _SQLITE3RBU_H #define _SQLITE3RBU_H /* #include "sqlite3.h" ** Required for error code definitions ** */ typedef struct sqlite3rbu sqlite3rbu; /* ** Open an RBU handle. ** ** Argument zTarget is the path to the target database. Argument zRbu is ** the path to the RBU database. Each call to this function must be matched ** by a call to sqlite3rbu_close(). When opening the databases, RBU passes ** the SQLITE_CONFIG_URI flag to sqlite3_open_v2(). So if either zTarget ** or zRbu begin with "file:", it will be interpreted as an SQLite ** database URI, not a regular file name. ** ** If the zState argument is passed a NULL value, the RBU extension stores ** the current state of the update (how many rows have been updated, which ** indexes are yet to be updated etc.) within the RBU database itself. This ** can be convenient, as it means that the RBU application does not need to ** organize removing a separate state file after the update is concluded. ** Or, if zState is non-NULL, it must be a path to a database file in which ** the RBU extension can store the state of the update. ** ** When resuming an RBU update, the zState argument must be passed the same ** value as when the RBU update was started. ** ** Once the RBU update is finished, the RBU extension does not ** automatically remove any zState database file, even if it created it. ** ** By default, RBU uses the default VFS to access the files on disk. To ** use a VFS other than the default, an SQLite "file:" URI containing a ** "vfs=..." option may be passed as the zTarget option. ** ** IMPORTANT NOTE FOR ZIPVFS USERS: The RBU extension works with all of ** SQLite's built-in VFSs, including the multiplexor VFS. However it does ** not work out of the box with zipvfs. Refer to the comment describing ** the zipvfs_create_vfs() API below for details on using RBU with zipvfs. */ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open( const char *zTarget, const char *zRbu, const char *zState ); /* ** Internally, each RBU connection uses a separate SQLite database ** connection to access the target and rbu update databases. This ** API allows the application direct access to these database handles. ** ** The first argument passed to this function must be a valid, open, RBU ** handle. The second argument should be passed zero to access the target ** database handle, or non-zero to access the rbu update database handle. ** Accessing the underlying database handles may be useful in the ** following scenarios: ** ** * If any target tables are virtual tables, it may be necessary to ** call sqlite3_create_module() on the target database handle to ** register the required virtual table implementations. ** ** * If the data_xxx tables in the RBU source database are virtual ** tables, the application may need to call sqlite3_create_module() on ** the rbu update db handle to any required virtual table ** implementations. ** ** * If the application uses the "rbu_delta()" feature described above, ** it must use sqlite3_create_function() or similar to register the ** rbu_delta() implementation with the target database handle. ** ** If an error has occurred, either while opening or stepping the RBU object, ** this function may return NULL. The error code and message may be collected ** when sqlite3rbu_close() is called. */ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3rbu_db(sqlite3rbu*, int bRbu); /* ** Do some work towards applying the RBU update to the target db. ** ** Return SQLITE_DONE if the update has been completely applied, or ** SQLITE_OK if no error occurs but there remains work to do to apply ** the RBU update. If an error does occur, some other error code is ** returned. ** ** Once a call to sqlite3rbu_step() has returned a value other than ** SQLITE_OK, all subsequent calls on the same RBU handle are no-ops ** that immediately return the same value. */ SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *pRbu); /* ** Close an RBU handle. ** ** If the RBU update has been completely applied, mark the RBU database ** as fully applied. Otherwise, assuming no error has occurred, save the ** current state of the RBU update appliation to the RBU database. ** ** If an error has already occurred as part of an sqlite3rbu_step() ** or sqlite3rbu_open() call, or if one occurs within this function, an ** SQLite error code is returned. Additionally, *pzErrmsg may be set to ** point to a buffer containing a utf-8 formatted English language error ** message. It is the responsibility of the caller to eventually free any ** such buffer using sqlite3_free(). ** ** Otherwise, if no error occurs, this function returns SQLITE_OK if the ** update has been partially applied, or SQLITE_DONE if it has been ** completely applied. */ SQLITE_API int SQLITE_STDCALL sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg); /* ** Return the total number of key-value operations (inserts, deletes or ** updates) that have been performed on the target database since the ** current RBU update was started. */ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu); /* ** Create an RBU VFS named zName that accesses the underlying file-system ** via existing VFS zParent. Or, if the zParent parameter is passed NULL, ** then the new RBU VFS uses the default system VFS to access the file-system. ** The new object is registered as a non-default VFS with SQLite before ** returning. ** ** Part of the RBU implementation uses a custom VFS object. Usually, this ** object is created and deleted automatically by RBU. ** ** The exception is for applications that also use zipvfs. In this case, ** the custom VFS must be explicitly created by the user before the RBU ** handle is opened. The RBU VFS should be installed so that the zipvfs ** VFS uses the RBU VFS, which in turn uses any other VFS layers in use ** (for example multiplexor) to access the file-system. For example, ** to assemble an RBU enabled VFS stack that uses both zipvfs and ** multiplexor (error checking omitted): ** ** // Create a VFS named "multiplex" (not the default). ** sqlite3_multiplex_initialize(0, 0); ** ** // Create an rbu VFS named "rbu" that uses multiplexor. If the ** // second argument were replaced with NULL, the "rbu" VFS would ** // access the file-system via the system default VFS, bypassing the ** // multiplexor. ** sqlite3rbu_create_vfs("rbu", "multiplex"); ** ** // Create a zipvfs VFS named "zipvfs" that uses rbu. ** zipvfs_create_vfs_v3("zipvfs", "rbu", 0, xCompressorAlgorithmDetector); ** ** // Make zipvfs the default VFS. ** sqlite3_vfs_register(sqlite3_vfs_find("zipvfs"), 1); ** ** Because the default VFS created above includes a RBU functionality, it ** may be used by RBU clients. Attempting to use RBU with a zipvfs VFS stack ** that does not include the RBU layer results in an error. ** ** The overhead of adding the "rbu" VFS to the system is negligible for ** non-RBU users. There is no harm in an application accessing the ** file-system via "rbu" all the time, even if it only uses RBU functionality ** occasionally. */ SQLITE_API int SQLITE_STDCALL sqlite3rbu_create_vfs(const char *zName, const char *zParent); /* ** Deregister and destroy an RBU vfs created by an earlier call to ** sqlite3rbu_create_vfs(). ** ** VFS objects are not reference counted. If a VFS object is destroyed ** before all database handles that use it have been closed, the results ** are undefined. */ SQLITE_API void SQLITE_STDCALL sqlite3rbu_destroy_vfs(const char *zName); #endif /* _SQLITE3RBU_H */ /************** End of sqlite3rbu.h ******************************************/ /************** Continuing where we left off in sqlite3rbu.c *****************/ /* Maximum number of prepared UPDATE statements held by this module */ #define SQLITE_RBU_UPDATE_CACHESIZE 16 /* ** Swap two objects of type TYPE. */ #if !defined(SQLITE_AMALGAMATION) # define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;} #endif /* ** The rbu_state table is used to save the state of a partially applied ** update so that it can be resumed later. The table consists of integer ** keys mapped to values as follows: ** ** RBU_STATE_STAGE: ** May be set to integer values 1, 2, 4 or 5. As follows: ** 1: the *-rbu file is currently under construction. ** 2: the *-rbu file has been constructed, but not yet moved ** to the *-wal path. ** 4: the checkpoint is underway. ** 5: the rbu update has been checkpointed. ** ** RBU_STATE_TBL: ** Only valid if STAGE==1. The target database name of the table ** currently being written. ** ** RBU_STATE_IDX: ** Only valid if STAGE==1. The target database name of the index ** currently being written, or NULL if the main table is currently being ** updated. ** ** RBU_STATE_ROW: ** Only valid if STAGE==1. Number of rows already processed for the current ** table/index. ** ** RBU_STATE_PROGRESS: ** Trbul number of sqlite3rbu_step() calls made so far as part of this ** rbu update. ** ** RBU_STATE_CKPT: ** Valid if STAGE==4. The 64-bit checksum associated with the wal-index ** header created by recovering the *-wal file. This is used to detect ** cases when another client appends frames to the *-wal file in the ** middle of an incremental checkpoint (an incremental checkpoint cannot ** be continued if this happens). ** ** RBU_STATE_COOKIE: ** Valid if STAGE==1. The current change-counter cookie value in the ** target db file. ** ** RBU_STATE_OALSZ: ** Valid if STAGE==1. The size in bytes of the *-oal file. */ #define RBU_STATE_STAGE 1 #define RBU_STATE_TBL 2 #define RBU_STATE_IDX 3 #define RBU_STATE_ROW 4 #define RBU_STATE_PROGRESS 5 #define RBU_STATE_CKPT 6 #define RBU_STATE_COOKIE 7 #define RBU_STATE_OALSZ 8 #define RBU_STAGE_OAL 1 #define RBU_STAGE_MOVE 2 #define RBU_STAGE_CAPTURE 3 #define RBU_STAGE_CKPT 4 #define RBU_STAGE_DONE 5 #define RBU_CREATE_STATE \ "CREATE TABLE IF NOT EXISTS %s.rbu_state(k INTEGER PRIMARY KEY, v)" typedef struct RbuFrame RbuFrame; typedef struct RbuObjIter RbuObjIter; typedef struct RbuState RbuState; typedef struct rbu_vfs rbu_vfs; typedef struct rbu_file rbu_file; typedef struct RbuUpdateStmt RbuUpdateStmt; #if !defined(SQLITE_AMALGAMATION) typedef unsigned int u32; typedef unsigned char u8; typedef sqlite3_int64 i64; #endif /* ** These values must match the values defined in wal.c for the equivalent ** locks. These are not magic numbers as they are part of the SQLite file ** format. */ #define WAL_LOCK_WRITE 0 #define WAL_LOCK_CKPT 1 #define WAL_LOCK_READ0 3 /* ** A structure to store values read from the rbu_state table in memory. */ struct RbuState { int eStage; char *zTbl; char *zIdx; i64 iWalCksum; int nRow; i64 nProgress; u32 iCookie; i64 iOalSz; }; struct RbuUpdateStmt { char *zMask; /* Copy of update mask used with pUpdate */ sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ RbuUpdateStmt *pNext; }; /* ** An iterator of this type is used to iterate through all objects in ** the target database that require updating. For each such table, the ** iterator visits, in order: ** ** * the table itself, ** * each index of the table (zero or more points to visit), and ** * a special "cleanup table" state. ** ** abIndexed: ** If the table has no indexes on it, abIndexed is set to NULL. Otherwise, ** it points to an array of flags nTblCol elements in size. The flag is ** set for each column that is either a part of the PK or a part of an ** index. Or clear otherwise. ** */ struct RbuObjIter { sqlite3_stmt *pTblIter; /* Iterate through tables */ sqlite3_stmt *pIdxIter; /* Index iterator */ int nTblCol; /* Size of azTblCol[] array */ char **azTblCol; /* Array of unquoted target column names */ char **azTblType; /* Array of target column types */ int *aiSrcOrder; /* src table col -> target table col */ u8 *abTblPk; /* Array of flags, set on target PK columns */ u8 *abNotNull; /* Array of flags, set on NOT NULL columns */ u8 *abIndexed; /* Array of flags, set on indexed & PK cols */ int eType; /* Table type - an RBU_PK_XXX value */ /* Output variables. zTbl==0 implies EOF. */ int bCleanup; /* True in "cleanup" state */ const char *zTbl; /* Name of target db table */ const char *zIdx; /* Name of target db index (or null) */ int iTnum; /* Root page of current object */ int iPkTnum; /* If eType==EXTERNAL, root of PK index */ int bUnique; /* Current index is unique */ /* Statements created by rbuObjIterPrepareAll() */ int nCol; /* Number of columns in current object */ sqlite3_stmt *pSelect; /* Source data */ sqlite3_stmt *pInsert; /* Statement for INSERT operations */ sqlite3_stmt *pDelete; /* Statement for DELETE ops */ sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zTbl */ /* Last UPDATE used (for PK b-tree updates only), or NULL. */ RbuUpdateStmt *pRbuUpdate; }; /* ** Values for RbuObjIter.eType ** ** 0: Table does not exist (error) ** 1: Table has an implicit rowid. ** 2: Table has an explicit IPK column. ** 3: Table has an external PK index. ** 4: Table is WITHOUT ROWID. ** 5: Table is a virtual table. */ #define RBU_PK_NOTABLE 0 #define RBU_PK_NONE 1 #define RBU_PK_IPK 2 #define RBU_PK_EXTERNAL 3 #define RBU_PK_WITHOUT_ROWID 4 #define RBU_PK_VTAB 5 /* ** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs ** one of the following operations. */ #define RBU_INSERT 1 /* Insert on a main table b-tree */ #define RBU_DELETE 2 /* Delete a row from a main table b-tree */ #define RBU_IDX_DELETE 3 /* Delete a row from an aux. index b-tree */ #define RBU_IDX_INSERT 4 /* Insert on an aux. index b-tree */ #define RBU_UPDATE 5 /* Update a row in a main table b-tree */ /* ** A single step of an incremental checkpoint - frame iWalFrame of the wal ** file should be copied to page iDbPage of the database file. */ struct RbuFrame { u32 iDbPage; u32 iWalFrame; }; /* ** RBU handle. */ struct sqlite3rbu { int eStage; /* Value of RBU_STATE_STAGE field */ sqlite3 *dbMain; /* target database handle */ sqlite3 *dbRbu; /* rbu database handle */ char *zTarget; /* Path to target db */ char *zRbu; /* Path to rbu db */ char *zState; /* Path to state db (or NULL if zRbu) */ char zStateDb[5]; /* Db name for state ("stat" or "main") */ int rc; /* Value returned by last rbu_step() call */ char *zErrmsg; /* Error message if rc!=SQLITE_OK */ int nStep; /* Rows processed for current object */ int nProgress; /* Rows processed for all objects */ RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ const char *zVfsName; /* Name of automatically created rbu vfs */ rbu_file *pTargetFd; /* File handle open on target db */ i64 iOalSz; /* The following state variables are used as part of the incremental ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding ** function rbuSetupCheckpoint() for details. */ u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */ u32 mLock; int nFrame; /* Entries in aFrame[] array */ int nFrameAlloc; /* Allocated size of aFrame[] array */ RbuFrame *aFrame; int pgsz; u8 *aBuf; i64 iWalCksum; }; /* ** An rbu VFS is implemented using an instance of this structure. */ struct rbu_vfs { sqlite3_vfs base; /* rbu VFS shim methods */ sqlite3_vfs *pRealVfs; /* Underlying VFS */ sqlite3_mutex *mutex; /* Mutex to protect pMain */ rbu_file *pMain; /* Linked list of main db files */ }; /* ** Each file opened by an rbu VFS is represented by an instance of ** the following structure. */ struct rbu_file { sqlite3_file base; /* sqlite3_file methods */ sqlite3_file *pReal; /* Underlying file handle */ rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */ sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */ int openFlags; /* Flags this file was opened with */ u32 iCookie; /* Cookie value for main db files */ u8 iWriteVer; /* "write-version" value for main db files */ int nShm; /* Number of entries in apShm[] array */ char **apShm; /* Array of mmap'd *-shm regions */ char *zDel; /* Delete this when closing file */ const char *zWal; /* Wal filename for this main db file */ rbu_file *pWalFd; /* Wal file descriptor for this main db */ rbu_file *pMainNext; /* Next MAIN_DB file */ }; /* ** Prepare the SQL statement in buffer zSql against database handle db. ** If successful, set *ppStmt to point to the new statement and return ** SQLITE_OK. |
︙ | ︙ | |||
157488 157489 157490 157491 157492 157493 157494 | rc = prepareAndCollectError(db, ppStmt, pzErrmsg, zSql); sqlite3_free(zSql); } return rc; } /* | | | | | | | | | | | | | | | | | | | | | | 157690 157691 157692 157693 157694 157695 157696 157697 157698 157699 157700 157701 157702 157703 157704 157705 157706 157707 157708 157709 157710 157711 157712 157713 157714 157715 157716 157717 157718 157719 157720 157721 157722 157723 157724 157725 157726 157727 157728 157729 157730 157731 157732 157733 157734 157735 157736 157737 157738 157739 157740 157741 157742 157743 157744 157745 157746 157747 157748 157749 157750 157751 157752 157753 157754 157755 157756 157757 157758 157759 157760 157761 157762 157763 157764 157765 157766 157767 157768 157769 157770 157771 157772 157773 157774 157775 157776 157777 157778 157779 157780 157781 157782 157783 157784 157785 157786 157787 157788 | rc = prepareAndCollectError(db, ppStmt, pzErrmsg, zSql); sqlite3_free(zSql); } return rc; } /* ** Free the RbuObjIter.azTblCol[] and RbuObjIter.abTblPk[] arrays allocated ** by an earlier call to rbuObjIterCacheTableInfo(). */ static void rbuObjIterFreeCols(RbuObjIter *pIter){ int i; for(i=0; i<pIter->nTblCol; i++){ sqlite3_free(pIter->azTblCol[i]); sqlite3_free(pIter->azTblType[i]); } sqlite3_free(pIter->azTblCol); pIter->azTblCol = 0; pIter->azTblType = 0; pIter->aiSrcOrder = 0; pIter->abTblPk = 0; pIter->abNotNull = 0; pIter->nTblCol = 0; pIter->eType = 0; /* Invalid value */ } /* ** Finalize all statements and free all allocations that are specific to ** the current object (table/index pair). */ static void rbuObjIterClearStatements(RbuObjIter *pIter){ RbuUpdateStmt *pUp; sqlite3_finalize(pIter->pSelect); sqlite3_finalize(pIter->pInsert); sqlite3_finalize(pIter->pDelete); sqlite3_finalize(pIter->pTmpInsert); pUp = pIter->pRbuUpdate; while( pUp ){ RbuUpdateStmt *pTmp = pUp->pNext; sqlite3_finalize(pUp->pUpdate); sqlite3_free(pUp); pUp = pTmp; } pIter->pSelect = 0; pIter->pInsert = 0; pIter->pDelete = 0; pIter->pRbuUpdate = 0; pIter->pTmpInsert = 0; pIter->nCol = 0; } /* ** Clean up any resources allocated as part of the iterator object passed ** as the only argument. */ static void rbuObjIterFinalize(RbuObjIter *pIter){ rbuObjIterClearStatements(pIter); sqlite3_finalize(pIter->pTblIter); sqlite3_finalize(pIter->pIdxIter); rbuObjIterFreeCols(pIter); memset(pIter, 0, sizeof(RbuObjIter)); } /* ** Advance the iterator to the next position. ** ** If no error occurs, SQLITE_OK is returned and the iterator is left ** pointing to the next entry. Otherwise, an error code and message is ** left in the RBU handle passed as the first argument. A copy of the ** error code is returned. */ static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){ int rc = p->rc; if( rc==SQLITE_OK ){ /* Free any SQLite statements used while processing the previous object */ rbuObjIterClearStatements(pIter); if( pIter->zIdx==0 ){ rc = sqlite3_exec(p->dbMain, "DROP TRIGGER IF EXISTS temp.rbu_insert_tr;" "DROP TRIGGER IF EXISTS temp.rbu_update1_tr;" "DROP TRIGGER IF EXISTS temp.rbu_update2_tr;" "DROP TRIGGER IF EXISTS temp.rbu_delete_tr;" , 0, 0, &p->zErrmsg ); } if( rc==SQLITE_OK ){ if( pIter->bCleanup ){ rbuObjIterFreeCols(pIter); pIter->bCleanup = 0; rc = sqlite3_step(pIter->pTblIter); if( rc!=SQLITE_ROW ){ rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg); pIter->zTbl = 0; }else{ pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); |
︙ | ︙ | |||
157605 157606 157607 157608 157609 157610 157611 | } } } } } if( rc!=SQLITE_OK ){ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 157807 157808 157809 157810 157811 157812 157813 157814 157815 157816 157817 157818 157819 157820 157821 157822 157823 157824 157825 157826 157827 157828 157829 157830 157831 157832 157833 157834 157835 157836 157837 157838 157839 157840 157841 157842 157843 157844 157845 157846 157847 157848 157849 157850 157851 157852 157853 157854 157855 157856 157857 157858 157859 157860 157861 157862 157863 157864 157865 157866 157867 157868 157869 157870 157871 157872 157873 157874 157875 157876 157877 157878 157879 157880 157881 157882 157883 157884 157885 157886 157887 157888 157889 157890 157891 157892 157893 157894 157895 157896 157897 157898 157899 157900 157901 157902 157903 157904 157905 157906 157907 157908 157909 157910 157911 157912 157913 157914 157915 157916 157917 157918 157919 157920 157921 157922 157923 157924 157925 157926 157927 157928 157929 157930 157931 157932 157933 157934 157935 157936 157937 157938 157939 157940 157941 157942 157943 157944 157945 157946 157947 157948 157949 157950 157951 157952 157953 157954 157955 157956 157957 157958 157959 157960 157961 157962 157963 157964 157965 157966 157967 157968 157969 157970 157971 157972 157973 157974 157975 157976 157977 157978 157979 157980 157981 157982 157983 157984 157985 157986 157987 157988 157989 157990 157991 157992 157993 157994 157995 157996 157997 157998 157999 158000 158001 158002 158003 158004 158005 158006 158007 158008 158009 158010 158011 158012 158013 158014 158015 158016 158017 158018 158019 158020 158021 158022 158023 158024 158025 158026 158027 158028 158029 158030 158031 158032 158033 158034 158035 158036 158037 158038 158039 158040 158041 158042 158043 158044 158045 158046 158047 158048 158049 158050 158051 158052 158053 158054 158055 158056 158057 158058 158059 158060 158061 158062 158063 158064 158065 158066 158067 158068 158069 158070 158071 158072 158073 158074 158075 158076 158077 158078 158079 158080 158081 158082 158083 158084 158085 158086 158087 158088 158089 158090 158091 158092 158093 158094 158095 158096 158097 158098 158099 158100 158101 158102 158103 158104 158105 158106 158107 158108 158109 158110 158111 158112 158113 158114 158115 158116 158117 158118 | } } } } } if( rc!=SQLITE_OK ){ rbuObjIterFinalize(pIter); p->rc = rc; } return rc; } /* ** Initialize the iterator structure passed as the second argument. ** ** If no error occurs, SQLITE_OK is returned and the iterator is left ** pointing to the first entry. Otherwise, an error code and message is ** left in the RBU handle passed as the first argument. A copy of the ** error code is returned. */ static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){ int rc; memset(pIter, 0, sizeof(RbuObjIter)); rc = prepareAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, "SELECT substr(name, 6) FROM sqlite_master " "WHERE type='table' AND name LIKE 'data_%'" ); if( rc==SQLITE_OK ){ rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg, "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' " " FROM main.sqlite_master " " WHERE type='index' AND tbl_name = ?" ); } pIter->bCleanup = 1; p->rc = rc; return rbuObjIterNext(p, pIter); } /* ** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs, ** an error code is stored in the RBU handle passed as the first argument. ** ** If an error has already occurred (p->rc is already set to something other ** than SQLITE_OK), then this function returns NULL without modifying the ** stored error code. In this case it still calls sqlite3_free() on any ** printf() parameters associated with %z conversions. */ static char *rbuMPrintf(sqlite3rbu *p, const char *zFmt, ...){ char *zSql = 0; va_list ap; va_start(ap, zFmt); zSql = sqlite3_vmprintf(zFmt, ap); if( p->rc==SQLITE_OK ){ if( zSql==0 ) p->rc = SQLITE_NOMEM; }else{ sqlite3_free(zSql); zSql = 0; } va_end(ap); return zSql; } /* ** Argument zFmt is a sqlite3_mprintf() style format string. The trailing ** arguments are the usual subsitution values. This function performs ** the printf() style substitutions and executes the result as an SQL ** statement on the RBU handles database. ** ** If an error occurs, an error code and error message is stored in the ** RBU handle. If an error has already occurred when this function is ** called, it is a no-op. */ static int rbuMPrintfExec(sqlite3rbu *p, sqlite3 *db, const char *zFmt, ...){ va_list ap; va_start(ap, zFmt); char *zSql = sqlite3_vmprintf(zFmt, ap); if( p->rc==SQLITE_OK ){ if( zSql==0 ){ p->rc = SQLITE_NOMEM; }else{ p->rc = sqlite3_exec(db, zSql, 0, 0, &p->zErrmsg); } } sqlite3_free(zSql); va_end(ap); return p->rc; } /* ** Attempt to allocate and return a pointer to a zeroed block of nByte ** bytes. ** ** If an error (i.e. an OOM condition) occurs, return NULL and leave an ** error code in the rbu handle passed as the first argument. Or, if an ** error has already occurred when this function is called, return NULL ** immediately without attempting the allocation or modifying the stored ** error code. */ static void *rbuMalloc(sqlite3rbu *p, int nByte){ void *pRet = 0; if( p->rc==SQLITE_OK ){ assert( nByte>0 ); pRet = sqlite3_malloc(nByte); if( pRet==0 ){ p->rc = SQLITE_NOMEM; }else{ memset(pRet, 0, nByte); } } return pRet; } /* ** Allocate and zero the pIter->azTblCol[] and abTblPk[] arrays so that ** there is room for at least nCol elements. If an OOM occurs, store an ** error code in the RBU handle passed as the first argument. */ static void rbuAllocateIterArrays(sqlite3rbu *p, RbuObjIter *pIter, int nCol){ int nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol; char **azNew; azNew = (char**)rbuMalloc(p, nByte); if( azNew ){ pIter->azTblCol = azNew; pIter->azTblType = &azNew[nCol]; pIter->aiSrcOrder = (int*)&pIter->azTblType[nCol]; pIter->abTblPk = (u8*)&pIter->aiSrcOrder[nCol]; pIter->abNotNull = (u8*)&pIter->abTblPk[nCol]; pIter->abIndexed = (u8*)&pIter->abNotNull[nCol]; } } /* ** The first argument must be a nul-terminated string. This function ** returns a copy of the string in memory obtained from sqlite3_malloc(). ** It is the responsibility of the caller to eventually free this memory ** using sqlite3_free(). ** ** If an OOM condition is encountered when attempting to allocate memory, ** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise, ** if the allocation succeeds, (*pRc) is left unchanged. */ static char *rbuStrndup(const char *zStr, int *pRc){ char *zRet = 0; assert( *pRc==SQLITE_OK ); if( zStr ){ int nCopy = strlen(zStr) + 1; zRet = (char*)sqlite3_malloc(nCopy); if( zRet ){ memcpy(zRet, zStr, nCopy); }else{ *pRc = SQLITE_NOMEM; } } return zRet; } /* ** Finalize the statement passed as the second argument. ** ** If the sqlite3_finalize() call indicates that an error occurs, and the ** rbu handle error code is not already set, set the error code and error ** message accordingly. */ static void rbuFinalize(sqlite3rbu *p, sqlite3_stmt *pStmt){ sqlite3 *db = sqlite3_db_handle(pStmt); int rc = sqlite3_finalize(pStmt); if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){ p->rc = rc; p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); } } /* Determine the type of a table. ** ** peType is of type (int*), a pointer to an output parameter of type ** (int). This call sets the output parameter as follows, depending ** on the type of the table specified by parameters dbName and zTbl. ** ** RBU_PK_NOTABLE: No such table. ** RBU_PK_NONE: Table has an implicit rowid. ** RBU_PK_IPK: Table has an explicit IPK column. ** RBU_PK_EXTERNAL: Table has an external PK index. ** RBU_PK_WITHOUT_ROWID: Table is WITHOUT ROWID. ** RBU_PK_VTAB: Table is a virtual table. ** ** Argument *piPk is also of type (int*), and also points to an output ** parameter. Unless the table has an external primary key index ** (i.e. unless *peType is set to 3), then *piPk is set to zero. Or, ** if the table does have an external primary key index, then *piPk ** is set to the root page number of the primary key index before ** returning. ** ** ALGORITHM: ** ** if( no entry exists in sqlite_master ){ ** return RBU_PK_NOTABLE ** }else if( sql for the entry starts with "CREATE VIRTUAL" ){ ** return RBU_PK_VTAB ** }else if( "PRAGMA index_list()" for the table contains a "pk" index ){ ** if( the index that is the pk exists in sqlite_master ){ ** *piPK = rootpage of that index. ** return RBU_PK_EXTERNAL ** }else{ ** return RBU_PK_WITHOUT_ROWID ** } ** }else if( "PRAGMA table_info()" lists one or more "pk" columns ){ ** return RBU_PK_IPK ** }else{ ** return RBU_PK_NONE ** } */ static void rbuTableType( sqlite3rbu *p, const char *zTab, int *peType, int *piTnum, int *piPk ){ /* ** 0) SELECT count(*) FROM sqlite_master where name=%Q AND IsVirtual(%Q) ** 1) PRAGMA index_list = ? ** 2) SELECT count(*) FROM sqlite_master where name=%Q ** 3) PRAGMA table_info = ? */ sqlite3_stmt *aStmt[4] = {0, 0, 0, 0}; *peType = RBU_PK_NOTABLE; *piPk = 0; assert( p->rc==SQLITE_OK ); p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg, sqlite3_mprintf( "SELECT (sql LIKE 'create virtual%%'), rootpage" " FROM sqlite_master" " WHERE name=%Q", zTab )); if( p->rc!=SQLITE_OK || sqlite3_step(aStmt[0])!=SQLITE_ROW ){ /* Either an error, or no such table. */ goto rbuTableType_end; } if( sqlite3_column_int(aStmt[0], 0) ){ *peType = RBU_PK_VTAB; /* virtual table */ goto rbuTableType_end; } *piTnum = sqlite3_column_int(aStmt[0], 1); p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[1], &p->zErrmsg, sqlite3_mprintf("PRAGMA index_list=%Q",zTab) ); if( p->rc ) goto rbuTableType_end; while( sqlite3_step(aStmt[1])==SQLITE_ROW ){ const u8 *zOrig = sqlite3_column_text(aStmt[1], 3); const u8 *zIdx = sqlite3_column_text(aStmt[1], 1); if( zOrig && zIdx && zOrig[0]=='p' ){ p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[2], &p->zErrmsg, sqlite3_mprintf( "SELECT rootpage FROM sqlite_master WHERE name = %Q", zIdx )); if( p->rc==SQLITE_OK ){ if( sqlite3_step(aStmt[2])==SQLITE_ROW ){ *piPk = sqlite3_column_int(aStmt[2], 0); *peType = RBU_PK_EXTERNAL; }else{ *peType = RBU_PK_WITHOUT_ROWID; } } goto rbuTableType_end; } } p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[3], &p->zErrmsg, sqlite3_mprintf("PRAGMA table_info=%Q",zTab) ); if( p->rc==SQLITE_OK ){ while( sqlite3_step(aStmt[3])==SQLITE_ROW ){ if( sqlite3_column_int(aStmt[3],5)>0 ){ *peType = RBU_PK_IPK; /* explicit IPK column */ goto rbuTableType_end; } } *peType = RBU_PK_NONE; } rbuTableType_end: { int i; for(i=0; i<sizeof(aStmt)/sizeof(aStmt[0]); i++){ rbuFinalize(p, aStmt[i]); } } } /* ** This is a helper function for rbuObjIterCacheTableInfo(). It populates ** the pIter->abIndexed[] array. */ static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){ sqlite3_stmt *pList = 0; int bIndex = 0; if( p->rc==SQLITE_OK ){ memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol); p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) |
︙ | ︙ | |||
157924 157925 157926 157927 157928 157929 157930 | p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ int iCid = sqlite3_column_int(pXInfo, 1); if( iCid>=0 ) pIter->abIndexed[iCid] = 1; } | | | | | | | | | | | | | | | | | | | | | | 158126 158127 158128 158129 158130 158131 158132 158133 158134 158135 158136 158137 158138 158139 158140 158141 158142 158143 158144 158145 158146 158147 158148 158149 158150 158151 158152 158153 158154 158155 158156 158157 158158 158159 158160 158161 158162 158163 158164 158165 158166 158167 158168 158169 158170 158171 158172 158173 158174 158175 158176 158177 158178 158179 158180 158181 158182 158183 158184 158185 158186 158187 158188 158189 158190 158191 158192 158193 158194 158195 158196 158197 158198 158199 158200 158201 158202 158203 158204 158205 158206 158207 158208 158209 158210 158211 158212 | p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ int iCid = sqlite3_column_int(pXInfo, 1); if( iCid>=0 ) pIter->abIndexed[iCid] = 1; } rbuFinalize(p, pXInfo); bIndex = 1; } rbuFinalize(p, pList); if( bIndex==0 ) pIter->abIndexed = 0; } /* ** If they are not already populated, populate the pIter->azTblCol[], ** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to ** the table (not index) that the iterator currently points to. ** ** Return SQLITE_OK if successful, or an SQLite error code otherwise. If ** an error does occur, an error code and error message are also left in ** the RBU handle. */ static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){ if( pIter->azTblCol==0 ){ sqlite3_stmt *pStmt = 0; int nCol = 0; int i; /* for() loop iterator variable */ int bRbuRowid = 0; /* If input table has column "rbu_rowid" */ int iOrder = 0; int iTnum = 0; /* Figure out the type of table this step will deal with. */ assert( pIter->eType==0 ); rbuTableType(p, pIter->zTbl, &pIter->eType, &iTnum, &pIter->iPkTnum); if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_NOTABLE ){ p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("no such table: %s", pIter->zTbl); } if( p->rc ) return p->rc; if( pIter->zIdx==0 ) pIter->iTnum = iTnum; assert( pIter->eType==RBU_PK_NONE || pIter->eType==RBU_PK_IPK || pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_WITHOUT_ROWID || pIter->eType==RBU_PK_VTAB ); /* Populate the azTblCol[] and nTblCol variables based on the columns ** of the input table. Ignore any input table columns that begin with ** "rbu_". */ p->rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, sqlite3_mprintf("SELECT * FROM 'data_%q'", pIter->zTbl) ); if( p->rc==SQLITE_OK ){ nCol = sqlite3_column_count(pStmt); rbuAllocateIterArrays(p, pIter, nCol); } for(i=0; p->rc==SQLITE_OK && i<nCol; i++){ const char *zName = (const char*)sqlite3_column_name(pStmt, i); if( sqlite3_strnicmp("rbu_", zName, 4) ){ char *zCopy = rbuStrndup(zName, &p->rc); pIter->aiSrcOrder[pIter->nTblCol] = pIter->nTblCol; pIter->azTblCol[pIter->nTblCol++] = zCopy; } else if( 0==sqlite3_stricmp("rbu_rowid", zName) ){ bRbuRowid = 1; } } sqlite3_finalize(pStmt); pStmt = 0; if( p->rc==SQLITE_OK && bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) ){ p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf( "table data_%q %s rbu_rowid column", pIter->zTbl, (bRbuRowid ? "may not have" : "requires") ); } /* Check that all non-HIDDEN columns in the destination table are also ** present in the input table. Populate the abTblPk[], azTblType[] and ** aiTblOrder[] arrays at the same time. */ if( p->rc==SQLITE_OK ){ |
︙ | ︙ | |||
158029 158030 158031 158032 158033 158034 158035 | const char *zType = (const char*)sqlite3_column_text(pStmt, 2); if( i!=iOrder ){ SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]); SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]); } | | | | | | | | | | | | | | | 158231 158232 158233 158234 158235 158236 158237 158238 158239 158240 158241 158242 158243 158244 158245 158246 158247 158248 158249 158250 158251 158252 158253 158254 158255 158256 158257 158258 158259 158260 158261 158262 158263 158264 158265 158266 158267 158268 158269 158270 158271 158272 158273 158274 158275 158276 158277 158278 158279 158280 158281 158282 158283 158284 158285 158286 158287 158288 158289 158290 158291 158292 158293 158294 158295 158296 158297 158298 158299 158300 158301 158302 158303 158304 158305 158306 158307 158308 158309 158310 | const char *zType = (const char*)sqlite3_column_text(pStmt, 2); if( i!=iOrder ){ SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]); SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]); } pIter->azTblType[iOrder] = rbuStrndup(zType, &p->rc); pIter->abTblPk[iOrder] = (iPk!=0); pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0); iOrder++; } } rbuFinalize(p, pStmt); rbuObjIterCacheIndexedCols(p, pIter); assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 ); } return p->rc; } /* ** This function constructs and returns a pointer to a nul-terminated ** string containing some SQL clause or list based on one or more of the ** column names currently stored in the pIter->azTblCol[] array. */ static char *rbuObjIterGetCollist( sqlite3rbu *p, /* RBU object */ RbuObjIter *pIter /* Object iterator for column names */ ){ char *zList = 0; const char *zSep = ""; int i; for(i=0; i<pIter->nTblCol; i++){ const char *z = pIter->azTblCol[i]; zList = rbuMPrintf(p, "%z%s\"%w\"", zList, zSep, z); zSep = ", "; } return zList; } /* ** This function is used to create a SELECT list (the list of SQL ** expressions that follows a SELECT keyword) for a SELECT statement ** used to read from an data_xxx or rbu_tmp_xxx table while updating the ** index object currently indicated by the iterator object passed as the ** second argument. A "PRAGMA index_xinfo = <idxname>" statement is used ** to obtain the required information. ** ** If the index is of the following form: ** ** CREATE INDEX i1 ON t1(c, b COLLATE nocase); ** ** and "t1" is a table with an explicit INTEGER PRIMARY KEY column ** "ipk", the returned string is: ** ** "`c` COLLATE 'BINARY', `b` COLLATE 'NOCASE', `ipk` COLLATE 'BINARY'" ** ** As well as the returned string, three other malloc'd strings are ** returned via output parameters. As follows: ** ** pzImposterCols: ... ** pzImposterPk: ... ** pzWhere: ... */ static char *rbuObjIterGetIndexCols( sqlite3rbu *p, /* RBU object */ RbuObjIter *pIter, /* Object iterator for column names */ char **pzImposterCols, /* OUT: Columns for imposter table */ char **pzImposterPk, /* OUT: Imposter PK clause */ char **pzWhere, /* OUT: WHERE clause */ int *pnBind /* OUT: Trbul number of columns */ ){ int rc = p->rc; /* Error code */ int rc2; /* sqlite3_finalize() return code */ char *zRet = 0; /* String to return */ char *zImpCols = 0; /* String to return via *pzImposterCols */ char *zImpPK = 0; /* String to return via *pzImposterPK */ char *zWhere = 0; /* String to return via *pzWhere */ |
︙ | ︙ | |||
158123 158124 158125 158126 158127 158128 158129 | int bDesc = sqlite3_column_int(pXInfo, 3); const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); const char *zCol; const char *zType; if( iCid<0 ){ /* An integer primary key. If the table has an explicit IPK, use | | | | | | | | 158325 158326 158327 158328 158329 158330 158331 158332 158333 158334 158335 158336 158337 158338 158339 158340 158341 158342 158343 158344 158345 158346 158347 158348 158349 158350 158351 158352 158353 158354 158355 158356 158357 158358 158359 158360 158361 158362 158363 158364 158365 | int bDesc = sqlite3_column_int(pXInfo, 3); const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); const char *zCol; const char *zType; if( iCid<0 ){ /* An integer primary key. If the table has an explicit IPK, use ** its name. Otherwise, use "rbu_rowid". */ if( pIter->eType==RBU_PK_IPK ){ int i; for(i=0; pIter->abTblPk[i]==0; i++); assert( i<pIter->nTblCol ); zCol = pIter->azTblCol[i]; }else{ zCol = "rbu_rowid"; } zType = "INTEGER"; }else{ zCol = pIter->azTblCol[iCid]; zType = pIter->azTblType[iCid]; } zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate); if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){ const char *zOrder = (bDesc ? " DESC" : ""); zImpPK = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s", zImpPK, zCom, nBind, zCol, zOrder ); } zImpCols = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\" %s COLLATE %Q", zImpCols, zCom, nBind, zCol, zType, zCollate ); zWhere = sqlite3_mprintf( "%z%s\"rbu_imp_%d%w\" IS ?", zWhere, zAnd, nBind, zCol ); if( zRet==0 || zImpPK==0 || zImpCols==0 || zWhere==0 ) rc = SQLITE_NOMEM; zCom = ", "; zAnd = " AND "; nBind++; } |
︙ | ︙ | |||
158187 158188 158189 158190 158191 158192 158193 | ** Assuming the current table columns are "a", "b" and "c", and the zObj ** paramter is passed "old", return a string of the form: ** ** "old.a, old.b, old.b" ** ** With the column names escaped. ** | | | | | | 158389 158390 158391 158392 158393 158394 158395 158396 158397 158398 158399 158400 158401 158402 158403 158404 158405 158406 158407 158408 | ** Assuming the current table columns are "a", "b" and "c", and the zObj ** paramter is passed "old", return a string of the form: ** ** "old.a, old.b, old.b" ** ** With the column names escaped. ** ** For tables with implicit rowids - RBU_PK_EXTERNAL and RBU_PK_NONE, append ** the text ", old._rowid_" to the returned value. */ static char *rbuObjIterGetOldlist( sqlite3rbu *p, RbuObjIter *pIter, const char *zObj ){ char *zList = 0; if( p->rc==SQLITE_OK && pIter->abIndexed ){ const char *zS = ""; int i; for(i=0; i<pIter->nTblCol; i++){ |
︙ | ︙ | |||
158214 158215 158216 158217 158218 158219 158220 | if( zList==0 ){ p->rc = SQLITE_NOMEM; break; } } /* For a table with implicit rowids, append "old._rowid_" to the list. */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 158416 158417 158418 158419 158420 158421 158422 158423 158424 158425 158426 158427 158428 158429 158430 158431 158432 158433 158434 158435 158436 158437 158438 158439 158440 158441 158442 158443 158444 158445 158446 158447 158448 158449 158450 158451 158452 158453 158454 158455 158456 158457 158458 158459 158460 158461 158462 158463 158464 158465 158466 158467 158468 158469 158470 158471 158472 158473 158474 158475 158476 158477 158478 158479 158480 158481 158482 158483 158484 158485 158486 158487 158488 158489 158490 158491 158492 158493 158494 158495 158496 158497 158498 158499 158500 158501 158502 158503 158504 158505 158506 158507 158508 158509 158510 158511 158512 158513 158514 158515 158516 158517 158518 158519 158520 158521 158522 158523 158524 158525 158526 158527 158528 158529 158530 158531 158532 158533 158534 158535 158536 158537 158538 158539 158540 158541 158542 158543 158544 158545 158546 158547 158548 158549 158550 158551 158552 158553 158554 158555 158556 158557 158558 158559 158560 158561 158562 158563 158564 158565 158566 158567 158568 158569 158570 158571 158572 158573 158574 158575 158576 158577 158578 158579 158580 158581 158582 158583 158584 158585 158586 | if( zList==0 ){ p->rc = SQLITE_NOMEM; break; } } /* For a table with implicit rowids, append "old._rowid_" to the list. */ if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ zList = rbuMPrintf(p, "%z, %s._rowid_", zList, zObj); } } return zList; } /* ** Return an expression that can be used in a WHERE clause to match the ** primary key of the current table. For example, if the table is: ** ** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c)); ** ** Return the string: ** ** "b = ?1 AND c = ?2" */ static char *rbuObjIterGetWhere( sqlite3rbu *p, RbuObjIter *pIter ){ char *zList = 0; if( pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE ){ zList = rbuMPrintf(p, "_rowid_ = ?%d", pIter->nTblCol+1); }else if( pIter->eType==RBU_PK_EXTERNAL ){ const char *zSep = ""; int i; for(i=0; i<pIter->nTblCol; i++){ if( pIter->abTblPk[i] ){ zList = rbuMPrintf(p, "%z%sc%d=?%d", zList, zSep, i, i+1); zSep = " AND "; } } zList = rbuMPrintf(p, "_rowid_ = (SELECT id FROM rbu_imposter2 WHERE %z)", zList ); }else{ const char *zSep = ""; int i; for(i=0; i<pIter->nTblCol; i++){ if( pIter->abTblPk[i] ){ const char *zCol = pIter->azTblCol[i]; zList = rbuMPrintf(p, "%z%s\"%w\"=?%d", zList, zSep, zCol, i+1); zSep = " AND "; } } } return zList; } /* ** The SELECT statement iterating through the keys for the current object ** (p->objiter.pSelect) currently points to a valid row. However, there ** is something wrong with the rbu_control value in the rbu_control value ** stored in the (p->nCol+1)'th column. Set the error code and error message ** of the RBU handle to something reflecting this. */ static void rbuBadControlError(sqlite3rbu *p){ p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("invalid rbu_control value"); } /* ** Return a nul-terminated string containing the comma separated list of ** assignments that should be included following the "SET" keyword of ** an UPDATE statement used to update the table object that the iterator ** passed as the second argument currently points to if the rbu_control ** column of the data_xxx table entry is set to zMask. ** ** The memory for the returned string is obtained from sqlite3_malloc(). ** It is the responsibility of the caller to eventually free it using ** sqlite3_free(). ** ** If an OOM error is encountered when allocating space for the new ** string, an error code is left in the rbu handle passed as the first ** argument and NULL is returned. Or, if an error has already occurred ** when this function is called, NULL is returned immediately, without ** attempting the allocation or modifying the stored error code. */ static char *rbuObjIterGetSetlist( sqlite3rbu *p, RbuObjIter *pIter, const char *zMask ){ char *zList = 0; if( p->rc==SQLITE_OK ){ int i; if( strlen(zMask)!=pIter->nTblCol ){ rbuBadControlError(p); }else{ const char *zSep = ""; for(i=0; i<pIter->nTblCol; i++){ char c = zMask[pIter->aiSrcOrder[i]]; if( c=='x' ){ zList = rbuMPrintf(p, "%z%s\"%w\"=?%d", zList, zSep, pIter->azTblCol[i], i+1 ); zSep = ", "; } if( c=='d' ){ zList = rbuMPrintf(p, "%z%s\"%w\"=rbu_delta(\"%w\", ?%d)", zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1 ); zSep = ", "; } } } } return zList; } /* ** Return a nul-terminated string consisting of nByte comma separated ** "?" expressions. For example, if nByte is 3, return a pointer to ** a buffer containing the string "?,?,?". ** ** The memory for the returned string is obtained from sqlite3_malloc(). ** It is the responsibility of the caller to eventually free it using ** sqlite3_free(). ** ** If an OOM error is encountered when allocating space for the new ** string, an error code is left in the rbu handle passed as the first ** argument and NULL is returned. Or, if an error has already occurred ** when this function is called, NULL is returned immediately, without ** attempting the allocation or modifying the stored error code. */ static char *rbuObjIterGetBindlist(sqlite3rbu *p, int nBind){ char *zRet = 0; int nByte = nBind*2 + 1; zRet = (char*)rbuMalloc(p, nByte); if( zRet ){ int i; for(i=0; i<nBind; i++){ zRet[i*2] = '?'; zRet[i*2+1] = (i+1==nBind) ? '\0' : ','; } } return zRet; } /* ** The iterator currently points to a table (not index) of type ** RBU_PK_WITHOUT_ROWID. This function creates the PRIMARY KEY ** declaration for the corresponding imposter table. For example, ** if the iterator points to a table created as: ** ** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, a DESC)) WITHOUT ROWID ** ** this function returns: ** ** PRIMARY KEY("b", "a" DESC) */ static char *rbuWithoutRowidPK(sqlite3rbu *p, RbuObjIter *pIter){ char *z = 0; assert( pIter->zIdx==0 ); if( p->rc==SQLITE_OK ){ const char *zSep = "PRIMARY KEY("; sqlite3_stmt *pXList = 0; /* PRAGMA index_list = (pIter->zTbl) */ sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = <pk-index> */ |
︙ | ︙ | |||
158393 158394 158395 158396 158397 158398 158399 | p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); } break; } } | | | | | | | | | | 158595 158596 158597 158598 158599 158600 158601 158602 158603 158604 158605 158606 158607 158608 158609 158610 158611 158612 158613 158614 158615 158616 158617 158618 158619 158620 158621 158622 158623 158624 158625 158626 158627 158628 158629 158630 158631 158632 158633 158634 158635 158636 158637 158638 158639 158640 158641 158642 158643 158644 158645 158646 | p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); } break; } } rbuFinalize(p, pXList); while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ if( sqlite3_column_int(pXInfo, 5) ){ /* int iCid = sqlite3_column_int(pXInfo, 0); */ const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2); const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : ""; z = rbuMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc); zSep = ", "; } } z = rbuMPrintf(p, "%z)", z); rbuFinalize(p, pXInfo); } return z; } /* ** This function creates the second imposter table used when writing to ** a table b-tree where the table has an external primary key. If the ** iterator passed as the second argument does not currently point to ** a table (not index) with an external primary key, this function is a ** no-op. ** ** Assuming the iterator does point to a table with an external PK, this ** function creates a WITHOUT ROWID imposter table named "rbu_imposter2" ** used to access that PK index. For example, if the target table is ** declared as follows: ** ** CREATE TABLE t1(a, b TEXT, c REAL, PRIMARY KEY(b, c)); ** ** then the imposter table schema is: ** ** CREATE TABLE rbu_imposter2(c1 TEXT, c2 REAL, id INTEGER) WITHOUT ROWID; ** */ static void rbuCreateImposterTable2(sqlite3rbu *p, RbuObjIter *pIter){ if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_EXTERNAL ){ int tnum = pIter->iPkTnum; /* Root page of PK index */ sqlite3_stmt *pQuery = 0; /* SELECT name ... WHERE rootpage = $tnum */ const char *zIdx = 0; /* Name of PK index */ sqlite3_stmt *pXInfo = 0; /* PRAGMA main.index_xinfo = $zIdx */ const char *zComma = ""; char *zCols = 0; /* Used to build up list of table cols */ char *zPk = 0; /* Used to build up table PK declaration */ |
︙ | ︙ | |||
158456 158457 158458 158459 158460 158461 158462 | } } if( zIdx ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); } | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 158658 158659 158660 158661 158662 158663 158664 158665 158666 158667 158668 158669 158670 158671 158672 158673 158674 158675 158676 158677 158678 158679 158680 158681 158682 158683 158684 158685 158686 158687 158688 158689 158690 158691 158692 158693 158694 158695 158696 158697 158698 158699 158700 158701 158702 158703 158704 158705 158706 158707 158708 158709 158710 158711 158712 158713 158714 158715 158716 158717 158718 158719 158720 158721 158722 158723 158724 158725 158726 158727 158728 158729 158730 158731 158732 158733 158734 158735 158736 158737 158738 158739 158740 158741 158742 158743 158744 158745 158746 158747 158748 158749 158750 158751 158752 158753 158754 158755 158756 158757 158758 158759 158760 158761 158762 158763 158764 158765 158766 158767 158768 158769 158770 158771 158772 158773 158774 158775 158776 158777 158778 158779 158780 158781 158782 158783 158784 158785 158786 158787 158788 158789 158790 158791 158792 158793 158794 158795 158796 158797 158798 | } } if( zIdx ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); } rbuFinalize(p, pQuery); while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ int bKey = sqlite3_column_int(pXInfo, 5); if( bKey ){ int iCid = sqlite3_column_int(pXInfo, 1); int bDesc = sqlite3_column_int(pXInfo, 3); const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma, iCid, pIter->azTblType[iCid], zCollate ); zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":""); zComma = ", "; } } zCols = rbuMPrintf(p, "%z, id INTEGER", zCols); rbuFinalize(p, pXInfo); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); rbuMPrintfExec(p, p->dbMain, "CREATE TABLE rbu_imposter2(%z, PRIMARY KEY(%z)) WITHOUT ROWID", zCols, zPk ); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); } } /* ** If an error has already occurred when this function is called, it ** immediately returns zero (without doing any work). Or, if an error ** occurs during the execution of this function, it sets the error code ** in the sqlite3rbu object indicated by the first argument and returns ** zero. ** ** The iterator passed as the second argument is guaranteed to point to ** a table (not an index) when this function is called. This function ** attempts to create any imposter table required to write to the main ** table b-tree of the table before returning. Non-zero is returned if ** an imposter table are created, or zero otherwise. ** ** An imposter table is required in all cases except RBU_PK_VTAB. Only ** virtual tables are written to directly. The imposter table has the ** same schema as the actual target table (less any UNIQUE constraints). ** More precisely, the "same schema" means the same columns, types, ** collation sequences. For tables that do not have an external PRIMARY ** KEY, it also means the same PRIMARY KEY declaration. */ static void rbuCreateImposterTable(sqlite3rbu *p, RbuObjIter *pIter){ if( p->rc==SQLITE_OK && pIter->eType!=RBU_PK_VTAB ){ int tnum = pIter->iTnum; const char *zComma = ""; char *zSql = 0; int iCol; sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); for(iCol=0; p->rc==SQLITE_OK && iCol<pIter->nTblCol; iCol++){ const char *zPk = ""; const char *zCol = pIter->azTblCol[iCol]; const char *zColl = 0; p->rc = sqlite3_table_column_metadata( p->dbMain, "main", pIter->zTbl, zCol, 0, &zColl, 0, 0, 0 ); if( pIter->eType==RBU_PK_IPK && pIter->abTblPk[iCol] ){ /* If the target table column is an "INTEGER PRIMARY KEY", add ** "PRIMARY KEY" to the imposter table column declaration. */ zPk = "PRIMARY KEY "; } zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s", zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl, (pIter->abNotNull[iCol] ? " NOT NULL" : "") ); zComma = ", "; } if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ char *zPk = rbuWithoutRowidPK(p, pIter); if( zPk ){ zSql = rbuMPrintf(p, "%z, %z", zSql, zPk); } } sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); rbuMPrintfExec(p, p->dbMain, "CREATE TABLE \"rbu_imp_%w\"(%z)%s", pIter->zTbl, zSql, (pIter->eType==RBU_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "") ); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); } } /* ** Prepare a statement used to insert rows into the "rbu_tmp_xxx" table. ** Specifically a statement of the form: ** ** INSERT INTO rbu_tmp_xxx VALUES(?, ?, ? ...); ** ** The number of bound variables is equal to the number of columns in ** the target table, plus one (for the rbu_control column), plus one more ** (for the rbu_rowid column) if the target table is an implicit IPK or ** virtual table. */ static void rbuObjIterPrepareTmpInsert( sqlite3rbu *p, RbuObjIter *pIter, const char *zCollist, const char *zRbuRowid ){ int bRbuRowid = (pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE); char *zBind = rbuObjIterGetBindlist(p, pIter->nTblCol + 1 + bRbuRowid); if( zBind ){ assert( pIter->pTmpInsert==0 ); p->rc = prepareFreeAndCollectError( p->dbRbu, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf( "INSERT INTO %s.'rbu_tmp_%q'(rbu_control,%s%s) VALUES(%z)", p->zStateDb, pIter->zTbl, zCollist, zRbuRowid, zBind )); } } static void rbuTmpInsertFunc( sqlite3_context *pCtx, int nVal, sqlite3_value **apVal ){ sqlite3rbu *p = sqlite3_user_data(pCtx); int rc = SQLITE_OK; int i; for(i=0; rc==SQLITE_OK && i<nVal; i++){ rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]); } if( rc==SQLITE_OK ){ |
︙ | ︙ | |||
158604 158605 158606 158607 158608 158609 158610 | } /* ** Ensure that the SQLite statement handles required to update the ** target database object currently indicated by the iterator passed ** as the second argument are available. */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 158806 158807 158808 158809 158810 158811 158812 158813 158814 158815 158816 158817 158818 158819 158820 158821 158822 158823 158824 158825 158826 158827 158828 158829 158830 158831 158832 158833 158834 158835 158836 158837 158838 158839 158840 158841 158842 158843 158844 158845 158846 158847 158848 158849 158850 158851 158852 158853 158854 158855 158856 158857 158858 158859 158860 158861 158862 158863 158864 158865 158866 158867 158868 158869 158870 158871 158872 158873 158874 158875 158876 158877 158878 158879 158880 158881 158882 158883 158884 158885 158886 158887 158888 158889 158890 158891 158892 158893 158894 158895 158896 158897 158898 158899 158900 158901 158902 158903 158904 158905 158906 158907 158908 158909 158910 158911 158912 158913 158914 158915 158916 158917 158918 158919 158920 158921 158922 158923 158924 158925 158926 158927 158928 158929 158930 158931 158932 158933 158934 158935 158936 158937 158938 158939 158940 158941 158942 158943 158944 158945 158946 158947 158948 158949 158950 158951 158952 158953 158954 158955 158956 158957 158958 158959 158960 158961 158962 158963 158964 158965 158966 158967 158968 158969 158970 158971 158972 158973 158974 158975 158976 158977 158978 158979 158980 158981 158982 158983 158984 158985 158986 158987 158988 158989 158990 158991 158992 158993 158994 158995 158996 158997 158998 158999 159000 159001 159002 159003 159004 159005 159006 159007 159008 159009 159010 159011 159012 159013 159014 159015 159016 159017 159018 159019 159020 159021 159022 159023 159024 159025 159026 159027 159028 159029 159030 159031 159032 159033 159034 159035 159036 159037 159038 159039 159040 159041 159042 159043 159044 159045 159046 159047 159048 159049 159050 159051 159052 159053 159054 159055 159056 159057 159058 159059 159060 159061 159062 159063 159064 159065 159066 159067 159068 159069 159070 159071 159072 159073 159074 159075 159076 159077 159078 159079 159080 159081 159082 159083 159084 159085 159086 159087 159088 159089 159090 159091 159092 159093 159094 159095 159096 159097 159098 159099 159100 159101 159102 159103 159104 159105 159106 159107 159108 159109 159110 159111 159112 159113 159114 159115 159116 159117 159118 159119 159120 159121 159122 159123 159124 159125 159126 159127 159128 159129 159130 159131 159132 159133 159134 159135 159136 159137 159138 159139 159140 159141 159142 159143 159144 159145 | } /* ** Ensure that the SQLite statement handles required to update the ** target database object currently indicated by the iterator passed ** as the second argument are available. */ static int rbuObjIterPrepareAll( sqlite3rbu *p, RbuObjIter *pIter, int nOffset /* Add "LIMIT -1 OFFSET $nOffset" to SELECT */ ){ assert( pIter->bCleanup==0 ); if( pIter->pSelect==0 && rbuObjIterCacheTableInfo(p, pIter)==SQLITE_OK ){ const int tnum = pIter->iTnum; char *zCollist = 0; /* List of indexed columns */ char **pz = &p->zErrmsg; const char *zIdx = pIter->zIdx; char *zLimit = 0; if( nOffset ){ zLimit = sqlite3_mprintf(" LIMIT -1 OFFSET %d", nOffset); if( !zLimit ) p->rc = SQLITE_NOMEM; } if( zIdx ){ const char *zTbl = pIter->zTbl; char *zImposterCols = 0; /* Columns for imposter table */ char *zImposterPK = 0; /* Primary key declaration for imposter */ char *zWhere = 0; /* WHERE clause on PK columns */ char *zBind = 0; int nBind = 0; assert( pIter->eType!=RBU_PK_VTAB ); zCollist = rbuObjIterGetIndexCols( p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind ); zBind = rbuObjIterGetBindlist(p, nBind); /* Create the imposter table used to write to this index. */ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum); rbuMPrintfExec(p, p->dbMain, "CREATE TABLE \"rbu_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID", zTbl, zImposterCols, zImposterPK ); sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); /* Create the statement to insert index entries */ pIter->nCol = nBind; if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError( p->dbMain, &pIter->pInsert, &p->zErrmsg, sqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind) ); } /* And to delete index entries */ if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError( p->dbMain, &pIter->pDelete, &p->zErrmsg, sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere) ); } /* Create the SELECT statement to read keys in sorted order */ if( p->rc==SQLITE_OK ){ char *zSql; if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ zSql = sqlite3_mprintf( "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s", zCollist, p->zStateDb, pIter->zTbl, zCollist, zLimit ); }else{ zSql = sqlite3_mprintf( "SELECT %s, rbu_control FROM 'data_%q' " "WHERE typeof(rbu_control)='integer' AND rbu_control!=1 " "UNION ALL " "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' " "ORDER BY %s%s", zCollist, pIter->zTbl, zCollist, p->zStateDb, pIter->zTbl, zCollist, zLimit ); } p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql); } sqlite3_free(zImposterCols); sqlite3_free(zImposterPK); sqlite3_free(zWhere); sqlite3_free(zBind); }else{ int bRbuRowid = (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE); const char *zTbl = pIter->zTbl; /* Table this step applies to */ const char *zWrite; /* Imposter table name */ char *zBindings = rbuObjIterGetBindlist(p, pIter->nTblCol + bRbuRowid); char *zWhere = rbuObjIterGetWhere(p, pIter); char *zOldlist = rbuObjIterGetOldlist(p, pIter, "old"); char *zNewlist = rbuObjIterGetOldlist(p, pIter, "new"); zCollist = rbuObjIterGetCollist(p, pIter); pIter->nCol = pIter->nTblCol; /* Create the SELECT statement to read keys from data_xxx */ if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, sqlite3_mprintf( "SELECT %s, rbu_control%s FROM 'data_%q'%s", zCollist, (bRbuRowid ? ", rbu_rowid" : ""), zTbl, zLimit ) ); } /* Create the imposter table or tables (if required). */ rbuCreateImposterTable(p, pIter); rbuCreateImposterTable2(p, pIter); zWrite = (pIter->eType==RBU_PK_VTAB ? "" : "rbu_imp_"); /* Create the INSERT statement to write to the target PK b-tree */ if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz, sqlite3_mprintf( "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)", zWrite, zTbl, zCollist, (bRbuRowid ? ", _rowid_" : ""), zBindings ) ); } /* Create the DELETE statement to write to the target PK b-tree */ if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz, sqlite3_mprintf( "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere ) ); } if( pIter->abIndexed ){ const char *zRbuRowid = ""; if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ zRbuRowid = ", rbu_rowid"; } /* Create the rbu_tmp_xxx table and the triggers to populate it. */ rbuMPrintfExec(p, p->dbRbu, "CREATE TABLE IF NOT EXISTS %s.'rbu_tmp_%q' AS " "SELECT *%s FROM 'data_%q' WHERE 0;" , p->zStateDb , zTbl, (pIter->eType==RBU_PK_EXTERNAL ? ", 0 AS rbu_rowid" : "") , zTbl ); rbuMPrintfExec(p, p->dbMain, "CREATE TEMP TRIGGER rbu_delete_tr BEFORE DELETE ON \"%s%w\" " "BEGIN " " SELECT rbu_tmp_insert(2, %s);" "END;" "CREATE TEMP TRIGGER rbu_update1_tr BEFORE UPDATE ON \"%s%w\" " "BEGIN " " SELECT rbu_tmp_insert(2, %s);" "END;" "CREATE TEMP TRIGGER rbu_update2_tr AFTER UPDATE ON \"%s%w\" " "BEGIN " " SELECT rbu_tmp_insert(3, %s);" "END;", zWrite, zTbl, zOldlist, zWrite, zTbl, zOldlist, zWrite, zTbl, zNewlist ); if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ rbuMPrintfExec(p, p->dbMain, "CREATE TEMP TRIGGER rbu_insert_tr AFTER INSERT ON \"%s%w\" " "BEGIN " " SELECT rbu_tmp_insert(0, %s);" "END;", zWrite, zTbl, zNewlist ); } rbuObjIterPrepareTmpInsert(p, pIter, zCollist, zRbuRowid); } sqlite3_free(zWhere); sqlite3_free(zOldlist); sqlite3_free(zNewlist); sqlite3_free(zBindings); } sqlite3_free(zCollist); sqlite3_free(zLimit); } return p->rc; } /* ** Set output variable *ppStmt to point to an UPDATE statement that may ** be used to update the imposter table for the main table b-tree of the ** table object that pIter currently points to, assuming that the ** rbu_control column of the data_xyz table contains zMask. ** ** If the zMask string does not specify any columns to update, then this ** is not an error. Output variable *ppStmt is set to NULL in this case. */ static int rbuGetUpdateStmt( sqlite3rbu *p, /* RBU handle */ RbuObjIter *pIter, /* Object iterator */ const char *zMask, /* rbu_control value ('x.x.') */ sqlite3_stmt **ppStmt /* OUT: UPDATE statement handle */ ){ RbuUpdateStmt **pp; RbuUpdateStmt *pUp = 0; int nUp = 0; /* In case an error occurs */ *ppStmt = 0; /* Search for an existing statement. If one is found, shift it to the front ** of the LRU queue and return immediately. Otherwise, leave nUp pointing ** to the number of statements currently in the cache and pUp to the ** last object in the list. */ for(pp=&pIter->pRbuUpdate; *pp; pp=&((*pp)->pNext)){ pUp = *pp; if( strcmp(pUp->zMask, zMask)==0 ){ *pp = pUp->pNext; pUp->pNext = pIter->pRbuUpdate; pIter->pRbuUpdate = pUp; *ppStmt = pUp->pUpdate; return SQLITE_OK; } nUp++; } assert( pUp==0 || pUp->pNext==0 ); if( nUp>=SQLITE_RBU_UPDATE_CACHESIZE ){ for(pp=&pIter->pRbuUpdate; *pp!=pUp; pp=&((*pp)->pNext)); *pp = 0; sqlite3_finalize(pUp->pUpdate); pUp->pUpdate = 0; }else{ pUp = (RbuUpdateStmt*)rbuMalloc(p, sizeof(RbuUpdateStmt)+pIter->nTblCol+1); } if( pUp ){ char *zWhere = rbuObjIterGetWhere(p, pIter); char *zSet = rbuObjIterGetSetlist(p, pIter, zMask); char *zUpdate = 0; pUp->zMask = (char*)&pUp[1]; memcpy(pUp->zMask, zMask, pIter->nTblCol); pUp->pNext = pIter->pRbuUpdate; pIter->pRbuUpdate = pUp; if( zSet ){ const char *zPrefix = ""; if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_"; zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s", zPrefix, pIter->zTbl, zSet, zWhere ); p->rc = prepareFreeAndCollectError( p->dbMain, &pUp->pUpdate, &p->zErrmsg, zUpdate ); *ppStmt = pUp->pUpdate; } sqlite3_free(zWhere); sqlite3_free(zSet); } return p->rc; } static sqlite3 *rbuOpenDbhandle(sqlite3rbu *p, const char *zName){ sqlite3 *db = 0; if( p->rc==SQLITE_OK ){ const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI; p->rc = sqlite3_open_v2(zName, &db, flags, p->zVfsName); if( p->rc ){ p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); sqlite3_close(db); db = 0; } } return db; } /* ** Open the database handle and attach the RBU database as "rbu". If an ** error occurs, leave an error code and message in the RBU handle. */ static void rbuOpenDatabase(sqlite3rbu *p){ assert( p->rc==SQLITE_OK ); assert( p->dbMain==0 && p->dbRbu==0 ); p->eStage = 0; p->dbMain = rbuOpenDbhandle(p, p->zTarget); p->dbRbu = rbuOpenDbhandle(p, p->zRbu); /* If using separate RBU and state databases, attach the state database to ** the RBU db handle now. */ if( p->zState ){ rbuMPrintfExec(p, p->dbRbu, "ATTACH %Q AS stat", p->zState); memcpy(p->zStateDb, "stat", 4); }else{ memcpy(p->zStateDb, "main", 4); } if( p->rc==SQLITE_OK ){ p->rc = sqlite3_create_function(p->dbMain, "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0 ); } if( p->rc==SQLITE_OK ){ p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); } rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master"); /* Mark the database file just opened as an RBU target database. If ** this call returns SQLITE_NOTFOUND, then the RBU vfs is not in use. ** This is an error. */ if( p->rc==SQLITE_OK ){ p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); } if( p->rc==SQLITE_NOTFOUND ){ p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("rbu vfs not found"); } } /* ** This routine is a copy of the sqlite3FileSuffix3() routine from the core. ** It is a no-op unless SQLITE_ENABLE_8_3_NAMES is defined. ** |
︙ | ︙ | |||
158953 158954 158955 158956 158957 158958 158959 | ** Examples: ** ** test.db-journal => test.nal ** test.db-wal => test.wal ** test.db-shm => test.shm ** test.db-mj7f3319fa => test.9fa */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 159155 159156 159157 159158 159159 159160 159161 159162 159163 159164 159165 159166 159167 159168 159169 159170 159171 159172 159173 159174 159175 159176 159177 159178 159179 159180 159181 159182 159183 159184 159185 159186 159187 159188 159189 159190 159191 159192 159193 159194 159195 159196 159197 159198 159199 159200 159201 159202 159203 159204 159205 159206 159207 159208 159209 159210 159211 159212 159213 159214 159215 159216 159217 159218 159219 159220 159221 159222 159223 159224 159225 159226 159227 159228 159229 159230 159231 159232 159233 159234 159235 159236 159237 159238 159239 159240 159241 159242 159243 159244 159245 159246 159247 159248 159249 159250 159251 159252 159253 159254 159255 159256 159257 159258 159259 159260 159261 159262 159263 159264 159265 159266 159267 159268 159269 159270 159271 159272 159273 159274 159275 159276 159277 159278 159279 159280 159281 159282 159283 159284 159285 159286 159287 159288 159289 159290 159291 159292 159293 159294 159295 159296 159297 159298 159299 159300 159301 159302 159303 159304 159305 159306 159307 159308 159309 159310 159311 159312 159313 159314 159315 159316 159317 159318 159319 159320 159321 159322 159323 159324 159325 159326 159327 159328 159329 159330 159331 159332 159333 159334 159335 159336 159337 159338 159339 159340 159341 159342 159343 159344 159345 159346 159347 159348 159349 159350 159351 159352 159353 159354 159355 159356 159357 159358 159359 159360 159361 159362 159363 159364 159365 159366 159367 159368 159369 159370 159371 159372 159373 159374 159375 159376 159377 159378 159379 159380 159381 159382 159383 159384 159385 159386 159387 159388 159389 159390 159391 159392 159393 159394 159395 159396 159397 159398 159399 159400 159401 159402 159403 159404 159405 159406 159407 159408 159409 159410 159411 159412 159413 159414 159415 159416 159417 159418 159419 159420 159421 159422 159423 159424 159425 159426 159427 159428 159429 159430 159431 159432 159433 159434 159435 159436 159437 159438 159439 159440 159441 159442 159443 159444 159445 159446 159447 159448 159449 159450 159451 159452 159453 159454 159455 159456 159457 159458 159459 159460 159461 159462 159463 159464 159465 159466 159467 159468 159469 159470 159471 159472 159473 159474 159475 159476 159477 159478 159479 159480 159481 159482 159483 159484 159485 159486 159487 159488 159489 159490 159491 159492 159493 159494 159495 159496 159497 159498 159499 159500 159501 159502 159503 159504 159505 159506 159507 159508 159509 159510 159511 159512 159513 159514 159515 159516 159517 159518 159519 159520 159521 159522 159523 159524 159525 159526 159527 159528 159529 159530 159531 159532 159533 159534 159535 159536 159537 159538 159539 159540 159541 159542 159543 159544 159545 159546 159547 159548 159549 159550 159551 159552 159553 159554 159555 159556 159557 159558 159559 159560 159561 159562 159563 159564 159565 159566 159567 159568 159569 159570 159571 159572 159573 159574 159575 159576 159577 159578 159579 159580 159581 159582 159583 159584 159585 159586 159587 159588 159589 159590 159591 159592 159593 159594 159595 159596 159597 159598 159599 159600 159601 159602 159603 159604 159605 159606 159607 159608 159609 159610 159611 159612 159613 159614 159615 159616 159617 159618 159619 159620 159621 159622 159623 159624 159625 159626 159627 159628 159629 159630 159631 159632 159633 159634 159635 159636 159637 159638 159639 159640 159641 159642 159643 159644 159645 159646 159647 159648 159649 159650 159651 159652 159653 159654 159655 159656 159657 159658 159659 159660 159661 159662 159663 159664 159665 159666 159667 159668 159669 159670 159671 159672 159673 159674 159675 159676 159677 159678 159679 159680 159681 159682 159683 159684 159685 159686 159687 159688 159689 159690 159691 159692 159693 159694 159695 159696 159697 159698 159699 159700 159701 159702 159703 159704 159705 159706 159707 159708 159709 159710 159711 159712 159713 159714 159715 159716 159717 159718 159719 159720 159721 159722 159723 159724 159725 159726 159727 159728 159729 159730 159731 159732 159733 159734 159735 159736 159737 159738 159739 159740 159741 159742 159743 159744 159745 159746 159747 159748 159749 159750 159751 159752 159753 159754 159755 159756 159757 159758 159759 159760 159761 159762 159763 159764 159765 159766 159767 159768 159769 159770 159771 159772 159773 159774 159775 159776 159777 159778 159779 159780 159781 159782 159783 159784 159785 159786 159787 159788 159789 159790 159791 159792 159793 159794 159795 159796 159797 159798 159799 159800 159801 159802 159803 159804 159805 159806 159807 159808 159809 159810 159811 159812 159813 159814 159815 159816 159817 159818 159819 159820 159821 159822 159823 159824 159825 159826 159827 159828 159829 159830 159831 159832 159833 159834 159835 159836 159837 159838 159839 159840 159841 159842 159843 159844 159845 159846 159847 159848 159849 159850 159851 159852 159853 159854 159855 159856 159857 159858 159859 159860 159861 159862 159863 159864 159865 159866 159867 159868 159869 159870 159871 159872 159873 159874 159875 159876 159877 159878 159879 159880 159881 159882 159883 159884 159885 159886 159887 159888 159889 159890 159891 159892 159893 159894 159895 159896 159897 159898 159899 159900 159901 159902 159903 159904 159905 159906 159907 159908 159909 159910 159911 159912 159913 159914 159915 159916 159917 159918 159919 159920 159921 159922 159923 159924 159925 159926 159927 159928 159929 159930 159931 159932 159933 159934 159935 159936 159937 159938 159939 159940 159941 159942 159943 159944 159945 159946 159947 159948 159949 159950 159951 159952 159953 159954 159955 159956 159957 159958 159959 159960 159961 159962 159963 159964 159965 159966 159967 159968 159969 159970 159971 159972 159973 159974 159975 159976 159977 159978 159979 159980 159981 159982 159983 159984 159985 159986 159987 159988 159989 159990 159991 159992 159993 159994 159995 159996 159997 159998 159999 160000 160001 160002 160003 160004 160005 160006 160007 160008 160009 160010 160011 160012 160013 160014 160015 160016 160017 160018 160019 160020 160021 160022 160023 160024 160025 160026 160027 160028 160029 160030 160031 160032 160033 160034 160035 160036 160037 160038 160039 160040 160041 160042 160043 160044 160045 160046 160047 160048 160049 160050 160051 160052 160053 160054 160055 160056 160057 160058 160059 160060 160061 160062 160063 160064 160065 160066 160067 160068 160069 160070 160071 160072 160073 160074 160075 160076 160077 160078 160079 160080 160081 160082 160083 160084 160085 160086 160087 160088 160089 160090 160091 160092 160093 160094 160095 160096 160097 160098 160099 160100 160101 160102 160103 160104 160105 160106 160107 160108 160109 160110 160111 160112 160113 160114 160115 160116 160117 160118 160119 160120 160121 160122 160123 160124 160125 160126 160127 160128 160129 160130 160131 160132 160133 160134 160135 160136 160137 160138 160139 160140 160141 160142 160143 160144 160145 160146 160147 160148 160149 160150 160151 160152 160153 160154 160155 160156 160157 160158 160159 160160 160161 160162 160163 160164 160165 160166 160167 160168 160169 160170 160171 160172 160173 160174 160175 160176 160177 160178 160179 160180 160181 160182 160183 160184 160185 160186 160187 160188 160189 160190 160191 160192 160193 160194 160195 160196 160197 160198 160199 160200 160201 160202 160203 160204 160205 160206 160207 160208 160209 160210 160211 160212 160213 160214 160215 160216 160217 160218 160219 160220 160221 160222 160223 160224 160225 160226 160227 160228 160229 160230 160231 160232 160233 160234 160235 160236 160237 160238 160239 160240 160241 160242 160243 160244 160245 160246 160247 160248 160249 160250 160251 160252 160253 160254 160255 160256 160257 160258 160259 160260 160261 160262 160263 160264 160265 160266 160267 160268 160269 160270 160271 160272 160273 160274 160275 160276 160277 160278 160279 160280 160281 160282 160283 160284 160285 160286 160287 160288 160289 160290 160291 160292 160293 160294 160295 160296 160297 160298 160299 160300 160301 160302 160303 160304 160305 160306 160307 160308 160309 160310 160311 160312 160313 160314 160315 160316 160317 160318 160319 160320 160321 160322 160323 160324 160325 160326 160327 160328 160329 160330 160331 160332 160333 160334 160335 160336 160337 160338 160339 160340 160341 160342 160343 160344 160345 160346 160347 160348 160349 160350 160351 160352 160353 160354 160355 160356 160357 160358 160359 160360 160361 160362 160363 160364 160365 160366 160367 160368 160369 160370 160371 160372 160373 160374 160375 160376 160377 160378 160379 160380 160381 160382 160383 160384 160385 160386 160387 160388 160389 160390 160391 160392 160393 160394 160395 160396 160397 160398 160399 160400 160401 160402 160403 160404 160405 160406 160407 160408 160409 160410 160411 160412 160413 160414 160415 160416 160417 160418 160419 160420 160421 160422 160423 160424 160425 160426 160427 160428 160429 160430 160431 160432 160433 160434 160435 160436 160437 160438 160439 160440 160441 160442 160443 160444 160445 160446 160447 160448 160449 160450 160451 160452 160453 160454 160455 160456 160457 160458 160459 160460 160461 160462 160463 160464 160465 160466 160467 160468 160469 160470 160471 160472 160473 160474 160475 160476 160477 160478 160479 160480 160481 160482 160483 160484 160485 160486 160487 160488 160489 160490 160491 160492 160493 160494 160495 160496 160497 160498 160499 160500 160501 160502 160503 160504 160505 160506 160507 | ** Examples: ** ** test.db-journal => test.nal ** test.db-wal => test.wal ** test.db-shm => test.shm ** test.db-mj7f3319fa => test.9fa */ static void rbuFileSuffix3(const char *zBase, char *z){ #ifdef SQLITE_ENABLE_8_3_NAMES #if SQLITE_ENABLE_8_3_NAMES<2 if( sqlite3_uri_boolean(zBase, "8_3_names", 0) ) #endif { int i, sz; sz = sqlite3Strlen30(z); for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); } #endif } /* ** Return the current wal-index header checksum for the target database ** as a 64-bit integer. ** ** The checksum is store in the first page of xShmMap memory as an 8-byte ** blob starting at byte offset 40. */ static i64 rbuShmChecksum(sqlite3rbu *p){ i64 iRet = 0; if( p->rc==SQLITE_OK ){ sqlite3_file *pDb = p->pTargetFd->pReal; u32 volatile *ptr; p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr); if( p->rc==SQLITE_OK ){ iRet = ((i64)ptr[10] << 32) + ptr[11]; } } return iRet; } /* ** This function is called as part of initializing or reinitializing an ** incremental checkpoint. ** ** It populates the sqlite3rbu.aFrame[] array with the set of ** (wal frame -> db page) copy operations required to checkpoint the ** current wal file, and obtains the set of shm locks required to safely ** perform the copy operations directly on the file-system. ** ** If argument pState is not NULL, then the incremental checkpoint is ** being resumed. In this case, if the checksum of the wal-index-header ** following recovery is not the same as the checksum saved in the RbuState ** object, then the rbu handle is set to DONE state. This occurs if some ** other client appends a transaction to the wal file in the middle of ** an incremental checkpoint. */ static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){ /* If pState is NULL, then the wal file may not have been opened and ** recovered. Running a read-statement here to ensure that doing so ** does not interfere with the "capture" process below. */ if( pState==0 ){ p->eStage = 0; if( p->rc==SQLITE_OK ){ p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_master", 0, 0, 0); } } /* Assuming no error has occurred, run a "restart" checkpoint with the ** sqlite3rbu.eStage variable set to CAPTURE. This turns on the following ** special behaviour in the rbu VFS: ** ** * If the exclusive shm WRITER or READ0 lock cannot be obtained, ** the checkpoint fails with SQLITE_BUSY (normally SQLite would ** proceed with running a passive checkpoint instead of failing). ** ** * Attempts to read from the *-wal file or write to the database file ** do not perform any IO. Instead, the frame/page combinations that ** would be read/written are recorded in the sqlite3rbu.aFrame[] ** array. ** ** * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER, ** READ0 and CHECKPOINT locks taken as part of the checkpoint are ** no-ops. These locks will not be released until the connection ** is closed. ** ** * Attempting to xSync() the database file causes an SQLITE_INTERNAL ** error. ** ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the ** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[] ** array populated with a set of (frame -> page) mappings. Because the ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy ** data from the wal file into the database file according to the ** contents of aFrame[]. */ if( p->rc==SQLITE_OK ){ int rc2; p->eStage = RBU_STAGE_CAPTURE; rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0); if( rc2!=SQLITE_INTERNAL ) p->rc = rc2; } if( p->rc==SQLITE_OK ){ p->eStage = RBU_STAGE_CKPT; p->nStep = (pState ? pState->nRow : 0); p->aBuf = rbuMalloc(p, p->pgsz); p->iWalCksum = rbuShmChecksum(p); } if( p->rc==SQLITE_OK && pState && pState->iWalCksum!=p->iWalCksum ){ p->rc = SQLITE_DONE; p->eStage = RBU_STAGE_DONE; } } /* ** Called when iAmt bytes are read from offset iOff of the wal file while ** the rbu object is in capture mode. Record the frame number of the frame ** being read in the aFrame[] array. */ static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){ const u32 mReq = (1<<WAL_LOCK_WRITE)|(1<<WAL_LOCK_CKPT)|(1<<WAL_LOCK_READ0); u32 iFrame; if( pRbu->mLock!=mReq ){ pRbu->rc = SQLITE_BUSY; return SQLITE_INTERNAL; } pRbu->pgsz = iAmt; if( pRbu->nFrame==pRbu->nFrameAlloc ){ int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2; RbuFrame *aNew; aNew = (RbuFrame*)sqlite3_realloc(pRbu->aFrame, nNew * sizeof(RbuFrame)); if( aNew==0 ) return SQLITE_NOMEM; pRbu->aFrame = aNew; pRbu->nFrameAlloc = nNew; } iFrame = (u32)((iOff-32) / (i64)(iAmt+24)) + 1; if( pRbu->iMaxFrame<iFrame ) pRbu->iMaxFrame = iFrame; pRbu->aFrame[pRbu->nFrame].iWalFrame = iFrame; pRbu->aFrame[pRbu->nFrame].iDbPage = 0; pRbu->nFrame++; return SQLITE_OK; } /* ** Called when a page of data is written to offset iOff of the database ** file while the rbu handle is in capture mode. Record the page number ** of the page being written in the aFrame[] array. */ static int rbuCaptureDbWrite(sqlite3rbu *pRbu, i64 iOff){ pRbu->aFrame[pRbu->nFrame-1].iDbPage = (u32)(iOff / pRbu->pgsz) + 1; return SQLITE_OK; } /* ** This is called as part of an incremental checkpoint operation. Copy ** a single frame of data from the wal file into the database file, as ** indicated by the RbuFrame object. */ static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){ sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal; sqlite3_file *pDb = p->pTargetFd->pReal; i64 iOff; assert( p->rc==SQLITE_OK ); iOff = (i64)(pFrame->iWalFrame-1) * (p->pgsz + 24) + 32 + 24; p->rc = pWal->pMethods->xRead(pWal, p->aBuf, p->pgsz, iOff); if( p->rc ) return; iOff = (i64)(pFrame->iDbPage-1) * p->pgsz; p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff); } /* ** Take an EXCLUSIVE lock on the database file. */ static void rbuLockDatabase(sqlite3rbu *p){ sqlite3_file *pReal = p->pTargetFd->pReal; assert( p->rc==SQLITE_OK ); p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED); if( p->rc==SQLITE_OK ){ p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE); } } /* ** The RBU handle is currently in RBU_STAGE_OAL state, with a SHARED lock ** on the database file. This proc moves the *-oal file to the *-wal path, ** then reopens the database file (this time in vanilla, non-oal, WAL mode). ** If an error occurs, leave an error code and error message in the rbu ** handle. */ static void rbuMoveOalFile(sqlite3rbu *p){ const char *zBase = sqlite3_db_filename(p->dbMain, "main"); char *zWal = sqlite3_mprintf("%s-wal", zBase); char *zOal = sqlite3_mprintf("%s-oal", zBase); assert( p->eStage==RBU_STAGE_MOVE ); assert( p->rc==SQLITE_OK && p->zErrmsg==0 ); if( zWal==0 || zOal==0 ){ p->rc = SQLITE_NOMEM; }else{ /* Move the *-oal file to *-wal. At this point connection p->db is ** holding a SHARED lock on the target database file (because it is ** in WAL mode). So no other connection may be writing the db. ** ** In order to ensure that there are no database readers, an EXCLUSIVE ** lock is obtained here before the *-oal is moved to *-wal. */ rbuLockDatabase(p); if( p->rc==SQLITE_OK ){ rbuFileSuffix3(zBase, zWal); rbuFileSuffix3(zBase, zOal); /* Re-open the databases. */ rbuObjIterFinalize(&p->objiter); sqlite3_close(p->dbMain); sqlite3_close(p->dbRbu); p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK; if( p->rc==SQLITE_OK ){ p->dbMain = 0; p->dbRbu = 0; rbuOpenDatabase(p); rbuSetupCheckpoint(p, 0); } } } sqlite3_free(zWal); sqlite3_free(zOal); } /* ** The SELECT statement iterating through the keys for the current object ** (p->objiter.pSelect) currently points to a valid row. This function ** determines the type of operation requested by this row and returns ** one of the following values to indicate the result: ** ** * RBU_INSERT ** * RBU_DELETE ** * RBU_IDX_DELETE ** * RBU_UPDATE ** ** If RBU_UPDATE is returned, then output variable *pzMask is set to ** point to the text value indicating the columns to update. ** ** If the rbu_control field contains an invalid value, an error code and ** message are left in the RBU handle and zero returned. */ static int rbuStepType(sqlite3rbu *p, const char **pzMask){ int iCol = p->objiter.nCol; /* Index of rbu_control column */ int res = 0; /* Return value */ switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){ case SQLITE_INTEGER: { int iVal = sqlite3_column_int(p->objiter.pSelect, iCol); if( iVal==0 ){ res = RBU_INSERT; }else if( iVal==1 ){ res = RBU_DELETE; }else if( iVal==2 ){ res = RBU_IDX_DELETE; }else if( iVal==3 ){ res = RBU_IDX_INSERT; } break; } case SQLITE_TEXT: { const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol); if( z==0 ){ p->rc = SQLITE_NOMEM; }else{ *pzMask = (const char*)z; } res = RBU_UPDATE; break; } default: break; } if( res==0 ){ rbuBadControlError(p); } return res; } #ifdef SQLITE_DEBUG /* ** Assert that column iCol of statement pStmt is named zName. */ static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){ const char *zCol = sqlite3_column_name(pStmt, iCol); assert( 0==sqlite3_stricmp(zName, zCol) ); } #else # define assertColumnName(x,y,z) #endif /* ** This function does the work for an sqlite3rbu_step() call. ** ** The object-iterator (p->objiter) currently points to a valid object, ** and the input cursor (p->objiter.pSelect) currently points to a valid ** input row. Perform whatever processing is required and return. ** ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code ** and message is left in the RBU handle and a copy of the error code ** returned. */ static int rbuStep(sqlite3rbu *p){ RbuObjIter *pIter = &p->objiter; const char *zMask = 0; int i; int eType = rbuStepType(p, &zMask); if( eType ){ assert( eType!=RBU_UPDATE || pIter->zIdx==0 ); if( pIter->zIdx==0 && eType==RBU_IDX_DELETE ){ rbuBadControlError(p); } else if( eType==RBU_INSERT || eType==RBU_DELETE || eType==RBU_IDX_DELETE || eType==RBU_IDX_INSERT ){ sqlite3_value *pVal; sqlite3_stmt *pWriter; assert( eType!=RBU_UPDATE ); assert( eType!=RBU_DELETE || pIter->zIdx==0 ); if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){ pWriter = pIter->pDelete; }else{ pWriter = pIter->pInsert; } for(i=0; i<pIter->nCol; i++){ /* If this is an INSERT into a table b-tree and the table has an ** explicit INTEGER PRIMARY KEY, check that this is not an attempt ** to write a NULL into the IPK column. That is not permitted. */ if( eType==RBU_INSERT && pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i] && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL ){ p->rc = SQLITE_MISMATCH; p->zErrmsg = sqlite3_mprintf("datatype mismatch"); goto step_out; } if( eType==RBU_DELETE && pIter->abTblPk[i]==0 ){ continue; } pVal = sqlite3_column_value(pIter->pSelect, i); p->rc = sqlite3_bind_value(pWriter, i+1, pVal); if( p->rc ) goto step_out; } if( pIter->zIdx==0 && (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) ){ /* For a virtual table, or a table with no primary key, the ** SELECT statement is: ** ** SELECT <cols>, rbu_control, rbu_rowid FROM .... ** ** Hence column_value(pIter->nCol+1). */ assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid"); pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1); p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal); } if( p->rc==SQLITE_OK ){ sqlite3_step(pWriter); p->rc = resetAndCollectError(pWriter, &p->zErrmsg); } }else{ sqlite3_value *pVal; sqlite3_stmt *pUpdate = 0; assert( eType==RBU_UPDATE ); rbuGetUpdateStmt(p, pIter, zMask, &pUpdate); if( pUpdate ){ for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){ char c = zMask[pIter->aiSrcOrder[i]]; pVal = sqlite3_column_value(pIter->pSelect, i); if( pIter->abTblPk[i] || c=='x' || c=='d' ){ p->rc = sqlite3_bind_value(pUpdate, i+1, pVal); } } if( p->rc==SQLITE_OK && (pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) ){ /* Bind the rbu_rowid value to column _rowid_ */ assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid"); pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1); p->rc = sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal); } if( p->rc==SQLITE_OK ){ sqlite3_step(pUpdate); p->rc = resetAndCollectError(pUpdate, &p->zErrmsg); } } } } step_out: return p->rc; } /* ** Increment the schema cookie of the main database opened by p->dbMain. */ static void rbuIncrSchemaCookie(sqlite3rbu *p){ if( p->rc==SQLITE_OK ){ int iCookie = 1000000; sqlite3_stmt *pStmt; p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, "PRAGMA schema_version" ); if( p->rc==SQLITE_OK ){ /* Coverage: it may be that this sqlite3_step() cannot fail. There ** is already a transaction open, so the prepared statement cannot ** throw an SQLITE_SCHEMA exception. The only database page the ** statement reads is page 1, which is guaranteed to be in the cache. ** And no memory allocations are required. */ if( SQLITE_ROW==sqlite3_step(pStmt) ){ iCookie = sqlite3_column_int(pStmt, 0); } rbuFinalize(p, pStmt); } if( p->rc==SQLITE_OK ){ rbuMPrintfExec(p, p->dbMain, "PRAGMA schema_version = %d", iCookie+1); } } } /* ** Update the contents of the rbu_state table within the rbu database. The ** value stored in the RBU_STATE_STAGE column is eStage. All other values ** are determined by inspecting the rbu handle passed as the first argument. */ static void rbuSaveState(sqlite3rbu *p, int eStage){ if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){ sqlite3_stmt *pInsert = 0; int rc; assert( p->zErrmsg==0 ); rc = prepareFreeAndCollectError(p->dbRbu, &pInsert, &p->zErrmsg, sqlite3_mprintf( "INSERT OR REPLACE INTO %s.rbu_state(k, v) VALUES " "(%d, %d), " "(%d, %Q), " "(%d, %Q), " "(%d, %d), " "(%d, %d), " "(%d, %lld), " "(%d, %lld), " "(%d, %lld) ", p->zStateDb, RBU_STATE_STAGE, eStage, RBU_STATE_TBL, p->objiter.zTbl, RBU_STATE_IDX, p->objiter.zIdx, RBU_STATE_ROW, p->nStep, RBU_STATE_PROGRESS, p->nProgress, RBU_STATE_CKPT, p->iWalCksum, RBU_STATE_COOKIE, (i64)p->pTargetFd->iCookie, RBU_STATE_OALSZ, p->iOalSz ) ); assert( pInsert==0 || rc==SQLITE_OK ); if( rc==SQLITE_OK ){ sqlite3_step(pInsert); rc = sqlite3_finalize(pInsert); } if( rc!=SQLITE_OK ) p->rc = rc; } } /* ** Step the RBU object. */ SQLITE_API int SQLITE_STDCALL sqlite3rbu_step(sqlite3rbu *p){ if( p ){ switch( p->eStage ){ case RBU_STAGE_OAL: { RbuObjIter *pIter = &p->objiter; while( p->rc==SQLITE_OK && pIter->zTbl ){ if( pIter->bCleanup ){ /* Clean up the rbu_tmp_xxx table for the previous table. It ** cannot be dropped as there are currently active SQL statements. ** But the contents can be deleted. */ if( pIter->abIndexed ){ rbuMPrintfExec(p, p->dbRbu, "DELETE FROM %s.'rbu_tmp_%q'", p->zStateDb, pIter->zTbl ); } }else{ rbuObjIterPrepareAll(p, pIter, 0); /* Advance to the next row to process. */ if( p->rc==SQLITE_OK ){ int rc = sqlite3_step(pIter->pSelect); if( rc==SQLITE_ROW ){ p->nProgress++; p->nStep++; return rbuStep(p); } p->rc = sqlite3_reset(pIter->pSelect); p->nStep = 0; } } rbuObjIterNext(p, pIter); } if( p->rc==SQLITE_OK ){ assert( pIter->zTbl==0 ); rbuSaveState(p, RBU_STAGE_MOVE); rbuIncrSchemaCookie(p); if( p->rc==SQLITE_OK ){ p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg); } if( p->rc==SQLITE_OK ){ p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg); } p->eStage = RBU_STAGE_MOVE; } break; } case RBU_STAGE_MOVE: { if( p->rc==SQLITE_OK ){ rbuMoveOalFile(p); p->nProgress++; } break; } case RBU_STAGE_CKPT: { if( p->rc==SQLITE_OK ){ if( p->nStep>=p->nFrame ){ sqlite3_file *pDb = p->pTargetFd->pReal; /* Sync the db file */ p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL); /* Update nBackfill */ if( p->rc==SQLITE_OK ){ void volatile *ptr; p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, &ptr); if( p->rc==SQLITE_OK ){ ((u32 volatile*)ptr)[24] = p->iMaxFrame; } } if( p->rc==SQLITE_OK ){ p->eStage = RBU_STAGE_DONE; p->rc = SQLITE_DONE; } }else{ RbuFrame *pFrame = &p->aFrame[p->nStep]; rbuCheckpointFrame(p, pFrame); p->nStep++; } p->nProgress++; } break; } default: break; } return p->rc; }else{ return SQLITE_NOMEM; } } /* ** Free an RbuState object allocated by rbuLoadState(). */ static void rbuFreeState(RbuState *p){ if( p ){ sqlite3_free(p->zTbl); sqlite3_free(p->zIdx); sqlite3_free(p); } } /* ** Allocate an RbuState object and load the contents of the rbu_state ** table into it. Return a pointer to the new object. It is the ** responsibility of the caller to eventually free the object using ** sqlite3_free(). ** ** If an error occurs, leave an error code and message in the rbu handle ** and return NULL. */ static RbuState *rbuLoadState(sqlite3rbu *p){ RbuState *pRet = 0; sqlite3_stmt *pStmt = 0; int rc; int rc2; pRet = (RbuState*)rbuMalloc(p, sizeof(RbuState)); if( pRet==0 ) return 0; rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb) ); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ switch( sqlite3_column_int(pStmt, 0) ){ case RBU_STATE_STAGE: pRet->eStage = sqlite3_column_int(pStmt, 1); if( pRet->eStage!=RBU_STAGE_OAL && pRet->eStage!=RBU_STAGE_MOVE && pRet->eStage!=RBU_STAGE_CKPT ){ p->rc = SQLITE_CORRUPT; } break; case RBU_STATE_TBL: pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); break; case RBU_STATE_IDX: pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); break; case RBU_STATE_ROW: pRet->nRow = sqlite3_column_int(pStmt, 1); break; case RBU_STATE_PROGRESS: pRet->nProgress = sqlite3_column_int64(pStmt, 1); break; case RBU_STATE_CKPT: pRet->iWalCksum = sqlite3_column_int64(pStmt, 1); break; case RBU_STATE_COOKIE: pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1); break; case RBU_STATE_OALSZ: pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1); break; default: rc = SQLITE_CORRUPT; break; } } rc2 = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ) rc = rc2; p->rc = rc; return pRet; } /* ** Compare strings z1 and z2, returning 0 if they are identical, or non-zero ** otherwise. Either or both argument may be NULL. Two NULL values are ** considered equal, and NULL is considered distinct from all other values. */ static int rbuStrCompare(const char *z1, const char *z2){ if( z1==0 && z2==0 ) return 0; if( z1==0 || z2==0 ) return 1; return (sqlite3_stricmp(z1, z2)!=0); } /* ** This function is called as part of sqlite3rbu_open() when initializing ** an rbu handle in OAL stage. If the rbu update has not started (i.e. ** the rbu_state table was empty) it is a no-op. Otherwise, it arranges ** things so that the next call to sqlite3rbu_step() continues on from ** where the previous rbu handle left off. ** ** If an error occurs, an error code and error message are left in the ** rbu handle passed as the first argument. */ static void rbuSetupOal(sqlite3rbu *p, RbuState *pState){ assert( p->rc==SQLITE_OK ); if( pState->zTbl ){ RbuObjIter *pIter = &p->objiter; int rc = SQLITE_OK; while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup || rbuStrCompare(pIter->zIdx, pState->zIdx) || rbuStrCompare(pIter->zTbl, pState->zTbl) )){ rc = rbuObjIterNext(p, pIter); } if( rc==SQLITE_OK && !pIter->zTbl ){ rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("rbu_state mismatch error"); } if( rc==SQLITE_OK ){ p->nStep = pState->nRow; rc = rbuObjIterPrepareAll(p, &p->objiter, p->nStep); } p->rc = rc; } } /* ** If there is a "*-oal" file in the file-system corresponding to the ** target database in the file-system, delete it. If an error occurs, ** leave an error code and error message in the rbu handle. */ static void rbuDeleteOalFile(sqlite3rbu *p){ char *zOal = sqlite3_mprintf("%s-oal", p->zTarget); assert( p->rc==SQLITE_OK && p->zErrmsg==0 ); unlink(zOal); sqlite3_free(zOal); } /* ** Allocate a private rbu VFS for the rbu handle passed as the only ** argument. This VFS will be used unless the call to sqlite3rbu_open() ** specified a URI with a vfs=? option in place of a target database ** file name. */ static void rbuCreateVfs(sqlite3rbu *p){ int rnd; char zRnd[64]; assert( p->rc==SQLITE_OK ); sqlite3_randomness(sizeof(int), (void*)&rnd); sprintf(zRnd, "rbu_vfs_%d", rnd); p->rc = sqlite3rbu_create_vfs(zRnd, 0); if( p->rc==SQLITE_OK ){ sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd); assert( pVfs ); p->zVfsName = pVfs->zName; } } /* ** Destroy the private VFS created for the rbu handle passed as the only ** argument by an earlier call to rbuCreateVfs(). */ static void rbuDeleteVfs(sqlite3rbu *p){ if( p->zVfsName ){ sqlite3rbu_destroy_vfs(p->zVfsName); p->zVfsName = 0; } } /* ** Open and return a new RBU handle. */ SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open( const char *zTarget, const char *zRbu, const char *zState ){ sqlite3rbu *p; int nTarget = strlen(zTarget); int nRbu = strlen(zRbu); int nState = zState ? strlen(zState) : 0; p = (sqlite3rbu*)sqlite3_malloc(sizeof(sqlite3rbu)+nTarget+1+nRbu+1+nState+1); if( p ){ RbuState *pState = 0; /* Create the custom VFS. */ memset(p, 0, sizeof(sqlite3rbu)); rbuCreateVfs(p); /* Open the target database */ if( p->rc==SQLITE_OK ){ p->zTarget = (char*)&p[1]; memcpy(p->zTarget, zTarget, nTarget+1); p->zRbu = &p->zTarget[nTarget+1]; memcpy(p->zRbu, zRbu, nRbu+1); if( zState ){ p->zState = &p->zRbu[nRbu+1]; memcpy(p->zState, zState, nState+1); } rbuOpenDatabase(p); } /* If it has not already been created, create the rbu_state table */ rbuMPrintfExec(p, p->dbRbu, RBU_CREATE_STATE, p->zStateDb); if( p->rc==SQLITE_OK ){ pState = rbuLoadState(p); assert( pState || p->rc!=SQLITE_OK ); if( p->rc==SQLITE_OK ){ if( pState->eStage==0 ){ rbuDeleteOalFile(p); p->eStage = RBU_STAGE_OAL; }else{ p->eStage = pState->eStage; } p->nProgress = pState->nProgress; p->iOalSz = pState->iOalSz; } } assert( p->rc!=SQLITE_OK || p->eStage!=0 ); if( p->rc==SQLITE_OK && p->pTargetFd->pWalFd ){ if( p->eStage==RBU_STAGE_OAL ){ p->rc = SQLITE_ERROR; p->zErrmsg = sqlite3_mprintf("cannot update wal mode database"); }else if( p->eStage==RBU_STAGE_MOVE ){ p->eStage = RBU_STAGE_CKPT; p->nStep = 0; } } if( p->rc==SQLITE_OK && (p->eStage==RBU_STAGE_OAL || p->eStage==RBU_STAGE_MOVE) && pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie ){ /* At this point (pTargetFd->iCookie) contains the value of the ** change-counter cookie (the thing that gets incremented when a ** transaction is committed in rollback mode) currently stored on ** page 1 of the database file. */ p->rc = SQLITE_BUSY; p->zErrmsg = sqlite3_mprintf("database modified during rbu update"); } if( p->rc==SQLITE_OK ){ if( p->eStage==RBU_STAGE_OAL ){ /* Open transactions both databases. The *-oal file is opened or ** created at this point. */ p->rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); if( p->rc==SQLITE_OK ){ p->rc = sqlite3_exec(p->dbRbu, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); } /* Point the object iterator at the first object */ if( p->rc==SQLITE_OK ){ p->rc = rbuObjIterFirst(p, &p->objiter); } /* If the RBU database contains no data_xxx tables, declare the RBU ** update finished. */ if( p->rc==SQLITE_OK && p->objiter.zTbl==0 ){ p->rc = SQLITE_DONE; } if( p->rc==SQLITE_OK ){ rbuSetupOal(p, pState); } }else if( p->eStage==RBU_STAGE_MOVE ){ /* no-op */ }else if( p->eStage==RBU_STAGE_CKPT ){ rbuSetupCheckpoint(p, pState); }else if( p->eStage==RBU_STAGE_DONE ){ p->rc = SQLITE_DONE; }else{ p->rc = SQLITE_CORRUPT; } } rbuFreeState(pState); } return p; } /* ** Return the database handle used by pRbu. */ SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){ sqlite3 *db = 0; if( pRbu ){ db = (bRbu ? pRbu->dbRbu : pRbu->dbMain); } return db; } /* ** If the error code currently stored in the RBU handle is SQLITE_CONSTRAINT, ** then edit any error message string so as to remove all occurrences of ** the pattern "rbu_imp_[0-9]*". */ static void rbuEditErrmsg(sqlite3rbu *p){ if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){ int i; int nErrmsg = strlen(p->zErrmsg); for(i=0; i<(nErrmsg-8); i++){ if( memcmp(&p->zErrmsg[i], "rbu_imp_", 8)==0 ){ int nDel = 8; while( p->zErrmsg[i+nDel]>='0' && p->zErrmsg[i+nDel]<='9' ) nDel++; memmove(&p->zErrmsg[i], &p->zErrmsg[i+nDel], nErrmsg + 1 - i - nDel); nErrmsg -= nDel; } } } } /* ** Close the RBU handle. */ SQLITE_API int SQLITE_STDCALL sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){ int rc; if( p ){ /* Commit the transaction to the *-oal file. */ if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){ p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg); } rbuSaveState(p, p->eStage); if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){ p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg); } /* Close any open statement handles. */ rbuObjIterFinalize(&p->objiter); /* Close the open database handle and VFS object. */ sqlite3_close(p->dbMain); sqlite3_close(p->dbRbu); rbuDeleteVfs(p); sqlite3_free(p->aBuf); sqlite3_free(p->aFrame); rbuEditErrmsg(p); rc = p->rc; *pzErrmsg = p->zErrmsg; sqlite3_free(p); }else{ rc = SQLITE_NOMEM; *pzErrmsg = 0; } return rc; } /* ** Return the total number of key-value operations (inserts, deletes or ** updates) that have been performed on the target database since the ** current RBU update was started. */ SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu){ return pRbu->nProgress; } /************************************************************************** ** Beginning of RBU VFS shim methods. The VFS shim modifies the behaviour ** of a standard VFS in the following ways: ** ** 1. Whenever the first page of a main database file is read or ** written, the value of the change-counter cookie is stored in ** rbu_file.iCookie. Similarly, the value of the "write-version" ** database header field is stored in rbu_file.iWriteVer. This ensures ** that the values are always trustworthy within an open transaction. ** ** 2. Whenever an SQLITE_OPEN_WAL file is opened, the (rbu_file.pWalFd) ** member variable of the associated database file descriptor is set ** to point to the new file. A mutex protected linked list of all main ** db fds opened using a particular RBU VFS is maintained at ** rbu_vfs.pMain to facilitate this. ** ** 3. Using a new file-control "SQLITE_FCNTL_RBU", a main db rbu_file ** object can be marked as the target database of an RBU update. This ** turns on the following extra special behaviour: ** ** 3a. If xAccess() is called to check if there exists a *-wal file ** associated with an RBU target database currently in RBU_STAGE_OAL ** stage (preparing the *-oal file), the following special handling ** applies: ** ** * if the *-wal file does exist, return SQLITE_CANTOPEN. An RBU ** target database may not be in wal mode already. ** ** * if the *-wal file does not exist, set the output parameter to ** non-zero (to tell SQLite that it does exist) anyway. ** ** Then, when xOpen() is called to open the *-wal file associated with ** the RBU target in RBU_STAGE_OAL stage, instead of opening the *-wal ** file, the rbu vfs opens the corresponding *-oal file instead. ** ** 3b. The *-shm pages returned by xShmMap() for a target db file in ** RBU_STAGE_OAL mode are actually stored in heap memory. This is to ** avoid creating a *-shm file on disk. Additionally, xShmLock() calls ** are no-ops on target database files in RBU_STAGE_OAL mode. This is ** because assert() statements in some VFS implementations fail if ** xShmLock() is called before xShmMap(). ** ** 3c. If an EXCLUSIVE lock is attempted on a target database file in any ** mode except RBU_STAGE_DONE (all work completed and checkpointed), it ** fails with an SQLITE_BUSY error. This is to stop RBU connections ** from automatically checkpointing a *-wal (or *-oal) file from within ** sqlite3_close(). ** ** 3d. In RBU_STAGE_CAPTURE mode, all xRead() calls on the wal file, and ** all xWrite() calls on the target database file perform no IO. ** Instead the frame and page numbers that would be read and written ** are recorded. Additionally, successful attempts to obtain exclusive ** xShmLock() WRITER, CHECKPOINTER and READ0 locks on the target ** database file are recorded. xShmLock() calls to unlock the same ** locks are no-ops (so that once obtained, these locks are never ** relinquished). Finally, calls to xSync() on the target database ** file fail with SQLITE_INTERNAL errors. */ static void rbuUnlockShm(rbu_file *p){ if( p->pRbu ){ int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock; int i; for(i=0; i<SQLITE_SHM_NLOCK;i++){ if( (1<<i) & p->pRbu->mLock ){ xShmLock(p->pReal, i, 1, SQLITE_SHM_UNLOCK|SQLITE_SHM_EXCLUSIVE); } } p->pRbu->mLock = 0; } } /* ** Close an rbu file. */ static int rbuVfsClose(sqlite3_file *pFile){ rbu_file *p = (rbu_file*)pFile; int rc; int i; /* Free the contents of the apShm[] array. And the array itself. */ for(i=0; i<p->nShm; i++){ sqlite3_free(p->apShm[i]); } sqlite3_free(p->apShm); p->apShm = 0; sqlite3_free(p->zDel); if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ rbu_file **pp; sqlite3_mutex_enter(p->pRbuVfs->mutex); for(pp=&p->pRbuVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext)); *pp = p->pMainNext; sqlite3_mutex_leave(p->pRbuVfs->mutex); rbuUnlockShm(p); p->pReal->pMethods->xShmUnmap(p->pReal, 0); } /* Close the underlying file handle */ rc = p->pReal->pMethods->xClose(p->pReal); return rc; } /* ** Read and return an unsigned 32-bit big-endian integer from the buffer ** passed as the only argument. */ static u32 rbuGetU32(u8 *aBuf){ return ((u32)aBuf[0] << 24) + ((u32)aBuf[1] << 16) + ((u32)aBuf[2] << 8) + ((u32)aBuf[3]); } /* ** Read data from an rbuVfs-file. */ static int rbuVfsRead( sqlite3_file *pFile, void *zBuf, int iAmt, sqlite_int64 iOfst ){ rbu_file *p = (rbu_file*)pFile; sqlite3rbu *pRbu = p->pRbu; int rc; if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){ assert( p->openFlags & SQLITE_OPEN_WAL ); rc = rbuCaptureWalRead(p->pRbu, iOfst, iAmt); }else{ if( pRbu && pRbu->eStage==RBU_STAGE_OAL && (p->openFlags & SQLITE_OPEN_WAL) && iOfst>=pRbu->iOalSz ){ rc = SQLITE_OK; memset(zBuf, 0, iAmt); }else{ rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); } if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ /* These look like magic numbers. But they are stable, as they are part ** of the definition of the SQLite file format, which may not change. */ u8 *pBuf = (u8*)zBuf; p->iCookie = rbuGetU32(&pBuf[24]); p->iWriteVer = pBuf[19]; } } return rc; } /* ** Write data to an rbuVfs-file. */ static int rbuVfsWrite( sqlite3_file *pFile, const void *zBuf, int iAmt, sqlite_int64 iOfst ){ rbu_file *p = (rbu_file*)pFile; sqlite3rbu *pRbu = p->pRbu; int rc; if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){ assert( p->openFlags & SQLITE_OPEN_MAIN_DB ); rc = rbuCaptureDbWrite(p->pRbu, iOfst); }else{ if( pRbu && pRbu->eStage==RBU_STAGE_OAL && (p->openFlags & SQLITE_OPEN_WAL) && iOfst>=pRbu->iOalSz ){ pRbu->iOalSz = iAmt + iOfst; } rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst); if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){ /* These look like magic numbers. But they are stable, as they are part ** of the definition of the SQLite file format, which may not change. */ u8 *pBuf = (u8*)zBuf; p->iCookie = rbuGetU32(&pBuf[24]); p->iWriteVer = pBuf[19]; } } return rc; } /* ** Truncate an rbuVfs-file. */ static int rbuVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){ rbu_file *p = (rbu_file*)pFile; return p->pReal->pMethods->xTruncate(p->pReal, size); } /* ** Sync an rbuVfs-file. */ static int rbuVfsSync(sqlite3_file *pFile, int flags){ rbu_file *p = (rbu_file *)pFile; if( p->pRbu && p->pRbu->eStage==RBU_STAGE_CAPTURE ){ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ return SQLITE_INTERNAL; } return SQLITE_OK; } return p->pReal->pMethods->xSync(p->pReal, flags); } /* ** Return the current file-size of an rbuVfs-file. */ static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ rbu_file *p = (rbu_file *)pFile; return p->pReal->pMethods->xFileSize(p->pReal, pSize); } /* ** Lock an rbuVfs-file. */ static int rbuVfsLock(sqlite3_file *pFile, int eLock){ rbu_file *p = (rbu_file*)pFile; sqlite3rbu *pRbu = p->pRbu; int rc = SQLITE_OK; assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); if( pRbu && eLock==SQLITE_LOCK_EXCLUSIVE && pRbu->eStage!=RBU_STAGE_DONE ){ /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this ** prevents it from checkpointing the database from sqlite3_close(). */ rc = SQLITE_BUSY; }else{ rc = p->pReal->pMethods->xLock(p->pReal, eLock); } return rc; } /* ** Unlock an rbuVfs-file. */ static int rbuVfsUnlock(sqlite3_file *pFile, int eLock){ rbu_file *p = (rbu_file *)pFile; return p->pReal->pMethods->xUnlock(p->pReal, eLock); } /* ** Check if another file-handle holds a RESERVED lock on an rbuVfs-file. */ static int rbuVfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){ rbu_file *p = (rbu_file *)pFile; return p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut); } /* ** File control method. For custom operations on an rbuVfs-file. */ static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){ rbu_file *p = (rbu_file *)pFile; int (*xControl)(sqlite3_file*,int,void*) = p->pReal->pMethods->xFileControl; int rc; assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) || p->openFlags & (SQLITE_OPEN_TRANSIENT_DB|SQLITE_OPEN_TEMP_JOURNAL) ); if( op==SQLITE_FCNTL_RBU ){ sqlite3rbu *pRbu = (sqlite3rbu*)pArg; /* First try to find another RBU vfs lower down in the vfs stack. If ** one is found, this vfs will operate in pass-through mode. The lower ** level vfs will do the special RBU handling. */ rc = xControl(p->pReal, op, pArg); if( rc==SQLITE_NOTFOUND ){ /* Now search for a zipvfs instance lower down in the VFS stack. If ** one is found, this is an error. */ void *dummy = 0; rc = xControl(p->pReal, SQLITE_FCNTL_ZIPVFS, &dummy); if( rc==SQLITE_OK ){ rc = SQLITE_ERROR; pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error"); }else if( rc==SQLITE_NOTFOUND ){ pRbu->pTargetFd = p; p->pRbu = pRbu; if( p->pWalFd ) p->pWalFd->pRbu = pRbu; rc = SQLITE_OK; } } return rc; } rc = xControl(p->pReal, op, pArg); if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){ rbu_vfs *pRbuVfs = p->pRbuVfs; char *zIn = *(char**)pArg; char *zOut = sqlite3_mprintf("rbu(%s)/%z", pRbuVfs->base.zName, zIn); *(char**)pArg = zOut; if( zOut==0 ) rc = SQLITE_NOMEM; } return rc; } /* ** Return the sector-size in bytes for an rbuVfs-file. */ static int rbuVfsSectorSize(sqlite3_file *pFile){ rbu_file *p = (rbu_file *)pFile; return p->pReal->pMethods->xSectorSize(p->pReal); } /* ** Return the device characteristic flags supported by an rbuVfs-file. */ static int rbuVfsDeviceCharacteristics(sqlite3_file *pFile){ rbu_file *p = (rbu_file *)pFile; return p->pReal->pMethods->xDeviceCharacteristics(p->pReal); } /* ** Take or release a shared-memory lock. */ static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ rbu_file *p = (rbu_file*)pFile; sqlite3rbu *pRbu = p->pRbu; int rc = SQLITE_OK; #ifdef SQLITE_AMALGAMATION assert( WAL_CKPT_LOCK==1 ); #endif assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); if( pRbu && (pRbu->eStage==RBU_STAGE_OAL || pRbu->eStage==RBU_STAGE_MOVE) ){ /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from ** taking this lock also prevents any checkpoints from occurring. ** todo: really, it's not clear why this might occur, as ** wal_autocheckpoint ought to be turned off. */ if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY; }else{ int bCapture = 0; if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE) && pRbu && pRbu->eStage==RBU_STAGE_CAPTURE && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0) ){ bCapture = 1; } if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){ rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags); if( bCapture && rc==SQLITE_OK ){ pRbu->mLock |= (1 << ofst); } } } return rc; } /* ** Obtain a pointer to a mapping of a single 32KiB page of the *-shm file. */ static int rbuVfsShmMap( sqlite3_file *pFile, int iRegion, int szRegion, int isWrite, void volatile **pp ){ rbu_file *p = (rbu_file*)pFile; int rc = SQLITE_OK; int eStage = (p->pRbu ? p->pRbu->eStage : 0); /* If not in RBU_STAGE_OAL, allow this call to pass through. Or, if this ** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space ** instead of a file on disk. */ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){ if( iRegion<=p->nShm ){ int nByte = (iRegion+1) * sizeof(char*); char **apNew = (char**)sqlite3_realloc(p->apShm, nByte); if( apNew==0 ){ rc = SQLITE_NOMEM; }else{ memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm)); |
︙ | ︙ | |||
160330 160331 160332 160333 160334 160335 160336 | return rc; } /* ** Memory barrier. */ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 160532 160533 160534 160535 160536 160537 160538 160539 160540 160541 160542 160543 160544 160545 160546 160547 160548 160549 160550 160551 160552 160553 160554 160555 160556 160557 160558 160559 160560 160561 160562 160563 160564 160565 160566 160567 160568 160569 160570 160571 160572 160573 160574 160575 160576 160577 160578 160579 160580 160581 160582 160583 160584 160585 160586 160587 160588 160589 160590 160591 160592 160593 160594 160595 160596 160597 160598 160599 160600 160601 160602 160603 160604 160605 160606 160607 160608 160609 160610 160611 160612 160613 160614 160615 160616 160617 160618 160619 160620 160621 | return rc; } /* ** Memory barrier. */ static void rbuVfsShmBarrier(sqlite3_file *pFile){ rbu_file *p = (rbu_file *)pFile; p->pReal->pMethods->xShmBarrier(p->pReal); } /* ** The xShmUnmap method. */ static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){ rbu_file *p = (rbu_file*)pFile; int rc = SQLITE_OK; int eStage = (p->pRbu ? p->pRbu->eStage : 0); assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){ /* no-op */ }else{ /* Release the checkpointer and writer locks */ rbuUnlockShm(p); rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag); } return rc; } /* ** Given that zWal points to a buffer containing a wal file name passed to ** either the xOpen() or xAccess() VFS method, return a pointer to the ** file-handle opened by the same database connection on the corresponding ** database file. */ static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal){ rbu_file *pDb; sqlite3_mutex_enter(pRbuVfs->mutex); for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext); sqlite3_mutex_leave(pRbuVfs->mutex); return pDb; } /* ** Open an rbu file handle. */ static int rbuVfsOpen( sqlite3_vfs *pVfs, const char *zName, sqlite3_file *pFile, int flags, int *pOutFlags ){ static sqlite3_io_methods rbuvfs_io_methods = { 2, /* iVersion */ rbuVfsClose, /* xClose */ rbuVfsRead, /* xRead */ rbuVfsWrite, /* xWrite */ rbuVfsTruncate, /* xTruncate */ rbuVfsSync, /* xSync */ rbuVfsFileSize, /* xFileSize */ rbuVfsLock, /* xLock */ rbuVfsUnlock, /* xUnlock */ rbuVfsCheckReservedLock, /* xCheckReservedLock */ rbuVfsFileControl, /* xFileControl */ rbuVfsSectorSize, /* xSectorSize */ rbuVfsDeviceCharacteristics, /* xDeviceCharacteristics */ rbuVfsShmMap, /* xShmMap */ rbuVfsShmLock, /* xShmLock */ rbuVfsShmBarrier, /* xShmBarrier */ rbuVfsShmUnmap /* xShmUnmap */ }; rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs; sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs; rbu_file *pFd = (rbu_file *)pFile; int rc = SQLITE_OK; const char *zOpen = zName; memset(pFd, 0, sizeof(rbu_file)); pFd->pReal = (sqlite3_file*)&pFd[1]; pFd->pRbuVfs = pRbuVfs; pFd->openFlags = flags; if( zName ){ if( flags & SQLITE_OPEN_MAIN_DB ){ /* A main database has just been opened. The following block sets ** (pFd->zWal) to point to a buffer owned by SQLite that contains ** the name of the *-wal file this db connection will use. SQLite ** happens to pass a pointer to this buffer when using xAccess() |
︙ | ︙ | |||
160433 160434 160435 160436 160437 160438 160439 | }else{ while( *z==0 ) z++; } z += (n + 8 + 1); pFd->zWal = z; } else if( flags & SQLITE_OPEN_WAL ){ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 160635 160636 160637 160638 160639 160640 160641 160642 160643 160644 160645 160646 160647 160648 160649 160650 160651 160652 160653 160654 160655 160656 160657 160658 160659 160660 160661 160662 160663 160664 160665 160666 160667 160668 160669 160670 160671 160672 160673 160674 160675 160676 160677 160678 160679 160680 160681 160682 160683 160684 160685 160686 160687 160688 160689 160690 160691 160692 160693 160694 160695 160696 160697 160698 160699 160700 160701 160702 160703 160704 160705 160706 160707 160708 160709 160710 160711 160712 160713 160714 160715 160716 160717 160718 160719 160720 160721 160722 160723 160724 160725 160726 160727 160728 160729 160730 160731 160732 160733 160734 160735 160736 160737 160738 160739 160740 160741 160742 160743 160744 160745 160746 160747 160748 160749 160750 160751 160752 160753 160754 160755 160756 160757 160758 160759 160760 160761 160762 160763 160764 160765 160766 160767 160768 160769 160770 160771 160772 160773 160774 160775 160776 160777 160778 160779 160780 160781 160782 160783 160784 160785 160786 160787 160788 160789 160790 160791 160792 160793 160794 160795 160796 160797 160798 160799 160800 160801 160802 160803 160804 160805 160806 160807 160808 160809 160810 160811 160812 160813 160814 160815 160816 160817 160818 160819 160820 160821 160822 160823 160824 160825 160826 160827 160828 160829 160830 160831 160832 160833 160834 160835 160836 160837 160838 160839 160840 160841 160842 160843 160844 160845 160846 160847 160848 160849 160850 160851 160852 160853 160854 160855 160856 160857 160858 160859 160860 160861 160862 160863 160864 160865 160866 160867 160868 160869 160870 160871 160872 160873 160874 160875 160876 160877 160878 160879 160880 160881 160882 160883 160884 160885 160886 160887 160888 160889 160890 160891 160892 160893 160894 160895 160896 160897 160898 160899 160900 160901 160902 160903 160904 160905 | }else{ while( *z==0 ) z++; } z += (n + 8 + 1); pFd->zWal = z; } else if( flags & SQLITE_OPEN_WAL ){ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName); if( pDb ){ if( pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ /* This call is to open a *-wal file. Intead, open the *-oal. This ** code ensures that the string passed to xOpen() is terminated by a ** pair of '\0' bytes in case the VFS attempts to extract a URI ** parameter from it. */ int nCopy = strlen(zName); char *zCopy = sqlite3_malloc(nCopy+2); if( zCopy ){ memcpy(zCopy, zName, nCopy); zCopy[nCopy-3] = 'o'; zCopy[nCopy] = '\0'; zCopy[nCopy+1] = '\0'; zOpen = (const char*)(pFd->zDel = zCopy); }else{ rc = SQLITE_NOMEM; } pFd->pRbu = pDb->pRbu; } pDb->pWalFd = pFd; } } } if( rc==SQLITE_OK ){ rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, flags, pOutFlags); } if( pFd->pReal->pMethods ){ /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods ** pointer and, if the file is a main database file, link it into the ** mutex protected linked list of all such files. */ pFile->pMethods = &rbuvfs_io_methods; if( flags & SQLITE_OPEN_MAIN_DB ){ sqlite3_mutex_enter(pRbuVfs->mutex); pFd->pMainNext = pRbuVfs->pMain; pRbuVfs->pMain = pFd; sqlite3_mutex_leave(pRbuVfs->mutex); } }else{ sqlite3_free(pFd->zDel); } return rc; } /* ** Delete the file located at zPath. */ static int rbuVfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xDelete(pRealVfs, zPath, dirSync); } /* ** Test for access permissions. Return true if the requested permission ** is available, or false otherwise. */ static int rbuVfsAccess( sqlite3_vfs *pVfs, const char *zPath, int flags, int *pResOut ){ rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs; sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs; int rc; rc = pRealVfs->xAccess(pRealVfs, zPath, flags, pResOut); /* If this call is to check if a *-wal file associated with an RBU target ** database connection exists, and the RBU update is in RBU_STAGE_OAL, ** the following special handling is activated: ** ** a) if the *-wal file does exist, return SQLITE_CANTOPEN. This ** ensures that the RBU extension never tries to update a database ** in wal mode, even if the first page of the database file has ** been damaged. ** ** b) if the *-wal file does not exist, claim that it does anyway, ** causing SQLite to call xOpen() to open it. This call will also ** be intercepted (see the rbuVfsOpen() function) and the *-oal ** file opened instead. */ if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zPath); if( pDb && pDb->pRbu && pDb->pRbu->eStage==RBU_STAGE_OAL ){ if( *pResOut ){ rc = SQLITE_CANTOPEN; }else{ *pResOut = 1; } } } return rc; } /* ** Populate buffer zOut with the full canonical pathname corresponding ** to the pathname in zPath. zOut is guaranteed to point to a buffer ** of at least (DEVSYM_MAX_PATHNAME+1) bytes. */ static int rbuVfsFullPathname( sqlite3_vfs *pVfs, const char *zPath, int nOut, char *zOut ){ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xFullPathname(pRealVfs, zPath, nOut, zOut); } #ifndef SQLITE_OMIT_LOAD_EXTENSION /* ** Open the dynamic library located at zPath and return a handle. */ static void *rbuVfsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xDlOpen(pRealVfs, zPath); } /* ** Populate the buffer zErrMsg (size nByte bytes) with a human readable ** utf-8 string describing the most recent error encountered associated ** with dynamic libraries. */ static void rbuVfsDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; pRealVfs->xDlError(pRealVfs, nByte, zErrMsg); } /* ** Return a pointer to the symbol zSymbol in the dynamic library pHandle. */ static void (*rbuVfsDlSym( sqlite3_vfs *pVfs, void *pArg, const char *zSym ))(void){ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xDlSym(pRealVfs, pArg, zSym); } /* ** Close the dynamic library handle pHandle. */ static void rbuVfsDlClose(sqlite3_vfs *pVfs, void *pHandle){ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xDlClose(pRealVfs, pHandle); } #endif /* SQLITE_OMIT_LOAD_EXTENSION */ /* ** Populate the buffer pointed to by zBufOut with nByte bytes of ** random data. */ static int rbuVfsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xRandomness(pRealVfs, nByte, zBufOut); } /* ** Sleep for nMicro microseconds. Return the number of microseconds ** actually slept. */ static int rbuVfsSleep(sqlite3_vfs *pVfs, int nMicro){ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xSleep(pRealVfs, nMicro); } /* ** Return the current time as a Julian Day number in *pTimeOut. */ static int rbuVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xCurrentTime(pRealVfs, pTimeOut); } /* ** No-op. */ static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){ return 0; } /* ** Deregister and destroy an RBU vfs created by an earlier call to ** sqlite3rbu_create_vfs(). */ SQLITE_API void SQLITE_STDCALL sqlite3rbu_destroy_vfs(const char *zName){ sqlite3_vfs *pVfs = sqlite3_vfs_find(zName); if( pVfs && pVfs->xOpen==rbuVfsOpen ){ sqlite3_mutex_free(((rbu_vfs*)pVfs)->mutex); sqlite3_vfs_unregister(pVfs); sqlite3_free(pVfs); } } /* ** Create an RBU VFS named zName that accesses the underlying file-system ** via existing VFS zParent. The new object is registered as a non-default ** VFS with SQLite before returning. */ SQLITE_API int SQLITE_STDCALL sqlite3rbu_create_vfs(const char *zName, const char *zParent){ /* Template for VFS */ static sqlite3_vfs vfs_template = { 1, /* iVersion */ 0, /* szOsFile */ 0, /* mxPathname */ 0, /* pNext */ 0, /* zName */ 0, /* pAppData */ rbuVfsOpen, /* xOpen */ rbuVfsDelete, /* xDelete */ rbuVfsAccess, /* xAccess */ rbuVfsFullPathname, /* xFullPathname */ #ifndef SQLITE_OMIT_LOAD_EXTENSION rbuVfsDlOpen, /* xDlOpen */ rbuVfsDlError, /* xDlError */ rbuVfsDlSym, /* xDlSym */ rbuVfsDlClose, /* xDlClose */ #else 0, 0, 0, 0, #endif rbuVfsRandomness, /* xRandomness */ rbuVfsSleep, /* xSleep */ rbuVfsCurrentTime, /* xCurrentTime */ rbuVfsGetLastError, /* xGetLastError */ 0, /* xCurrentTimeInt64 (version 2) */ 0, 0, 0 /* Unimplemented version 3 methods */ }; rbu_vfs *pNew = 0; /* Newly allocated VFS */ int nName; int rc = SQLITE_OK; int nByte; nName = strlen(zName); nByte = sizeof(rbu_vfs) + nName + 1; pNew = (rbu_vfs*)sqlite3_malloc(nByte); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ sqlite3_vfs *pParent; /* Parent VFS */ memset(pNew, 0, nByte); pParent = sqlite3_vfs_find(zParent); if( pParent==0 ){ rc = SQLITE_NOTFOUND; }else{ char *zSpace; memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs)); pNew->base.mxPathname = pParent->mxPathname; pNew->base.szOsFile = sizeof(rbu_file) + pParent->szOsFile; pNew->pRealVfs = pParent; pNew->base.zName = (const char*)(zSpace = (char*)&pNew[1]); memcpy(zSpace, zName, nName); /* Allocate the mutex and register the new VFS (not as the default) */ pNew->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE); if( pNew->mutex==0 ){ |
︙ | ︙ | |||
160715 160716 160717 160718 160719 160720 160721 | return rc; } /**************************************************************************/ | | | | 160917 160918 160919 160920 160921 160922 160923 160924 160925 160926 160927 160928 160929 160930 160931 160932 160933 | return rc; } /**************************************************************************/ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */ /************** End of sqlite3rbu.c ******************************************/ /************** Begin file dbstat.c ******************************************/ /* ** 2010 July 12 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** |
︙ | ︙ | |||
160739 160740 160741 160742 160743 160744 160745 160746 160747 160748 160749 160750 160751 160752 | ** ** The dbstat virtual table is used to extract low-level formatting ** information from an SQLite database in order to implement the ** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script ** for an example implementation. */ #if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \ && !defined(SQLITE_OMIT_VIRTUALTABLE) /* ** Page paths: ** ** The value of the 'path' column describes the path taken from the | > | 160941 160942 160943 160944 160945 160946 160947 160948 160949 160950 160951 160952 160953 160954 160955 | ** ** The dbstat virtual table is used to extract low-level formatting ** information from an SQLite database in order to implement the ** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script ** for an example implementation. */ /* #include "sqliteInt.h" ** Requires access to internal data structures ** */ #if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \ && !defined(SQLITE_OMIT_VIRTUALTABLE) /* ** Page paths: ** ** The value of the 'path' column describes the path taken from the |
︙ | ︙ |
Changes to src/sqlite3.h.
︙ | ︙ | |||
109 110 111 112 113 114 115 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.11" #define SQLITE_VERSION_NUMBER 3008011 | | | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.8.11" #define SQLITE_VERSION_NUMBER 3008011 #define SQLITE_SOURCE_ID "2015-07-23 20:44:49 017c5019e1ce042025d4f327e50ec50af49f9fa4" /* ** 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 |
︙ | ︙ | |||
963 964 965 966 967 968 969 | ** circumstances in order to fix a problem with priority inversion. ** Applications should <em>not</em> use this file-control. ** ** <li>[[SQLITE_FCNTL_ZIPVFS]] ** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other ** VFS should return SQLITE_NOTFOUND for this opcode. ** | | | | | 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 | ** circumstances in order to fix a problem with priority inversion. ** Applications should <em>not</em> use this file-control. ** ** <li>[[SQLITE_FCNTL_ZIPVFS]] ** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other ** VFS should return SQLITE_NOTFOUND for this opcode. ** ** <li>[[SQLITE_FCNTL_RBU]] ** The [SQLITE_FCNTL_RBU] opcode is implemented by the special VFS used by ** the RBU extension only. All other VFS should return SQLITE_NOTFOUND for ** this opcode. ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 #define SQLITE_FCNTL_LAST_ERRNO 4 |
︙ | ︙ | |||
993 994 995 996 997 998 999 | #define SQLITE_FCNTL_TRACE 19 #define SQLITE_FCNTL_HAS_MOVED 20 #define SQLITE_FCNTL_SYNC 21 #define SQLITE_FCNTL_COMMIT_PHASETWO 22 #define SQLITE_FCNTL_WIN32_SET_HANDLE 23 #define SQLITE_FCNTL_WAL_BLOCK 24 #define SQLITE_FCNTL_ZIPVFS 25 | | | 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 | #define SQLITE_FCNTL_TRACE 19 #define SQLITE_FCNTL_HAS_MOVED 20 #define SQLITE_FCNTL_SYNC 21 #define SQLITE_FCNTL_COMMIT_PHASETWO 22 #define SQLITE_FCNTL_WIN32_SET_HANDLE 23 #define SQLITE_FCNTL_WAL_BLOCK 24 #define SQLITE_FCNTL_ZIPVFS 25 #define SQLITE_FCNTL_RBU 26 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO |
︙ | ︙ |
Changes to src/th_main.c.
︙ | ︙ | |||
335 336 337 338 339 340 341 342 343 344 345 346 347 348 | ){ if( argc!=2 ){ return Th_WrongNumArgs(interp, "puts STRING"); } sendText((char*)argv[1], argl[1], *(unsigned int*)pConvert); return TH_OK; } /* ** TH1 command: decorate STRING ** TH1 command: wiki STRING ** ** Render the input string as wiki. For the decorate command, only links ** are handled. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | ){ if( argc!=2 ){ return Th_WrongNumArgs(interp, "puts STRING"); } sendText((char*)argv[1], argl[1], *(unsigned int*)pConvert); return TH_OK; } /* ** TH1 command: markdown STRING ** ** Renders the input string as markdown. The result is a two-element list. ** The first element is the text-only title string. The second element ** contains the body, rendered as HTML. */ static int markdownCmd( Th_Interp *interp, void *p, int argc, const char **argv, int *argl ){ Blob src, title, body; char *zValue = 0; int nValue = 0; if( argc!=2 ){ return Th_WrongNumArgs(interp, "markdown STRING"); } blob_zero(&src); blob_init(&src, (char*)argv[1], argl[1]); blob_zero(&title); blob_zero(&body); markdown_to_html(&src, &title, &body); Th_ListAppend(interp, &zValue, &nValue, blob_str(&title), blob_size(&title)); Th_ListAppend(interp, &zValue, &nValue, blob_str(&body), blob_size(&body)); Th_SetResult(interp, zValue, nValue); return TH_OK; } /* ** TH1 command: decorate STRING ** TH1 command: wiki STRING ** ** Render the input string as wiki. For the decorate command, only links ** are handled. |
︙ | ︙ | |||
1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 | {"httpize", httpizeCmd, 0}, {"hascap", hascapCmd, (void*)&zeroInt}, {"hasfeature", hasfeatureCmd, 0}, {"html", putsCmd, (void*)&aFlags[0]}, {"htmlize", htmlizeCmd, 0}, {"http", httpCmd, 0}, {"linecount", linecntCmd, 0}, {"puts", putsCmd, (void*)&aFlags[1]}, {"query", queryCmd, 0}, {"randhex", randhexCmd, 0}, {"regexp", regexpCmd, 0}, {"reinitialize", reinitializeCmd, 0}, {"render", renderCmd, 0}, {"repository", repositoryCmd, 0}, | > | 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 | {"httpize", httpizeCmd, 0}, {"hascap", hascapCmd, (void*)&zeroInt}, {"hasfeature", hasfeatureCmd, 0}, {"html", putsCmd, (void*)&aFlags[0]}, {"htmlize", htmlizeCmd, 0}, {"http", httpCmd, 0}, {"linecount", linecntCmd, 0}, {"markdown", markdownCmd, 0}, {"puts", putsCmd, (void*)&aFlags[1]}, {"query", queryCmd, 0}, {"randhex", randhexCmd, 0}, {"regexp", regexpCmd, 0}, {"reinitialize", reinitializeCmd, 0}, {"render", renderCmd, 0}, {"repository", repositoryCmd, 0}, |
︙ | ︙ |
Changes to test/th1.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # http://www.hwaci.com/drh/ # ############################################################################ # # TH1 Commands # fossil test-th-eval --open-config "setting th1-hooks" set th1Hooks [expr {$RESULT eq "1"}] ############################################################################### fossil test-th-eval --open-config "setting abc" test th1-setting-1 {$RESULT eq ""} | > > > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # http://www.hwaci.com/drh/ # ############################################################################ # # TH1 Commands # set dir [file dirname [info script]] ############################################################################### fossil test-th-eval --open-config "setting th1-hooks" set th1Hooks [expr {$RESULT eq "1"}] ############################################################################### fossil test-th-eval --open-config "setting abc" test th1-setting-1 {$RESULT eq ""} |
︙ | ︙ | |||
857 858 859 860 861 862 863 | # NOTE: This test may fail if the command names do not always come # out in a deterministic order from TH1. # fossil test-th-eval "info commands" test th1-info-commands-1 {$RESULT eq {linecount htmlize date stime\ enable_output uplevel http expr glob_match utime styleFooter catch if\ tclReady searchable reinitialize combobox lindex query html anoncap randhex\ | | | | 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 | # NOTE: This test may fail if the command names do not always come # out in a deterministic order from TH1. # fossil test-th-eval "info commands" test th1-info-commands-1 {$RESULT eq {linecount htmlize date stime\ enable_output uplevel http expr glob_match utime styleFooter catch if\ tclReady searchable reinitialize combobox lindex query html anoncap randhex\ llength for set break regexp markdown styleHeader puts return checkout\ decorate artifact trace wiki proc hascap globalState continue getParameter\ hasfeature setting lsearch breakpoint upvar render repository string unset\ setParameter list error info rename anycap httpize}} ############################################################################### fossil test-th-eval "info vars" test th1-info-vars-1 {$RESULT eq ""} |
︙ | ︙ | |||
1169 1170 1171 1172 1173 1174 1175 | fossil test-th-eval {string is integer 0xC0DEF00D} test th1-string-is-30 {$RESULT eq "1"} ############################################################################### fossil test-th-eval {string is integer 0xC0DEF00Z} test th1-string-is-31 {$RESULT eq "0"} | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 | fossil test-th-eval {string is integer 0xC0DEF00D} test th1-string-is-30 {$RESULT eq "1"} ############################################################################### fossil test-th-eval {string is integer 0xC0DEF00Z} test th1-string-is-31 {$RESULT eq "0"} ############################################################################### fossil test-th-eval {markdown} test th1-markdown-1 {$RESULT eq \ {TH_ERROR: wrong # args: should be "markdown STRING"}} ############################################################################### fossil test-th-eval {markdown one two} test th1-markdown-2 {$RESULT eq \ {TH_ERROR: wrong # args: should be "markdown STRING"}} ############################################################################### fossil test-th-eval {markdown "*This is a test.*"} test th1-markdown-3 {[normalize_result] eq {{} {<div class="markdown"> <p><em>This is a test.</em></p> </div> }}} ############################################################################### fossil test-th-eval {markdown "Test1\n=====\n*This is a test.*"} test th1-markdown-4 {[normalize_result] eq {Test1 {<div class="markdown"> <h1>Test1</h1> <p><em>This is a test.</em></p> </div> }}} ############################################################################### set markdown [read_file [file join $dir markdown-test1.md]] fossil test-th-eval [string map \ [list %markdown% $markdown] {markdown {%markdown%}}] test th1-markdown-5 {[normalize_result] eq \ {{Markdown Formatter Test Document} {<div class="markdown"> <h1>Markdown Formatter Test Document</h1> <p>This document is designed to test the markdown formatter.</p> <ul> <li>A bullet item. <ul> <li>A subitem</li> </ul></li> <li>Second bullet</li> </ul> <p>More text</p> <ol> <li>Enumeration 1.1. Subitem 1 1.2. Subitem 2</li> <li>Second enumeration.</li> </ol> <p>Another paragraph.</p> <h2>Other Features</h2> <p>Text can show <em>emphasis</em> or <em>emphasis</em> or <strong>strong emphassis</strong>.</p> </div> }}} |
Changes to www/changes.wiki.
1 2 3 | <title>Change Log</title> <h2>Changes for Version 1.34 (2015-??-??)</h2> | | > | | > | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <title>Change Log</title> <h2>Changes for Version 1.34 (2015-??-??)</h2> * Fix --hard option to [/help?cmd=mv|fossil mv] and [/help?cmd=rm|fossil rm] to enable them to work properly with certain relative paths. * Make the [/help?cmd=clean|fossil clean] command undoable for files less than 10MiB. * Add minimal <nowiki>[lsearch]</nowiki> command to TH1. Only exact case-sensitive matching is supported. * Add the <nowiki>[glob_match]</nowiki> and <nowiki>[markdown]</nowiki> commands to TH1. * Add the <nowiki>[tclIsSafe] and [tclMakeSafe]</nowiki> TH1 commands to the Tcl integration subsystem. * Add 'double', 'integer', and 'list' classes to the <nowiki>[string is]</nowiki> command in TH1. * Update internal Unicode character tables, used in regular expression handling, from version 7.0 to 8.0. |
︙ | ︙ |
Changes to www/settings.wiki.
︙ | ︙ | |||
40 41 42 43 44 45 46 | <tt>manifest</tt>. The most important is <tt>ignore-glob</tt> which specifies which files should be ignored when looking for unmanaged files with the <tt>extras</tt> command. Because these options can change over time, and the inconvenience of replicating changes, these settings are "versionable". As well as being able to be set using the <tt>settings</tt> command or the web interface, | | > | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | <tt>manifest</tt>. The most important is <tt>ignore-glob</tt> which specifies which files should be ignored when looking for unmanaged files with the <tt>extras</tt> command. Because these options can change over time, and the inconvenience of replicating changes, these settings are "versionable". As well as being able to be set using the <tt>settings</tt> command or the web interface, you can create versioned files in the <tt>.fossil-settings</tt> subdirectory of the check-out root, named with the setting name. The contents of the file is the value of the setting, and these files are checked in, committed, merged, and so on, as with any other file. Where a setting is a list of values, such as <tt>ignore-glob</tt>, you can use a newline as a separator as well as a comma. For example, to set the list of ignored files, create a |
︙ | ︙ |
Changes to www/th1.md.
︙ | ︙ | |||
137 138 139 140 141 142 143 144 145 146 147 148 149 150 | * hascap * hasfeature * html * htmlize * http * httpize * linecount * puts * query * randhex * regexp * reinitialize * render * repository | > | 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | * hascap * hasfeature * html * htmlize * http * httpize * linecount * markdown * puts * query * randhex * regexp * reinitialize * render * repository |
︙ | ︙ | |||
348 349 350 351 352 353 354 355 356 357 358 359 360 361 | <a name="linecount"></a>TH1 linecount Command --------------------------------------------- * linecount STRING MAX MIN Returns one more than the number of \n characters in STRING. But never returns less than MIN or more than MAX. <a name="puts"></a>TH1 puts Command ----------------------------------- * puts STRING Outputs the STRING unchanged. | > > > > > > > > > | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | <a name="linecount"></a>TH1 linecount Command --------------------------------------------- * linecount STRING MAX MIN Returns one more than the number of \n characters in STRING. But never returns less than MIN or more than MAX. <a name="markdown"></a>TH1 markdown Command --------------------------------------------- * markdown STRING Renders the input string as markdown. The result is a two-element list. The first element contains the body, rendered as HTML. The second element is the text-only title string. <a name="puts"></a>TH1 puts Command ----------------------------------- * puts STRING Outputs the STRING unchanged. |
︙ | ︙ |
Changes to www/webui.wiki.
︙ | ︙ | |||
59 60 61 62 63 64 65 | from within an open check-out, you can omit the repository name: <b>fossil ui</b> The latter case is a very useful short-cut when you are working on a Fossil project and you want to quickly do some work with the web interface. Notice that Fossil automatically finds an unused TCP port to run the | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | from within an open check-out, you can omit the repository name: <b>fossil ui</b> The latter case is a very useful short-cut when you are working on a Fossil project and you want to quickly do some work with the web interface. Notice that Fossil automatically finds an unused TCP port to run the server on and automatically points your web browser to the correct URL. So there is never any fumbling around trying to find an open port or to type arcane strings into your browser URL entry box. The interface just pops right up, ready to run. The Fossil web interface is also very easy to setup and run on a network server, as either a CGI program or from inetd, or as an SCGI server. Details on how |
︙ | ︙ |