Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch branch-3.48 Excluding Merge-Ins
This is equivalent to a diff from d2fe6b05f3 to fddcfbcafd
2025-02-05
| ||
12:49 | Upstream JimTCL patch and minor tcl script tweaks to support (fconfigure -translation binary) for better cross-platform build portability. (check-in: 0974a17c45 user: stephan tags: trunk) | |
12:15 | Portability tweaks to the code generators so that they produce identical output with JimTCL on Windows and Unix systems (that is: no Windows-style line endings). (Leaf check-in: fddcfbcafd user: stephan tags: branch-3.48) | |
2025-02-03
| ||
17:45 | New test case for test/fuzzdata8.db (check-in: 8a882f976e user: drh tags: fuzz-data) | |
14:44 | Fix the build process on Windows so that it generates identical sqlite3.c, sqlite3.h, and shell.c files on Windows and Unix. This patch also includes a change to JS bindings that got caught up in the branch. (check-in: 91ef45fc29 user: drh tags: trunk) | |
2025-01-31
| ||
18:34 | Remove an assert() that is not true if a trace-callback is deregistered while there are active statements. (check-in: d53c58243d user: dan tags: branch-3.48) | |
2025-01-15
| ||
14:31 | Disable the C-style comment stripper in the JS dist build, as explained in forum post 529c20d344. (check-in: 76ffc70f13 user: stephan tags: branch-3.48) | |
2025-01-14
| ||
16:10 | Trying to remove a warning from some compiler that I do not have access to. (check-in: bc6de90c70 user: drh tags: trunk) | |
12:43 | Version 3.48.0 for the reuse-schema branch. (check-in: 1a031a536b user: drh tags: reuse-schema) | |
12:21 | Version 3.48.0 for the wal2 branch. (check-in: ef970ef037 user: drh tags: wal2) | |
12:15 | Version 3.48.0 for the begin-concurrent branch. (check-in: 56d110b636 user: drh tags: begin-concurrent) | |
11:05 | Version 3.48.0 (check-in: d2fe6b05f3 user: drh tags: trunk, release, major-release, version-3.48.0) | |
2025-01-13
| ||
13:32 | Remove a stray tab character from a comment. (check-in: 315079b150 user: drh tags: trunk) | |
Changes to Makefile.in.
︙ | ︙ | |||
331 332 333 334 335 336 337 338 | # # tool/version-info: a utility for emitting sqlite3 version info # in various forms. # version-info$(T.exe): $(TOP)/tool/version-info.c Makefile sqlite3.h $(T.link) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c include $(TOP)/main.mk | > | 331 332 333 334 335 336 337 338 339 | # # tool/version-info: a utility for emitting sqlite3 version info # in various forms. # version-info$(T.exe): $(TOP)/tool/version-info.c Makefile sqlite3.h $(T.link) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c IS_CROSS_COMPILING = @IS_CROSS_COMPILING@ include $(TOP)/main.mk |
Changes to Makefile.msc.
︙ | ︙ | |||
2330 2331 2332 2333 2334 2335 2336 | parse.c: $(TOP)\src\parse.y lemon.exe del /Q parse.y parse.h parse.h.temp 2>NUL copy /Y $(TOP)\src\parse.y . copy /B parse.y +,, .\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) -S parse.y $(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION $(JIM_TCLSH) | | | 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 | parse.c: $(TOP)\src\parse.y lemon.exe del /Q parse.y parse.h parse.h.temp 2>NUL copy /Y $(TOP)\src\parse.y . copy /B parse.y +,, .\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) -S parse.y $(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION $(JIM_TCLSH) $(JIM_TCLSH) $(TOP)\tool\mksqlite3h.tcl "$(TOP:\=/)" -o $(SQLITE3H) $(MKSQLITE3H_ARGS) sqlite3ext.h: .target_source !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0 type tsrc\sqlite3ext.h | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*\)" "(SQLITE_CALLBACK *)" \ | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*" "(SQLITE_APICALL *" > sqlite3ext.h copy /Y sqlite3ext.h tsrc\sqlite3ext.h !ELSE |
︙ | ︙ | |||
2394 2395 2396 2397 2398 2399 2400 | # !IF $(USE_ZLIB)!=0 SHELL_DEP = $(SHELL_DEP) $(TOP)\ext\misc\sqlar.c SHELL_DEP = $(SHELL_DEP) $(TOP)\ext\misc\zipfile.c !ENDIF shell.c: $(SHELL_DEP) $(TOP)\tool\mkshellc.tcl $(JIM_TCLSH) | | | 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 | # !IF $(USE_ZLIB)!=0 SHELL_DEP = $(SHELL_DEP) $(TOP)\ext\misc\sqlar.c SHELL_DEP = $(SHELL_DEP) $(TOP)\ext\misc\zipfile.c !ENDIF shell.c: $(SHELL_DEP) $(TOP)\tool\mkshellc.tcl $(JIM_TCLSH) $(JIM_TCLSH) $(TOP)\tool\mkshellc.tcl shell.c zlib: pushd $(ZLIBDIR) && $(MAKE) /f win32\Makefile.msc clean $(ZLIBLIB) && popd # Rules to build the extension objects. # icu.lo: $(TOP)\ext\icu\icu.c $(HDR) $(EXTHDR) |
︙ | ︙ | |||
2807 2808 2809 2810 2811 2812 2813 | moreclean: clean del /Q $(SQLITE3C) $(SQLITE3H) 2>NUL # <</mark>> clean: del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL | | > | 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 | moreclean: clean del /Q $(SQLITE3C) $(SQLITE3H) 2>NUL # <</mark>> clean: del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL del /Q sqlite3.def tclsqlite3.def 2>NUL del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL # <<mark>> del /Q $(SQLITE3TCLDLL) pkgIndex.tcl 2>NUL del /Q opcodes.c opcodes.h 2>NUL del /Q lemon.* lempar.c parse.* 2>NUL del /Q mksourceid.* mkkeywordhash.* keywordhash.h 2>NUL del /Q notasharedlib.* 2>NUL |
︙ | ︙ |
Changes to VERSION.
|
| | | 1 | 3.48.1 |
Changes to auto.def.
︙ | ︙ | |||
321 322 323 324 325 326 327 | ######################################################################## # We differentiate between two C compilers: the one used for binaries # which are to run on the build system (in autosetup it's called # CC_FOR_BUILD and in Makefile.in it's $(B.cc)) and the one used for # compiling binaries for the target system (CC a.k.a. $(T.cc)). # Normally they're the same, but they will differ when # cross-compiling. | > > > > > > > > | > > > > | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | ######################################################################## # We differentiate between two C compilers: the one used for binaries # which are to run on the build system (in autosetup it's called # CC_FOR_BUILD and in Makefile.in it's $(B.cc)) and the one used for # compiling binaries for the target system (CC a.k.a. $(T.cc)). # Normally they're the same, but they will differ when # cross-compiling. # # When cross-compiling we default to not using the -g flag, based on a # /chat discussion prompted by # https://sqlite.org/forum/forumpost/9a67df63eda9925c set defaultCFlags {-O2} if {!$isCrossCompiling} { lappend defaultCFlags -g } define CFLAGS [proj-get-env CFLAGS $defaultCFlags] # BUILD_CFLAGS is the CFLAGS for CC_FOR_BUILD. define BUILD_CFLAGS [proj-get-env BUILD_CFLAGS {-g}] unset defaultCFlags proj-if-opt-truthy dev { # --enable-dev needs to come early so that the downstream tests # which check for the following flags use their updated state. proj-opt-set all 1 proj-opt-set debug 1 proj-opt-set amalgamation 0 define CFLAGS [get-env CFLAGS {-O0 -g}] # -------------^^^^^^^ intentionally using [get-env] instead of # [proj-get-env] here. } ######################################################################## # Handle --with-wasi-sdk=DIR # # This must be run relatively early on because it may change the # toolchain and disable a number of config options. |
︙ | ︙ | |||
471 472 473 474 475 476 477 | # and this project has no direct use for soname, so default to # none. Package maintainers, on the other hand, like to have an # soname. set soname none } switch -exact -- $soname { none - "" { return 0 } | < | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 | # and this project has no direct use for soname, so default to # none. Package maintainers, on the other hand, like to have an # soname. set soname none } switch -exact -- $soname { none - "" { return 0 } legacy { set soname libsqlite3.so.0 } default { if {[string match libsqlite3.* $soname]} { # use it as-is } else { # Assume it's a suffix set soname "libsqlite3.so.${soname}" |
︙ | ︙ | |||
600 601 602 603 604 605 606 | msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}" } set doConfigLookup 1 ; # set to 0 to test the tclConfig.sh-not-found cases if {"" ne $with_tclsh} { # --with-tclsh was provided or found above. Validate it and use it # to trump any value passed via --with-tcl=DIR. | < < | | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | msg-debug "sqlite-check-tcl: with_tclsh=${with_tclsh}" } set doConfigLookup 1 ; # set to 0 to test the tclConfig.sh-not-found cases if {"" ne $with_tclsh} { # --with-tclsh was provided or found above. Validate it and use it # to trump any value passed via --with-tcl=DIR. if {![file-isexec $with_tclsh]} { proj-fatal "TCL shell $with_tclsh is not executable" } else { define TCLSH_CMD $with_tclsh #msg-result "Using tclsh: $with_tclsh" } if {$doConfigLookup && [catch {exec $with_tclsh $srcdir/tool/find_tclconfig.tcl} result] == 0} { |
︙ | ︙ | |||
666 667 668 669 670 671 672 | msg-result "Using tclConfig.sh: $cfg" break } define TCL_CONFIG_SH $cfg # Export a subset of tclConfig.sh to the current TCL-space. If $cfg # is an empty string, this emits empty-string entries for the # various options we're interested in. | | > > | 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | msg-result "Using tclConfig.sh: $cfg" break } define TCL_CONFIG_SH $cfg # Export a subset of tclConfig.sh to the current TCL-space. If $cfg # is an empty string, this emits empty-string entries for the # various options we're interested in. eval [exec sh "$srcdir/tool/tclConfigShToAutoDef.sh" "$cfg"] # ---------^^ a Windows/msys workaround, without which it cannot # exec a .sh file: https://sqlite.org/forum/forumpost/befb352a42a7cd6d if {"" eq $with_tclsh && $cfg ne ""} { # We have tclConfig.sh but no tclsh. Attempt to locate a tclsh # based on info from tclConfig.sh. proj-assert {"" ne [get-define TCL_EXEC_PREFIX]} set with_tclsh [get-define TCL_EXEC_PREFIX]/bin/tclsh[get-define TCL_VERSION] if {![file-isexec $with_tclsh]} { |
︙ | ︙ | |||
1335 1336 1337 1338 1339 1340 1341 1342 1343 | if {[proj-opt-truthy $boolFlag]} { msg-result " + $boolFlag" } else { sqlite-add-feature-flag $featureFlag msg-result " - $boolFlag" } } ######################################################################### | > > > > > > > > > > > > > > > > > > > | > < > > > > > | 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 | if {[proj-opt-truthy $boolFlag]} { msg-result " + $boolFlag" } else { sqlite-add-feature-flag $featureFlag msg-result " - $boolFlag" } } ######################################################################## # Copy all CFLAGS entries matching -DSQLITE_OMIT* and # -DSQLITE_ENABLE* to OPT_FEATURE_FLAGS. This behavior is derived # from the legacy build and was missing the 3.48.0 release (the # initial Autosetup port). # https://sqlite.org/forum/forumpost/9801e54665afd728 # # If any configure flags for features are in conflict with # CFLAGS-specified feature flags, all bets are off. There are no # guarantees about which one will take precedence. foreach cf [get-define CFLAGS ""] { switch -glob -- $cf { -DSQLITE_OMIT* - -DSQLITE_ENABLE* { sqlite-add-feature-flag $cf } } } ######################################################################### # Remove duplicates from the final feature flag sets and show them to # the user: apply {{} { set oFF [get-define OPT_FEATURE_FLAGS] if {"" ne $oFF} { define OPT_FEATURE_FLAGS [lsort -unique $oFF] msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]" } set oFF [get-define OPT_SHELL] if {"" ne $oFF} { define OPT_SHELL [lsort -unique $oFF] msg-result "Shell options: [get-define OPT_SHELL]" } }} ######################################################################## # When cross-compiling, we have to avoid using the -s flag to # /usr/bin/install: https://sqlite.org/forum/forumpost/9a67df63eda9925c define IS_CROSS_COMPILING $isCrossCompiling ######################################################################## # "Re-export" the autoconf-conventional --XYZdir flags into something # which is more easily overridable from a make invocation. See the docs # for [proj-remap-autoconf-dir-vars] for the explanation of why. # # We do this late in the config process, immediately before we export |
︙ | ︙ |
Changes to autoconf/Makefile.msc.
︙ | ︙ | |||
1083 1084 1085 1086 1087 1088 1089 | echo #endif >> sqlite3rc.h $(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc !ENDIF clean: del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL | | > | 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 | echo #endif >> sqlite3rc.h $(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc !ENDIF clean: del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL del /Q sqlite3.def tclsqlite3.def 2>NUL del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL |
Changes to autoconf/tea/configure.ac.
︙ | ︙ | |||
15 16 17 18 19 20 21 | # This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION # set as provided. These will also be added as -D defs in your Makefile # so you can encode the package version directly into the source files. # This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME> # so that we create the export library with the dll. #----------------------------------------------------------------------- | | | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION # set as provided. These will also be added as -D defs in your Makefile # so you can encode the package version directly into the source files. # This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME> # so that we create the export library with the dll. #----------------------------------------------------------------------- AC_INIT([sqlite],[3.48.1]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. #-------------------------------------------------------------------- |
︙ | ︙ |
Changes to autosetup/jimsh0.c.
︙ | ︙ | |||
71 72 73 74 75 76 77 78 79 80 81 82 83 84 | #ifdef __cplusplus extern "C" { #endif #if defined(_WIN32) || defined(WIN32) #define HAVE_DLOPEN void *dlopen(const char *path, int mode); int dlclose(void *handle); void *dlsym(void *handle, const char *symbol); char *dlerror(void); | > > > | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | #ifdef __cplusplus extern "C" { #endif #if defined(_WIN32) || defined(WIN32) #ifndef STDIN_FILENO #define STDIN_FILENO 0 #endif #define HAVE_DLOPEN void *dlopen(const char *path, int mode); int dlclose(void *handle); void *dlsym(void *handle, const char *symbol); char *dlerror(void); |
︙ | ︙ | |||
1860 1861 1862 1863 1864 1865 1866 | " -bl* {\n" " $f ndelay $(!$v)\n" " }\n" " -bu* {\n" " $f buffering $v\n" " }\n" " -tr* {\n" | | | 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 | " -bl* {\n" " $f ndelay $(!$v)\n" " }\n" " -bu* {\n" " $f buffering $v\n" " }\n" " -tr* {\n" " $f translation $v\n" " }\n" " default {\n" " return -code error \"fconfigure: unknown option $n\"\n" " }\n" " }\n" " }\n" " }\n" |
︙ | ︙ | |||
2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 | if (af->wbuft == WBUF_OPT_FULL) { Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, af->wbuf_limit)); } Jim_SetResult(interp, resultObj); return JIM_OK; } static int aio_cmd_readsize(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); if (argc) { long l; | > > > > > > > > > > > > > > > > > > > > > > | 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 | if (af->wbuft == WBUF_OPT_FULL) { Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, af->wbuf_limit)); } Jim_SetResult(interp, resultObj); return JIM_OK; } static int aio_cmd_translation(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { enum {OPT_BINARY, OPT_TEXT}; static const char * const options[] = { "binary", "text", NULL }; int opt; if (Jim_GetEnum(interp, argv[0], options, &opt, NULL, JIM_ERRMSG) != JIM_OK) { return JIM_ERR; } #if defined(_setmode) && defined(O_BINARY) else { AioFile *af = Jim_CmdPrivData(interp); _setmode(af->fh, opt == OPT_BINARY ? O_BINARY : O_TEXT); } #endif return JIM_OK; } static int aio_cmd_readsize(Jim_Interp *interp, int argc, Jim_Obj *const *argv) { AioFile *af = Jim_CmdPrivData(interp); if (argc) { long l; |
︙ | ︙ | |||
3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 | #endif { "buffering", "?none|line|full? ?size?", aio_cmd_buffering, 0, 2, }, { "readsize", "?size?", aio_cmd_readsize, 0, 1, | > > > > > > > | 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 | #endif { "buffering", "?none|line|full? ?size?", aio_cmd_buffering, 0, 2, }, { "translation", "binary|text", aio_cmd_translation, 1, 1, }, { "readsize", "?size?", aio_cmd_readsize, 0, 1, |
︙ | ︙ | |||
24338 24339 24340 24341 24342 24343 24344 24345 24346 24347 24348 24349 24350 24351 | } #include <stdio.h> #include <stdlib.h> #include <string.h> extern int Jim_initjimshInit(Jim_Interp *interp); static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[]) { int n; Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); | > > > > | 24370 24371 24372 24373 24374 24375 24376 24377 24378 24379 24380 24381 24382 24383 24384 24385 24386 24387 | } #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef HAVE_UNISTD_H #include <unistd.h> #endif extern int Jim_initjimshInit(Jim_Interp *interp); static void JimSetArgv(Jim_Interp *interp, int argc, char *const argv[]) { int n; Jim_Obj *listObj = Jim_NewListObj(interp, NULL, 0); |
︙ | ︙ | |||
24421 24422 24423 24424 24425 24426 24427 24428 24429 24430 24431 24432 24433 24434 | if (argc == 1) { if (retcode == JIM_ERR) { JimPrintErrorMessage(interp); } if (retcode != JIM_EXIT) { JimSetArgv(interp, 0, NULL); retcode = Jim_InteractivePrompt(interp); } } else { if (argc > 2 && strcmp(argv[1], "-e") == 0) { | > > > > | 24457 24458 24459 24460 24461 24462 24463 24464 24465 24466 24467 24468 24469 24470 24471 24472 24473 24474 | if (argc == 1) { if (retcode == JIM_ERR) { JimPrintErrorMessage(interp); } if (retcode != JIM_EXIT) { JimSetArgv(interp, 0, NULL); if (!isatty(STDIN_FILENO)) { goto eval_stdin; } retcode = Jim_InteractivePrompt(interp); } } else { if (argc > 2 && strcmp(argv[1], "-e") == 0) { |
︙ | ︙ | |||
24443 24444 24445 24446 24447 24448 24449 24450 24451 24452 24453 24454 24455 24456 | putchar('\n'); } } else { Jim_SetVariableStr(interp, "argv0", Jim_NewStringObj(interp, argv[1], -1)); JimSetArgv(interp, argc - 2, argv + 2); if (strcmp(argv[1], "-") == 0) { retcode = Jim_Eval(interp, "eval [info source [stdin read] stdin 1]"); } else { retcode = Jim_EvalFile(interp, argv[1]); } } if (retcode == JIM_ERR) { JimPrintErrorMessage(interp); | > | 24483 24484 24485 24486 24487 24488 24489 24490 24491 24492 24493 24494 24495 24496 24497 | putchar('\n'); } } else { Jim_SetVariableStr(interp, "argv0", Jim_NewStringObj(interp, argv[1], -1)); JimSetArgv(interp, argc - 2, argv + 2); if (strcmp(argv[1], "-") == 0) { eval_stdin: retcode = Jim_Eval(interp, "eval [info source [stdin read] stdin 1]"); } else { retcode = Jim_EvalFile(interp, argv[1]); } } if (retcode == JIM_ERR) { JimPrintErrorMessage(interp); |
︙ | ︙ |
Changes to ext/fts5/fts5_index.c.
︙ | ︙ | |||
774 775 776 777 778 779 780 | fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret); return ret; } /* ** Close the read-only blob handle, if it is open. */ | | > | > | 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 | fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret); return ret; } /* ** Close the read-only blob handle, if it is open. */ static void fts5IndexCloseReader(Fts5Index *p){ if( p->pReader ){ int rc; sqlite3_blob *pReader = p->pReader; p->pReader = 0; rc = sqlite3_blob_close(pReader); if( p->rc==SQLITE_OK ) p->rc = rc; } } /* ** Retrieve a record from the %_data table. ** ** If an error occurs, NULL is returned and an error left in the |
︙ | ︙ | |||
803 804 805 806 807 808 809 | ** is required. */ sqlite3_blob *pBlob = p->pReader; p->pReader = 0; rc = sqlite3_blob_reopen(pBlob, iRowid); assert( p->pReader==0 ); p->pReader = pBlob; if( rc!=SQLITE_OK ){ | | | 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 | ** is required. */ sqlite3_blob *pBlob = p->pReader; p->pReader = 0; rc = sqlite3_blob_reopen(pBlob, iRowid); assert( p->pReader==0 ); p->pReader = pBlob; if( rc!=SQLITE_OK ){ fts5IndexCloseReader(p); } if( rc==SQLITE_ABORT ) rc = SQLITE_OK; } /* If the blob handle is not open at this point, open it and seek ** to the requested entry. */ if( p->pReader==0 && rc==SQLITE_OK ){ |
︙ | ︙ | |||
5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 | } static int fts5IndexReturn(Fts5Index *p){ int rc = p->rc; p->rc = SQLITE_OK; return rc; } typedef struct Fts5FlushCtx Fts5FlushCtx; struct Fts5FlushCtx { Fts5Index *pIdx; Fts5SegWriter writer; }; | > > > > > > > > | 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 | } static int fts5IndexReturn(Fts5Index *p){ int rc = p->rc; p->rc = SQLITE_OK; return rc; } /* ** Close the read-only blob handle, if it is open. */ void sqlite3Fts5IndexCloseReader(Fts5Index *p){ fts5IndexCloseReader(p); fts5IndexReturn(p); } typedef struct Fts5FlushCtx Fts5FlushCtx; struct Fts5FlushCtx { Fts5Index *pIdx; Fts5SegWriter writer; }; |
︙ | ︙ | |||
6726 6727 6728 6729 6730 6731 6732 | /* ** Commit data to disk. */ int sqlite3Fts5IndexSync(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); | | | < | | 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 | /* ** Commit data to disk. */ int sqlite3Fts5IndexSync(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); fts5IndexCloseReader(p); return fts5IndexReturn(p); } /* ** Discard any data stored in the in-memory hash tables. Do not write it ** to the database. Additionally, assume that the contents of the %_data ** table may have changed on disk. So any in-memory caches of %_data ** records must be invalidated. */ int sqlite3Fts5IndexRollback(Fts5Index *p){ fts5IndexCloseReader(p); fts5IndexDiscardData(p); fts5StructureInvalidate(p); return fts5IndexReturn(p); } /* ** The %_data table is completely empty when this function is called. This ** function populates it with the initial structure objects for each index, ** and the initial version of the "averages" record (a zero-byte blob). */ |
︙ | ︙ | |||
6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 | /* ** Ensure the segment-iterator passed as the only argument points to EOF. */ static void fts5SegIterSetEOF(Fts5SegIter *pSeg){ fts5DataRelease(pSeg->pLeaf); pSeg->pLeaf = 0; } /* ** This function appends iterator pAppend to Fts5TokenDataIter pIn and ** returns the result. */ static Fts5TokenDataIter *fts5AppendTokendataIter( Fts5Index *p, /* Index object (for error code) */ | > > > > > > > > > > | 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 | /* ** Ensure the segment-iterator passed as the only argument points to EOF. */ static void fts5SegIterSetEOF(Fts5SegIter *pSeg){ fts5DataRelease(pSeg->pLeaf); pSeg->pLeaf = 0; } static void fts5IterClose(Fts5IndexIter *pIndexIter){ if( pIndexIter ){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *pIndex = pIter->pIndex; fts5TokendataIterDelete(pIter->pTokenDataIter); fts5MultiIterFree(pIter); fts5IndexCloseReader(pIndex); } } /* ** This function appends iterator pAppend to Fts5TokenDataIter pIn and ** returns the result. */ static Fts5TokenDataIter *fts5AppendTokendataIter( Fts5Index *p, /* Index object (for error code) */ |
︙ | ︙ | |||
6969 6970 6971 6972 6973 6974 6975 | if( pIn==0 ) memset(pNew, 0, nByte); pRet = pNew; pNew->nIterAlloc = nAlloc; } } } if( p->rc ){ | | | 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 | if( pIn==0 ) memset(pNew, 0, nByte); pRet = pNew; pNew->nIterAlloc = nAlloc; } } } if( p->rc ){ fts5IterClose((Fts5IndexIter*)pAppend); }else{ pRet->apIter[pRet->nIter++] = pAppend; } assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc ); return pRet; } |
︙ | ︙ | |||
7182 7183 7184 7185 7186 7187 7188 | if( pSmall ){ fts5BufferSet(&p->rc, &bSeek, pSmall->n, pSmall->p); fts5BufferAppendBlob(&p->rc, &bSeek, 1, (const u8*)"\0"); }else{ fts5BufferSet(&p->rc, &bSeek, nToken, pToken); } if( p->rc ){ | | | 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 | if( pSmall ){ fts5BufferSet(&p->rc, &bSeek, pSmall->n, pSmall->p); fts5BufferAppendBlob(&p->rc, &bSeek, 1, (const u8*)"\0"); }else{ fts5BufferSet(&p->rc, &bSeek, nToken, pToken); } if( p->rc ){ fts5IterClose((Fts5IndexIter*)pNew); break; } pNewIter = &pNew->aSeg[0]; pPrevIter = (pPrev ? &pPrev->aSeg[0] : 0); for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){ |
︙ | ︙ | |||
7247 7248 7249 7250 7251 7252 7253 | } } /* If pSmall is still NULL at this point, then the new iterator does ** not point to any terms that match the query. So delete it and break ** out of the loop - all required iterators have been collected. */ if( pSmall==0 ){ | | | 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 | } } /* If pSmall is still NULL at this point, then the new iterator does ** not point to any terms that match the query. So delete it and break ** out of the loop - all required iterators have been collected. */ if( pSmall==0 ){ fts5IterClose((Fts5IndexIter*)pNew); break; } /* Append this iterator to the set and continue. */ pSet = fts5AppendTokendataIter(p, pSet, pNew); } |
︙ | ︙ | |||
7376 7377 7378 7379 7380 7381 7382 | Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); } } } if( p->rc ){ | | | | 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 | Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); } } } if( p->rc ){ fts5IterClose((Fts5IndexIter*)pRet); pRet = 0; fts5IndexCloseReader(p); } *ppIter = (Fts5IndexIter*)pRet; sqlite3Fts5BufferFree(&buf); } return fts5IndexReturn(p); } |
︙ | ︙ | |||
7628 7629 7630 7631 7632 7633 7634 | } /* ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery(). */ void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ if( pIndexIter ){ | < | < | | | 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 | } /* ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery(). */ void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ if( pIndexIter ){ Fts5Index *pIndex = ((Fts5Iter*)pIndexIter)->pIndex; fts5IterClose(pIndexIter); fts5IndexReturn(pIndex); } } /* ** Read and decode the "averages" record from the database. ** ** Parameter anSize must point to an array of size nCol, where nCol is |
︙ | ︙ | |||
8162 8163 8164 8165 8166 8167 8168 | cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n); } } if( rc==SQLITE_OK ){ rc = sqlite3Fts5IterNext(pIter); } } | | | 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 | cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n); } } if( rc==SQLITE_OK ){ rc = sqlite3Fts5IterNext(pIter); } } fts5IterClose(pIter); *pCksum = cksum; return rc; } /* ** Check if buffer z[], size n bytes, contains as series of valid utf-8 |
︙ | ︙ |
Changes to ext/fts5/test/fts5faultI.test.
︙ | ︙ | |||
285 286 287 288 289 290 291 292 293 294 | } -body { execsql { INSERT INTO f1(rowid, content) SELECT id, content FROM g1; } } -test { faultsim_test_result {0 {}} } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 | } -body { execsql { INSERT INTO f1(rowid, content) SELECT id, content FROM g1; } } -test { faultsim_test_result {0 {}} } #------------------------------------------------------------------------- reset_db ifcapable foreignkey { do_execsql_test 12.0 { CREATE VIRTUAL TABLE f1 USING fts5(content); CREATE TABLE p1(a INTEGER PRIMARY KEY); CREATE TABLE c1(b REFERENCES p1 DEFERRABLE INITIALLY DEFERRED); } faultsim_save_and_close do_faultsim_test 11 -faults oom* -prep { faultsim_restore_and_reopen execsql { PRAGMA foreign_keys = 1; BEGIN; INSERT INTO c1 VALUES(123); SAVEPOINT xyz; } } -body { execsql { INSERT INTO f1 VALUES('a b c'); ROLLBACK TO xyz; COMMIT; } } -test { execsql { SELECT 123 } faultsim_test_result \ {1 {FOREIGN KEY constraint failed}} \ {1 {out of memory}} \ {1 {constraint failed}} } } finish_test |
Changes to ext/fts5/test/fts5misc.test.
︙ | ︙ | |||
587 588 589 590 591 592 593 | UPDATE t1 SET y='TWO' WHERE ii=2; } do_execsql_test 21.2 { PRAGMA integrity_check } {ok} | < | 587 588 589 590 591 592 593 594 595 596 597 598 599 600 | UPDATE t1 SET y='TWO' WHERE ii=2; } do_execsql_test 21.2 { PRAGMA integrity_check } {ok} sqlite3_db_config db DEFENSIVE 1 do_execsql_test 21.3 { CREATE TABLE xyz_notashadow(x, y); DROP TABLE xyz_notashadow; } sqlite3_db_config db DEFENSIVE 0 |
︙ | ︙ | |||
660 661 662 663 664 665 666 667 668 669 | CREATE VIRTUAL TABLE t1 USING fts5(a, detail='none', content=''); INSERT INTO t1(a) VALUES('a b c'); } do_execsql_test 25.0 { SELECT fts5_test_poslist(t1) FROM t1('b') ORDER BY rank; } {{}} finish_test | > > > > > > > > > > > > > > > > > > > > > | 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 | CREATE VIRTUAL TABLE t1 USING fts5(a, detail='none', content=''); INSERT INTO t1(a) VALUES('a b c'); } do_execsql_test 25.0 { SELECT fts5_test_poslist(t1) FROM t1('b') ORDER BY rank; } {{}} #------------------------------------------------------------------------- reset_db do_execsql_test 26.0 { PRAGMA foreign_keys = ON; CREATE TABLE t1(x INTEGER PRIMARY KEY); CREATE TABLE t2(y INTEGER PRIMARY KEY, z INTEGER REFERENCES t1(x) DEFERRABLE INITIALLY DEFERRED ); CREATE VIRTUAL TABLE t3 USING fts5(a, b, content='', tokendata=1); } do_execsql_test 26.1 { BEGIN; INSERT INTO t2 VALUES(1,111); INSERT INTO t3 VALUES(3,3); PRAGMA defer_foreign_keys=ON; DELETE FROM t2 WHERE y+1; COMMIT; } finish_test |
Changes to ext/misc/sqlite3_stdio.c.
︙ | ︙ | |||
42 43 44 45 46 47 48 49 50 51 52 53 54 55 | ** in the CLI, or other context clues in other applications) for all ** other output channels. ** ** The default behavior, if neither of the above is defined is to ** use O_U8TEXT when writing to the Windows console (or anything ** else for which _isatty() returns true) and to use O_BINARY or O_TEXT ** for all other output channels. */ #if defined(SQLITE_U8TEXT_ONLY) # define UseWtextForOutput(fd) 1 # define UseWtextForInput(fd) 1 # define IsConsole(fd) _isatty(_fileno(fd)) #elif defined(SQLITE_U8TEXT_STDIO) # define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr) | > > > > > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | ** in the CLI, or other context clues in other applications) for all ** other output channels. ** ** The default behavior, if neither of the above is defined is to ** use O_U8TEXT when writing to the Windows console (or anything ** else for which _isatty() returns true) and to use O_BINARY or O_TEXT ** for all other output channels. ** ** The SQLITE_USE_W32_FOR_CONSOLE_IO macro is also available. If ** defined, it forces the use of Win32 APIs for all console I/O, both ** input and output. This is necessary for some non-Microsoft run-times ** that implement stdio differently from Microsoft/Visual-Studio. */ #if defined(SQLITE_U8TEXT_ONLY) # define UseWtextForOutput(fd) 1 # define UseWtextForInput(fd) 1 # define IsConsole(fd) _isatty(_fileno(fd)) #elif defined(SQLITE_U8TEXT_STDIO) # define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr) |
︙ | ︙ | |||
144 145 146 147 148 149 150 | /* When reading from the command-prompt in Windows, it is necessary ** to use _O_WTEXT input mode to read UTF-16 characters, then translate ** that into UTF-8. Otherwise, non-ASCII characters all get translated ** into '?'. */ wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) ); if( b1==0 ) return 0; | | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | /* When reading from the command-prompt in Windows, it is necessary ** to use _O_WTEXT input mode to read UTF-16 characters, then translate ** that into UTF-8. Otherwise, non-ASCII characters all get translated ** into '?'. */ wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) ); if( b1==0 ) return 0; #ifdef SQLITE_USE_W32_FOR_CONSOLE_IO DWORD nRead = 0; if( IsConsole(in) && ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz-1, &nRead, 0) ){ b1[nRead] = 0; }else #endif { _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT); if( fgetws(b1, sz/4, in)==0 ){ |
︙ | ︙ | |||
222 223 224 225 226 227 228 | */ int sz = (int)strlen(z); wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) ); if( b1==0 ) return 0; sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz); b1[sz] = 0; | | > | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | */ int sz = (int)strlen(z); wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) ); if( b1==0 ) return 0; sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz); b1[sz] = 0; #ifdef SQLITE_USE_W32_FOR_CONSOLE_IO DWORD nWr = 0; if( IsConsole(out) && WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),b1,sz,&nWr,0) ){ /* If writing to the console, then the WriteConsoleW() is all we ** need to do. */ }else #endif { /* As long as SQLITE_USE_W32_FOR_CONSOLE_IO is not defined, or for ** non-console I/O even if that macro is defined, write using the ** standard library. */ _setmode(_fileno(out), _O_U8TEXT); if( UseBinaryWText(out) ){ piecemealOutput(b1, sz, out); }else{ fputws(b1, out); } } |
︙ | ︙ |
Changes to ext/misc/vfstrace.c.
︙ | ︙ | |||
1029 1030 1031 1032 1033 1034 1035 | /* ** Close the dynamic library handle pHandle. */ static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; vfstraceOnOff(pInfo, VTR_DLCLOSE); | | | 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 | /* ** Close the dynamic library handle pHandle. */ static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; sqlite3_vfs *pRoot = pInfo->pRootVfs; vfstraceOnOff(pInfo, VTR_DLCLOSE); vfstrace_printf(pInfo, "%s.xDlClose()\n", pInfo->zVfsName); pRoot->xDlClose(pRoot, pHandle); } /* ** Populate the buffer pointed to by zBufOut with nByte bytes of ** random data. */ |
︙ | ︙ |
Changes to ext/session/session1.test.
︙ | ︙ | |||
281 282 283 284 285 286 287 | DELETE FROM t2 WHERE a = 4; } -conflicts { {DELETE t2 NOTFOUND {i 3 t three}} {DELETE t2 DATA {i 4 t four} {i 4 t five}} {FOREIGN_KEY 1} } do_execsql_test $tn.3.2.4 "SELECT * FROM t2" {} | | | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | DELETE FROM t2 WHERE a = 4; } -conflicts { {DELETE t2 NOTFOUND {i 3 t three}} {DELETE t2 DATA {i 4 t four} {i 4 t five}} {FOREIGN_KEY 1} } do_execsql_test $tn.3.2.4 "SELECT * FROM t2" {} do_db2_test $tn.3.2.5 "SELECT * FROM t2" {4 five} # Test UPDATE changesets. # do_execsql_test $tn.3.3.1 { CREATE TABLE t4(a, b, c, PRIMARY KEY(b, c))%WR%; INSERT INTO t4 VALUES(1, 2, 3); INSERT INTO t4 VALUES(4, 5, 6); |
︙ | ︙ |
Changes to ext/session/session9.test.
︙ | ︙ | |||
76 77 78 79 80 81 82 | 4 3 1 {FOREIGN_KEY 1} OMIT 5 2 0 {FOREIGN_KEY 1} ABORT 6 3 0 {FOREIGN_KEY 1} ABORT 7 2 1 {FOREIGN_KEY 1} ABORT 8 3 1 {FOREIGN_KEY 1} ABORT } { | | | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | 4 3 1 {FOREIGN_KEY 1} OMIT 5 2 0 {FOREIGN_KEY 1} ABORT 6 3 0 {FOREIGN_KEY 1} ABORT 7 2 1 {FOREIGN_KEY 1} ABORT 8 3 1 {FOREIGN_KEY 1} ABORT } { set A(OMIT,0) {0 {}} set A(OMIT,1) {0 {}} set A(ABORT,0) {1 SQLITE_CONSTRAINT} set A(ABORT,1) {1 SQLITE_CONSTRAINT} do_test 1.2.$tn.1 { populate_db execsql { DELETE FROM p1 WHERE a=($delrow+0) } if {$trans} { execsql BEGIN } set ::xConflict [list] list [catch {sqlite3changeset_apply db $::cc xConflict} msg] $msg } $A($conflictret,$trans) do_test 1.2.$tn.2 { set ::xConflict } $conflictargs set A(OMIT,0) {1 1} set A(OMIT,1) {1 1} set A(ABORT,0) {0 0} set A(ABORT,1) {0 0} do_test 1.2.$tn.3 { execsql { SELECT count(*) FROM c1 UNION ALL SELECT count(*) FROM c2 } } $A($conflictret,$trans) |
︙ | ︙ |
Changes to ext/session/sessionnoact.test.
︙ | ︙ | |||
55 56 57 58 59 60 61 | do_execsql_test 1.2 { PRAGMA foreign_keys = 1; } set ::nConflict 0 proc conflict {args} { incr ::nConflict | | | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | do_execsql_test 1.2 { PRAGMA foreign_keys = 1; } set ::nConflict 0 proc conflict {args} { incr ::nConflict return "ABORT" } sqlite3changeset_apply_v2 db $C conflict do_execsql_test 1.3 { SELECT * FROM c1 } { |
︙ | ︙ | |||
107 108 109 110 111 112 113 114 115 116 117 118 119 120 | PRAGMA foreign_key_check } #------------------------------------------------------------------------- # Check that a changeset that causes an FK violation may not be applied, # even if SQLITE_CHANGESETAPPLY_FKNOACTION is specified. # reset_db do_execsql_test 2.0 { CREATE TABLE p1(a INTEGER PRIMARY KEY, b, c UNIQUE); INSERT INTO p1 VALUES(1, 1, 'one'); INSERT INTO p1 VALUES(2, 2, 'two'); CREATE TABLE c1(x REFERENCES p1(c) ON DELETE CASCADE); | > > > | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | PRAGMA foreign_key_check } #------------------------------------------------------------------------- # Check that a changeset that causes an FK violation may not be applied, # even if SQLITE_CHANGESETAPPLY_FKNOACTION is specified. # # UPDATE: Unless the conflict-handler returns OMIT. In that case it can # be committed. See test cases 3.* in this file. # reset_db do_execsql_test 2.0 { CREATE TABLE p1(a INTEGER PRIMARY KEY, b, c UNIQUE); INSERT INTO p1 VALUES(1, 1, 'one'); INSERT INTO p1 VALUES(2, 2, 'two'); CREATE TABLE c1(x REFERENCES p1(c) ON DELETE CASCADE); |
︙ | ︙ | |||
159 160 161 162 163 164 165 166 167 168 | } {1 SQLITE_CONSTRAINT} do_execsql_test 2.7 { SELECT * FROM p1; } {1 1 one 2 2 two} do_execsql_test 2.8 { SELECT * FROM c1; } {two} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 162 163 164 165 166 167 168 169 170 171 172 173 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 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | } {1 SQLITE_CONSTRAINT} do_execsql_test 2.7 { SELECT * FROM p1; } {1 1 one 2 2 two} do_execsql_test 2.8 { SELECT * FROM c1; } {two} #------------------------------------------------------------------------- # reset_db do_execsql_test 3.0 { CREATE TABLE p1(a INTEGER PRIMARY KEY, b, c UNIQUE); INSERT INTO p1 VALUES(1, 1, 'one'); INSERT INTO p1 VALUES(2, 2, 'two'); CREATE TABLE c1(x REFERENCES p1(c) ON DELETE CASCADE); INSERT INTO c1 VALUES('two'); } set ::nConflict 0 proc conflict {args} { incr ::nConflict return "OMIT" } db_save set C [changeset_from_sql { DELETE FROM p1 WHERE a=2; }] db_restore_and_reopen do_test 3.1 { sqlite3changeset_apply_v2 -noaction db $C conflict } {} do_execsql_test 3.2 { SELECT * FROM p1 } {1 1 one} db_restore_and_reopen db eval { PRAGMA foreign_keys = 1 } do_test 3.3 { list [catch { sqlite3changeset_apply_v2 -noaction db $C conflict } msg] $msg } {0 {}} do_execsql_test 3.4 { SELECT * FROM p1; } {1 1 one} do_execsql_test 3.5 { SELECT * FROM c1; } {two} db_restore_and_reopen db eval { PRAGMA foreign_keys = 1 } do_test 3.6 { list [catch { sqlite3changeset_apply_v2 -ignorenoop -noaction db $C conflict } msg] $msg } {0 {}} do_execsql_test 3.7 { SELECT * FROM p1; } {1 1 one} do_execsql_test 3.8 { SELECT * FROM c1; } {two} finish_test |
Changes to ext/session/sqlite3session.c.
︙ | ︙ | |||
5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 | sIter.nCol = nFk; res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter); if( res!=SQLITE_CHANGESET_OMIT ){ rc = SQLITE_CONSTRAINT; } } } if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ if( rc==SQLITE_OK ){ rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); } if( rc!=SQLITE_OK ){ sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); | > > > > > | 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 | sIter.nCol = nFk; res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter); if( res!=SQLITE_CHANGESET_OMIT ){ rc = SQLITE_CONSTRAINT; } } } { int rc2 = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0); if( rc==SQLITE_OK ) rc = rc2; } if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ if( rc==SQLITE_OK ){ rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); } if( rc!=SQLITE_OK ){ sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); |
︙ | ︙ |
Changes to ext/wasm/api/extern-post-js.c-pp.js.
︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | most of the associated JS code, runs outside of the Emscripten-generated module init scope, in the current global scope. */ //#if target=es6-module const toExportForESM = //#endif (function(){ /** In order to hide the sqlite3InitModule()'s resulting Emscripten module from downstream clients (and simplify our documentation by being able to elide those details), we hide that function and expose a hand-written sqlite3InitModule() to return the sqlite3 object (most of the time). | > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | most of the associated JS code, runs outside of the Emscripten-generated module init scope, in the current global scope. */ //#if target=es6-module const toExportForESM = //#endif (function(){ //console.warn("this is extern-post-js"); /** In order to hide the sqlite3InitModule()'s resulting Emscripten module from downstream clients (and simplify our documentation by being able to elide those details), we hide that function and expose a hand-written sqlite3InitModule() to return the sqlite3 object (most of the time). |
︙ | ︙ | |||
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | li.pop(); initModuleState.sqlite3Dir = li.join('/') + '/'; } globalThis.sqlite3InitModule = function ff(...args){ //console.warn("Using replaced sqlite3InitModule()",globalThis.location); return originalInit(...args).then((EmscriptenModule)=>{ //#if wasmfs if('undefined'!==typeof WorkerGlobalScope && EmscriptenModule['ENVIRONMENT_IS_PTHREAD']){ /** Workaround for wasmfs-generated worker, which calls this routine from each individual thread and requires that its argument be returned. The conditional criteria above are fragile, based solely on inspection of the offending code, not public Emscripten details. */ //console.warn("sqlite3InitModule() returning E-module.",EmscriptenModule); return EmscriptenModule; } //#endif | > > > > > > > > > > > < | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | li.pop(); initModuleState.sqlite3Dir = li.join('/') + '/'; } globalThis.sqlite3InitModule = function ff(...args){ //console.warn("Using replaced sqlite3InitModule()",globalThis.location); return originalInit(...args).then((EmscriptenModule)=>{ //console.warn("originalInit() then() arg =",EmscriptenModule); //console.warn("initModuleState =",initModuleState); if( EmscriptenModule.postRun && EmscriptenModule.postRun.length ){ /* Emscripten 4.0.0 changes the order in which our Module.postRun handler runs. In 3.x postRun would have run by now, and our code relies heavily on that order, so we'll work around that difference here. https://github.com/emscripten-core/emscripten/issues/23420 */ //console.warn("Emscripten did not run postRun: running them now!"); EmscriptenModule.postRun.shift()(EmscriptenModule); } //#if wasmfs if('undefined'!==typeof WorkerGlobalScope && EmscriptenModule['ENVIRONMENT_IS_PTHREAD']){ /** Workaround for wasmfs-generated worker, which calls this routine from each individual thread and requires that its argument be returned. The conditional criteria above are fragile, based solely on inspection of the offending code, not public Emscripten details. */ //console.warn("sqlite3InitModule() returning E-module.",EmscriptenModule); return EmscriptenModule; } //#endif const s = EmscriptenModule.sqlite3; s.scriptInfo = initModuleState; //console.warn("sqlite3.scriptInfo =",s.scriptInfo); if(ff.__isUnderTest) s.__isUnderTest = true; const f = s.asyncPostInit; delete s.asyncPostInit; return f(); |
︙ | ︙ |
Changes to ext/wasm/api/post-js-footer.js.
1 2 3 4 | /* The current function scope was opened via post-js-header.js, which gets prepended to this at build-time. This file closes that scope. */ })/*postRun.push(...)*/; | > > | 1 2 3 4 5 6 | /* The current function scope was opened via post-js-header.js, which gets prepended to this at build-time. This file closes that scope. */ //console.warn("This is the end of the Module.postRun handler."); })/*postRun.push(...)*/; //console.warn("This is the end of the setup of the (pending) Module.postRun"); |
Changes to ext/wasm/api/post-js-header.js.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** post-js-header.js is to be prepended to other code to create post-js.js for use with Emscripten's --post-js flag. This code requires that it be running in that context. The Emscripten environment must have been set up already but it will not have loaded its WASM when the code in this file is run. The function it installs will be run after the WASM module is loaded, at which point the sqlite3 JS API bits will get set up. */ if(!Module.postRun) Module.postRun = []; Module.postRun.push(function(Module/*the Emscripten-style module object*/){ 'use strict'; /* This function will contain at least the following: - post-js-header.js (this file) - sqlite3-api-prologue.js => Bootstrapping bits to attach the rest to - common/whwasmutil.js => Replacements for much of Emscripten's glue - jaccwaby/jaccwabyt.js => Jaccwabyt (C/JS struct binding) - sqlite3-api-glue.js => glues previous parts together | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | /** post-js-header.js is to be prepended to other code to create post-js.js for use with Emscripten's --post-js flag. This code requires that it be running in that context. The Emscripten environment must have been set up already but it will not have loaded its WASM when the code in this file is run. The function it installs will be run after the WASM module is loaded, at which point the sqlite3 JS API bits will get set up. */ if(!Module.postRun) Module.postRun = []; Module.postRun.push(function(Module/*the Emscripten-style module object*/){ 'use strict'; //console.warn("This is the start of the Module.postRun handler."); /* This function will contain at least the following: - post-js-header.js (this file) - sqlite3-api-prologue.js => Bootstrapping bits to attach the rest to - common/whwasmutil.js => Replacements for much of Emscripten's glue - jaccwaby/jaccwabyt.js => Jaccwabyt (C/JS struct binding) - sqlite3-api-glue.js => glues previous parts together |
︙ | ︙ |
Changes to ext/wasm/api/sqlite3-api-cleanup.js.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | *********************************************************************** This file is the tail end of the sqlite3-api.js constellation, intended to be appended after all other sqlite3-api-*.js files so that it can finalize any setup and clean up any global symbols temporarily used for setting up the API's various subsystems. */ 'use strict'; if('undefined' !== typeof Module){ // presumably an Emscripten build /** Install a suitable default configuration for sqlite3ApiBootstrap(). */ const SABC = Object.assign( | > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | *********************************************************************** This file is the tail end of the sqlite3-api.js constellation, intended to be appended after all other sqlite3-api-*.js files so that it can finalize any setup and clean up any global symbols temporarily used for setting up the API's various subsystems. In Emscripten builds it's run in the context of a Module.postRun handler. */ 'use strict'; if('undefined' !== typeof Module){ // presumably an Emscripten build /** Install a suitable default configuration for sqlite3ApiBootstrap(). */ const SABC = Object.assign( |
︙ | ︙ |
Changes to ext/wasm/api/sqlite3-api-glue.c-pp.js.
︙ | ︙ | |||
228 229 230 231 232 233 234 | }), '*' ]], ["sqlite3_set_auxdata", undefined, [ "sqlite3_context*", "int", "*", new wasm.xWrap.FuncPtrAdapter({ name: 'xDestroyAuxData', | | | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | }), '*' ]], ["sqlite3_set_auxdata", undefined, [ "sqlite3_context*", "int", "*", new wasm.xWrap.FuncPtrAdapter({ name: 'xDestroyAuxData', signature: 'v(p)', contextKey: (argv, argIndex)=>argv[0/* sqlite3_context* */] }) ]], ["sqlite3_shutdown", undefined], ["sqlite3_sourceid", "string"], ["sqlite3_sql", "string", "sqlite3_stmt*"], ["sqlite3_status", "int", "int", "*", "*", "int"], |
︙ | ︙ |
Changes to ext/wasm/dist.make.
︙ | ︙ | |||
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | # target will lead to grief in parallel builds (-j #). Thus # dist's deps must be trimmed to non-generated files or # files which are _not_ cleaned up by the clean target. # # Note that we require $(bin.version-info) in order to figure out the # dist file's name, so cannot (without a recursive make) have the # target name equal to the archive name. dist: \ $(bin.stripccomments) $(bin.version-info) \ $(dist.build) $(STRIP_K1.js) $(STRIP_K2.js) \ $(dist.jswasm.extras) $(dist.common.extras) \ $(MAKEFILE) $(MAKEFILE.dist) @echo "Making end-user deliverables..." @rm -fr $(dist-dir.top) @mkdir -p $(dist-dir.jswasm) $(dist-dir.common) @cp -p $(dist.top.extras) $(dist-dir.top) @cp -p README-dist.txt $(dist-dir.top)/README.txt @cp -p index-dist.html $(dist-dir.top)/index.html @cp -p $(dist.jswasm.extras) $(dist-dir.jswasm) | > > > > > > > > > > | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | # target will lead to grief in parallel builds (-j #). Thus # dist's deps must be trimmed to non-generated files or # files which are _not_ cleaned up by the clean target. # # Note that we require $(bin.version-info) in order to figure out the # dist file's name, so cannot (without a recursive make) have the # target name equal to the archive name. # # 2025-01-15: Emsdk 4.0.0 introduces, in its generated code, a regex # which contains the pattern /*. That, of course, confuses any C-style # comment-stripper which is not specifically JS-aware and smart enough # to know that it's in a regex or string literal. Because of that, # comment-stripping is currently disabled, which means the builds will # be significantly larger than before. #apply_comment_stripper := false apply_comment_stripper := true # ^^^ shell command true or false dist: \ $(bin.stripccomments) $(bin.version-info) \ $(dist.build) $(STRIP_K1.js) $(STRIP_K2.js) \ $(dist.jswasm.extras) $(dist.common.extras) \ $(MAKEFILE) $(MAKEFILE.dist) @echo "Making end-user deliverables..." @rm -fr $(dist-dir.top) @mkdir -p $(dist-dir.jswasm) $(dist-dir.common) @cp -p $(dist.top.extras) $(dist-dir.top) @cp -p README-dist.txt $(dist-dir.top)/README.txt @cp -p index-dist.html $(dist-dir.top)/index.html @cp -p $(dist.jswasm.extras) $(dist-dir.jswasm) @if $(apply_comment_stripper); then $(foreach JS,$(STRIP_K1.js),$(call DIST_STRIP_COMMENTS,$(JS),-k)) fi @if $(apply_comment_stripper); then $(foreach JS,$(STRIP_K2.js),$(call DIST_STRIP_COMMENTS,$(JS),-k -k)) fi @cp -p $(dist.common.extras) $(dist-dir.common) @set -e; \ vnum=$$($(bin.version-info) --download-version); \ vdir=$(dist-name-prefix)-$$vnum; \ arczip=$$vdir.zip; \ echo "Making $$arczip ..."; \ rm -fr $$arczip $$vdir; \ |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
1062 1063 1064 1065 1066 1067 1068 | # mksourceid$(B.exe): $(MAKE_SANITY_CHECK) $(TOP)/tool/mksourceid.c $(B.cc) -o $@ $(TOP)/tool/mksourceid.c sqlite3.h: $(MAKE_SANITY_CHECK) $(TOP)/src/sqlite.h.in \ $(TOP)/manifest mksourceid$(B.exe) \ $(TOP)/VERSION $(B.tclsh) | | | | 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 | # mksourceid$(B.exe): $(MAKE_SANITY_CHECK) $(TOP)/tool/mksourceid.c $(B.cc) -o $@ $(TOP)/tool/mksourceid.c sqlite3.h: $(MAKE_SANITY_CHECK) $(TOP)/src/sqlite.h.in \ $(TOP)/manifest mksourceid$(B.exe) \ $(TOP)/VERSION $(B.tclsh) $(B.tclsh) $(TOP)/tool/mksqlite3h.tcl $(TOP) -o sqlite3.h sqlite3.c: .target_source sqlite3.h $(TOP)/tool/mksqlite3c.tcl src-verify$(B.exe) \ $(B.tclsh) $(B.tclsh) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_GEN_FLAGS) $(EXTRA_SRC) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . sqlite3r.h: sqlite3.h $(B.tclsh) $(B.tclsh) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover -o sqlite3r.h sqlite3r.c: sqlite3.c sqlite3r.h $(B.tclsh) cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ cp $(TOP)/ext/recover/dbdata.c tsrc/ $(B.tclsh) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_GEN_FLAGS) $(EXTRA_SRC) |
︙ | ︙ | |||
2013 2014 2015 2016 2017 2018 2019 | sqlite3d$(T.exe): shell.c $(LIBOBJS0) $(T.link) -o $@ \ shell.c $(LIBOBJS0) \ $(CFLAGS.readline) $(SHELL_OPT) \ $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) install-shell-0: sqlite3$(T.exe) $(install-dir.bin) | | | | 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 | sqlite3d$(T.exe): shell.c $(LIBOBJS0) $(T.link) -o $@ \ shell.c $(LIBOBJS0) \ $(CFLAGS.readline) $(SHELL_OPT) \ $(LDFLAGS.libsqlite3) $(LDFLAGS.readline) install-shell-0: sqlite3$(T.exe) $(install-dir.bin) $(INSTALL) sqlite3$(T.exe) "$(install-dir.bin)" install-shell-1: install: install-shell-$(HAVE_WASI_SDK) # How to build sqldiff$(T.exe) depends on $(LINK_TOOLS_DYNAMICALLY) # sqldiff.0.deps = $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o sqlite3.h sqldiff.0.rules = $(T.link) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS.libsqlite3) sqldiff.1.deps = $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h $(libsqlite3.SO) sqldiff.1.rules = $(T.link) -o $@ $(TOP)/tool/sqldiff.c -L. -lsqlite3 $(LDFLAGS.configure) sqldiff$(T.exe): $(sqldiff.$(LINK_TOOLS_DYNAMICALLY).deps) $(sqldiff.$(LINK_TOOLS_DYNAMICALLY).rules) install-diff: sqldiff$(T.exe) $(install-dir.bin) $(INSTALL) sqldiff$(T.exe) "$(install-dir.bin)" #install: install-diff dbhash$(T.exe): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h $(T.link) -o $@ $(TOP)/tool/dbhash.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: dbhash$(T.exe) RSYNC_SRC = \ |
︙ | ︙ | |||
2206 2207 2208 2209 2210 2211 2212 | $(TOP)/ext/recover/dbdata.c \ $(TOP)/ext/recover/sqlite3recover.c \ $(TOP)/ext/recover/sqlite3recover.h \ $(TOP)/src/test_windirent.c \ $(TOP)/src/test_windirent.h shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(B.tclsh) | | | 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 | $(TOP)/ext/recover/dbdata.c \ $(TOP)/ext/recover/sqlite3recover.c \ $(TOP)/ext/recover/sqlite3recover.h \ $(TOP)/src/test_windirent.c \ $(TOP)/src/test_windirent.h shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(B.tclsh) $(B.tclsh) $(TOP)/tool/mkshellc.tcl shell.c # # Rules to build the extension objects. # DEPS_EXT_COMMON = $(DEPS_OBJ_COMMON) $(EXTHDR) icu.o: $(TOP)/ext/icu/icu.c $(DEPS_EXT_COMMON) $(T.cc.extension) -c $(TOP)/ext/icu/icu.c $(CFLAGS.icu) |
︙ | ︙ |
Changes to src/date.c.
︙ | ︙ | |||
218 219 220 221 222 223 224 225 226 227 228 229 230 231 | zDate++; while( sqlite3Isdigit(*zDate) ){ ms = ms*10.0 + *zDate - '0'; rScale *= 10.0; zDate++; } ms /= rScale; } }else{ s = 0; } p->validJD = 0; p->rawS = 0; p->validHMS = 1; | > > > | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | zDate++; while( sqlite3Isdigit(*zDate) ){ ms = ms*10.0 + *zDate - '0'; rScale *= 10.0; zDate++; } ms /= rScale; /* Truncate to avoid problems with sub-milliseconds ** rounding. https://sqlite.org/forum/forumpost/766a2c9231 */ if( ms>0.999 ) ms = 0.999; } }else{ s = 0; } p->validJD = 0; p->rawS = 0; p->validHMS = 1; |
︙ | ︙ | |||
1425 1426 1427 1428 1429 1430 1431 | case 'd': /* Fall thru */ case 'e': { sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D); break; } case 'f': { /* Fractional seconds. (Non-standard) */ double s = x.s; | | | 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 | case 'd': /* Fall thru */ case 'e': { sqlite3_str_appendf(&sRes, cf=='d' ? "%02d" : "%2d", x.D); break; } case 'f': { /* Fractional seconds. (Non-standard) */ double s = x.s; if( NEVER(s>59.999) ) s = 59.999; sqlite3_str_appendf(&sRes, "%06.3f", s); break; } case 'F': { sqlite3_str_appendf(&sRes, "%04d-%02d-%02d", x.Y, x.M, x.D); break; } |
︙ | ︙ |
Changes to src/dbpage.c.
︙ | ︙ | |||
420 421 422 423 424 425 426 427 428 429 430 431 432 433 | }else{ pTab->pgnoTrunc = 0; } sqlite3PagerUnref(pDbPage); return rc; update_fail: sqlite3_free(pVtab->zErrMsg); pVtab->zErrMsg = sqlite3_mprintf("%s", zErr); return SQLITE_ERROR; } static int dbpageBegin(sqlite3_vtab *pVtab){ DbpageTable *pTab = (DbpageTable *)pVtab; | > | 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 | }else{ pTab->pgnoTrunc = 0; } sqlite3PagerUnref(pDbPage); return rc; update_fail: pTab->pgnoTrunc = 0; sqlite3_free(pVtab->zErrMsg); pVtab->zErrMsg = sqlite3_mprintf("%s", zErr); return SQLITE_ERROR; } static int dbpageBegin(sqlite3_vtab *pVtab){ DbpageTable *pTab = (DbpageTable *)pVtab; |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 | pOp = sqlite3VdbeGetOp(v, 1); pEnd = sqlite3VdbeGetLastOp(v); for(; pOp<pEnd; pOp++){ if( pOp->p4type!=P4_SUBRTNSIG ) continue; assert( pOp->opcode==OP_BeginSubrtn ); pSig = pOp->p4.pSubrtnSig; assert( pSig!=0 ); if( pNewSig->selId!=pSig->selId ) continue; if( strcmp(pNewSig->zAff,pSig->zAff)!=0 ) continue; pExpr->y.sub.iAddr = pSig->iAddr; pExpr->y.sub.regReturn = pSig->regReturn; pExpr->iTable = pSig->iTable; ExprSetProperty(pExpr, EP_Subrtn); return 1; | > | 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 | pOp = sqlite3VdbeGetOp(v, 1); pEnd = sqlite3VdbeGetLastOp(v); for(; pOp<pEnd; pOp++){ if( pOp->p4type!=P4_SUBRTNSIG ) continue; assert( pOp->opcode==OP_BeginSubrtn ); pSig = pOp->p4.pSubrtnSig; assert( pSig!=0 ); if( !pSig->bComplete ) continue; if( pNewSig->selId!=pSig->selId ) continue; if( strcmp(pNewSig->zAff,pSig->zAff)!=0 ) continue; pExpr->y.sub.iAddr = pSig->iAddr; pExpr->y.sub.regReturn = pSig->regReturn; pExpr->iTable = pSig->iTable; ExprSetProperty(pExpr, EP_Subrtn); return 1; |
︙ | ︙ | |||
3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 | ){ int addrOnce = 0; /* Address of the OP_Once instruction at top */ int addr; /* Address of OP_OpenEphemeral instruction */ Expr *pLeft; /* the LHS of the IN operator */ KeyInfo *pKeyInfo = 0; /* Key information */ int nVal; /* Size of vector pLeft */ Vdbe *v; /* The prepared statement under construction */ v = pParse->pVdbe; assert( v!=0 ); /* The evaluation of the IN must be repeated every time it ** is encountered if any of the following is true: ** ** * The right-hand side is a correlated subquery ** * The right-hand side is an expression list containing variables ** * We are inside a trigger ** ** If all of the above are false, then we can compute the RHS just once ** and reuse it many names. */ if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ /* Reuse of the RHS is allowed ** ** Compute a signature for the RHS of the IN operator to facility ** finding and reusing prior instances of the same IN operator. */ | > < | 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 | ){ int addrOnce = 0; /* Address of the OP_Once instruction at top */ int addr; /* Address of OP_OpenEphemeral instruction */ Expr *pLeft; /* the LHS of the IN operator */ KeyInfo *pKeyInfo = 0; /* Key information */ int nVal; /* Size of vector pLeft */ Vdbe *v; /* The prepared statement under construction */ SubrtnSig *pSig = 0; /* Signature for this subroutine */ v = pParse->pVdbe; assert( v!=0 ); /* The evaluation of the IN must be repeated every time it ** is encountered if any of the following is true: ** ** * The right-hand side is a correlated subquery ** * The right-hand side is an expression list containing variables ** * We are inside a trigger ** ** If all of the above are false, then we can compute the RHS just once ** and reuse it many names. */ if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ /* Reuse of the RHS is allowed ** ** Compute a signature for the RHS of the IN operator to facility ** finding and reusing prior instances of the same IN operator. */ assert( !ExprUseXSelect(pExpr) || pExpr->x.pSelect!=0 ); if( ExprUseXSelect(pExpr) && (pExpr->x.pSelect->selFlags & SF_All)==0 ){ pSig = sqlite3DbMallocRawNN(pParse->db, sizeof(pSig[0])); if( pSig ){ pSig->selId = pExpr->x.pSelect->selId; pSig->zAff = exprINAffinity(pParse, pExpr); } |
︙ | ︙ | |||
3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 | assert( !ExprUseYWin(pExpr) ); ExprSetProperty(pExpr, EP_Subrtn); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; if( pSig ){ pSig->iAddr = pExpr->y.sub.iAddr; pSig->regReturn = pExpr->y.sub.regReturn; pSig->iTable = iTab; pParse->mSubrtnSig = 1 << (pSig->selId&7); sqlite3VdbeChangeP4(v, -1, (const char*)pSig, P4_SUBRTNSIG); } addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); | > | 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 | assert( !ExprUseYWin(pExpr) ); ExprSetProperty(pExpr, EP_Subrtn); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pExpr->y.sub.regReturn) + 1; if( pSig ){ pSig->bComplete = 0; pSig->iAddr = pExpr->y.sub.iAddr; pSig->regReturn = pExpr->y.sub.regReturn; pSig->iTable = iTab; pParse->mSubrtnSig = 1 << (pSig->selId&7); sqlite3VdbeChangeP4(v, -1, (const char*)pSig, P4_SUBRTNSIG); } addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); |
︙ | ︙ | |||
3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 | sqlite3ExprCode(pParse, pE2, r1); sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1); } sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r2); } if( pKeyInfo ){ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); } if( addrOnce ){ sqlite3VdbeAddOp1(v, OP_NullRow, iTab); sqlite3VdbeJumpHere(v, addrOnce); /* Subroutine return */ | > | 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 | sqlite3ExprCode(pParse, pE2, r1); sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1); } sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r2); } if( pSig ) pSig->bComplete = 1; if( pKeyInfo ){ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); } if( addrOnce ){ sqlite3VdbeAddOp1(v, OP_NullRow, iTab); sqlite3VdbeJumpHere(v, addrOnce); /* Subroutine return */ |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
1660 1661 1662 1663 1664 1665 1666 | int rc; unixInodeInfo *pInode = pFile->pInode; assert( pInode!=0 ); assert( sqlite3_mutex_held(pInode->pLockMutex) ); if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){ if( pInode->bProcessLock==0 ){ struct flock lock; | | | 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 | int rc; unixInodeInfo *pInode = pFile->pInode; assert( pInode!=0 ); assert( sqlite3_mutex_held(pInode->pLockMutex) ); if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){ if( pInode->bProcessLock==0 ){ struct flock lock; /* assert( pInode->nLock==0 ); <-- Not true if unix-excl READONLY used */ lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; lock.l_type = F_WRLCK; rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile); if( rc<0 ) return rc; pInode->bProcessLock = 1; |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
804 805 806 807 808 809 810 | assert( pPager->fd!=0 ); if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */ if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */ #ifndef SQLITE_OMIT_WAL if( pPager->pWal ){ u32 iRead = 0; (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); | | | 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 | assert( pPager->fd!=0 ); if( pPager->fd->pMethods==0 ) return 0; /* Case (1) */ if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */ #ifndef SQLITE_OMIT_WAL if( pPager->pWal ){ u32 iRead = 0; (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); if( iRead ) return 0; /* Case (4) */ } #endif assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 ); if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd) & SQLITE_IOCAP_SUBPAGE_READ)==0 ){ return 0; /* Case (2) */ } |
︙ | ︙ |
Changes to src/vdbe.h.
︙ | ︙ | |||
36 37 38 39 40 41 42 43 44 45 46 47 48 49 | /* ** A signature for a reusable subroutine that materializes the RHS of ** an IN operator. */ struct SubrtnSig { int selId; /* SELECT-id for the SELECT statement on the RHS */ char *zAff; /* Affinity of the overall IN expression */ int iTable; /* Ephemeral table generated by the subroutine */ int iAddr; /* Subroutine entry address */ int regReturn; /* Register used to hold return address */ }; /* | > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /* ** A signature for a reusable subroutine that materializes the RHS of ** an IN operator. */ struct SubrtnSig { int selId; /* SELECT-id for the SELECT statement on the RHS */ u8 bComplete; /* True if fully coded and available for reusable */ char *zAff; /* Affinity of the overall IN expression */ int iTable; /* Ephemeral table generated by the subroutine */ int iAddr; /* Subroutine entry address */ int regReturn; /* Register used to hold return address */ }; /* |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
59 60 61 62 63 64 65 | ** 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; sqlite3_int64 iElapse; assert( p->startTime>0 ); | < | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | ** 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; sqlite3_int64 iElapse; assert( p->startTime>0 ); assert( db->init.busy==0 ); assert( p->zSql!=0 ); sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); iElapse = (iNow - p->startTime)*1000000; #ifndef SQLITE_OMIT_DEPRECATED if( db->xProfile ){ db->xProfile(db->pProfileArg, p->zSql, iElapse); |
︙ | ︙ | |||
779 780 781 782 783 784 785 | ** from interrupting a statement that has not yet started. */ if( db->nVdbeActive==0 ){ AtomicStore(&db->u1.isInterrupted, 0); } assert( db->nVdbeWrite>0 || db->autoCommit==0 | | | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 | ** from interrupting a statement that has not yet started. */ if( db->nVdbeActive==0 ){ AtomicStore(&db->u1.isInterrupted, 0); } assert( db->nVdbeWrite>0 || db->autoCommit==0 || ((db->nDeferredCons + db->nDeferredImmCons)==0) ); #ifndef SQLITE_OMIT_TRACE if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 && !db->init.busy && p->zSql ){ sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); }else{ |
︙ | ︙ |
Changes to src/whereexpr.c.
︙ | ︙ | |||
215 216 217 218 219 220 221 | sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); }else if( op==TK_STRING ){ assert( !ExprHasProperty(pRight, EP_IntValue) ); z = (u8*)pRight->u.zToken; } if( z ){ | | | | | | | | > > | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); }else if( op==TK_STRING ){ assert( !ExprHasProperty(pRight, EP_IntValue) ); z = (u8*)pRight->u.zToken; } if( z ){ /* Count the number of prefix bytes prior to the first wildcard, ** U+fffd character, or malformed utf-8. If the underlying database ** has a UTF16LE encoding, then only consider ASCII characters. Note that ** the encoding of z[] is UTF8 - we are dealing with only UTF8 here in this ** code, but the database engine itself might be processing content using a ** different encoding. */ cnt = 0; while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; if( c==wc[3] && z[cnt]>0 && z[cnt]<0x80 ){ cnt++; }else if( c>=0x80 ){ const u8 *z2 = z+cnt-1; if( sqlite3Utf8Read(&z2)==0xfffd || c==0xFF /* bad utf-8 */ || ENC(db)==SQLITE_UTF16LE ){ cnt--; break; }else{ cnt = (int)(z2-z); } } } |
︙ | ︙ | |||
1380 1381 1382 1383 1384 1385 1386 | for(i=0; (c = pStr1->u.zToken[i])!=0; i++){ pStr1->u.zToken[i] = sqlite3Toupper(c); pStr2->u.zToken[i] = sqlite3Tolower(c); } } if( !db->mallocFailed ){ | | < | | > > > | > > > > | 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 | for(i=0; (c = pStr1->u.zToken[i])!=0; i++){ pStr1->u.zToken[i] = sqlite3Toupper(c); pStr2->u.zToken[i] = sqlite3Tolower(c); } } if( !db->mallocFailed ){ u8 *pC; /* Last character before the first wildcard */ pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1]; if( noCase ){ /* The point is to increment the last character before the first ** wildcard. But if we increment '@', that will push it into the ** alphabetic range where case conversions will mess up the ** inequality. To avoid this, make sure to also run the full ** LIKE on all candidate expressions by clearing the isComplete flag */ if( *pC=='A'-1 ) isComplete = 0; *pC = sqlite3UpperToLower[*pC]; } /* Increment the value of the last utf8 character in the prefix. */ while( *pC==0xBF && pC>(u8*)pStr2->u.zToken ){ *pC = 0x80; pC--; } assert( *pC!=0xFF ); /* isLikeOrGlob() guarantees this */ (*pC)++; } zCollSeqName = noCase ? "NOCASE" : sqlite3StrBINARY; pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), pStr1); transferJoinMarkings(pNewExpr1, pExpr); |
︙ | ︙ |
Changes to test/date.test.
︙ | ︙ | |||
647 648 649 650 651 652 653 654 655 | datetest 19.48 {date('2024-02-29','-0110-00-00','floor')} {1914-02-28} datetest 19.49 {date('2024-02-29','-0110-00-00','ceiling')} {1914-03-01} datetest 19.50 {date('2000-08-31','+0023-06-00','floor')} {2024-02-29} datetest 19.51 {date('2000-08-31','+0022-06-00','floor')} {2023-02-28} datetest 19.52 {date('2000-08-31','+0023-06-00','ceiling')} {2024-03-02} datetest 19.53 {date('2000-08-31','+0022-06-00','ceiling')} {2023-03-03} finish_test | > > > > > > > > | 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 | datetest 19.48 {date('2024-02-29','-0110-00-00','floor')} {1914-02-28} datetest 19.49 {date('2024-02-29','-0110-00-00','ceiling')} {1914-03-01} datetest 19.50 {date('2000-08-31','+0023-06-00','floor')} {2024-02-29} datetest 19.51 {date('2000-08-31','+0022-06-00','floor')} {2023-02-28} datetest 19.52 {date('2000-08-31','+0023-06-00','ceiling')} {2024-03-02} datetest 19.53 {date('2000-08-31','+0022-06-00','ceiling')} {2023-03-03} # 2025-01-21 # https://sqlite.org/forum/forumpost/766a2c9231 # datetest 20.1 {datetime('2024-12-31 23:59:59.9990')} {2024-12-31 23:59:59} datetest 20.2 {datetime('2024-12-31 23:59:59.9999999999999')} \ {2024-12-31 23:59:59} datetest 20.3 {datetime('2024-12-31 23:59:59.9995')} {2024-12-31 23:59:59} datetest 20.4 {datetime('2024-12-31 23:59:58.9995')} {2024-12-31 23:59:58} finish_test |
Changes to test/fkey6.test.
︙ | ︙ | |||
246 247 248 249 250 251 252 | DELETE FROM p1 WHERE a=2; } do_catchsql_test 4.2 { COMMIT; } {1 {FOREIGN KEY constraint failed}} | > | > > > > > > > > > > > > > > | 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 | DELETE FROM p1 WHERE a=2; } do_catchsql_test 4.2 { COMMIT; } {1 {FOREIGN KEY constraint failed}} #------------------------------------------------------------------------- # reset_db do_execsql_test 5.0 { PRAGMA foreign_keys = 1; CREATE TABLE p1(a INTEGER PRIMARY KEY, b); CREATE TABLE c1(x REFERENCES p1 DEFERRABLE INITIALLY DEFERRED); } do_execsql_test 5.1 { BEGIN; INSERT INTO c1 VALUES(123); PRAGMA defer_foreign_keys = 1; INSERT INTO p1 VALUES(123, 'one two three'); COMMIT; } finish_test |
Changes to test/in7.test.
︙ | ︙ | |||
214 215 216 217 218 219 220 221 222 | } {1 1} do_execsql_test 3.7 { SELECT t1.a, t2.b FROM t1, t2 WHERE (t1.a, t2.b) = (1, 2); } {1 2} do_execsql_test 3.8 { SELECT t1.a, t2.b FROM t1, t2 WHERE (t1.a, t2.b) IN ((1, 2)); } {1 2} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | } {1 1} do_execsql_test 3.7 { SELECT t1.a, t2.b FROM t1, t2 WHERE (t1.a, t2.b) = (1, 2); } {1 2} do_execsql_test 3.8 { SELECT t1.a, t2.b FROM t1, t2 WHERE (t1.a, t2.b) IN ((1, 2)); } {1 2} # 2025-01-30 Inifinite loop in byte-code discovered by dbsqlfuzz # having to do with SubrtnSig logic. The code was using a Subroutine # from within itself resulting in infinite recursion. # # This test will spin forever if the bug has not been fixed, or if # it reappears. # reset_db do_execsql_test 4.0 { CREATE TABLE t1(a INTEGER PRIMARY KEY, b); INSERT INTO t1 VALUES(1,x'1111'); CREATE TABLE t2(c); CREATE TABLE t3(d); CREATE TRIGGER t1tr UPDATE ON t1 BEGIN UPDATE t1 SET b=x'2222' FROM t2; UPDATE t1 SET b = (SELECT a IN (SELECT a FROM t1 WHERE (b,a) IN (SELECT rowid, d FROM t3 ) ) FROM t1 NATURAL RIGHT JOIN t1 ); END; UPDATE t1 SET b=x'3333'; SELECT quote(b) FROM t1; } {X'3333'} finish_test |
Changes to test/like3.test.
︙ | ︙ | |||
270 271 272 273 274 275 276 277 278 | do_eqp_test like3-6.240 { SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '\'; } { QUERY PLAN `--SEARCH t2 USING INDEX t2path2 (path>? AND path<?) } } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | do_eqp_test like3-6.240 { SELECT * FROM t2 WHERE path LIKE 'a%' ESCAPE '\'; } { QUERY PLAN `--SEARCH t2 USING INDEX t2path2 (path>? AND path<?) } } #------------------------------------------------------------------------- ifcapable utf16 { reset_db do_execsql_test like3-7.0 { PRAGMA encoding = 'UTF-16be'; CREATE TABLE Example(word TEXT NOT NULL); CREATE INDEX Example_word on Example(word); INSERT INTO Example VALUES(char(0x307F)); } do_execsql_test like3-7.1 { SELECT char(0x307F)=='み'; } {1} do_execsql_test like3-7.1 { SELECT * FROM Example WHERE word GLOB 'み*' } {み} do_execsql_test like3-7.2 { SELECT * FROM Example WHERE word >= char(0x307F) AND word < char(0x3080); } {み} } #------------------------------------------------------------------------- reset_db foreach enc { UTF-8 UTF-16le UTF-16be } { foreach {tn expr} { 1 "CAST (X'FF' AS TEXT)" 2 "CAST (X'FFBF' AS TEXT)" 3 "CAST (X'FFBFBF' AS TEXT)" 4 "CAST (X'FFBFBFBF' AS TEXT)" 5 "'abc' || CAST (X'FF' AS TEXT)" 6 "'def' || CAST (X'FFBF' AS TEXT)" 7 "'ghi' || CAST (X'FFBFBF' AS TEXT)" 8 "'jkl' || CAST (X'FFBFBFBF' AS TEXT)" } { reset_db execsql "PRAGMA encoding = '$enc'" do_execsql_test like3-8.$tn.0 { CREATE TABLE t1(x); } do_execsql_test like3-8.$tn.1 { PRAGMA encoding } $enc do_execsql_test like3-8.$tn.1 " INSERT INTO t1 VALUES( $expr ) " do_execsql_test like3-8.$tn.2 { SELECT typeof(x) FROM t1 } {text} set x [db one {SELECT x || '%' FROM t1}] do_execsql_test like3-8.$tn.3 { SELECT rowid FROM t1 WHERE x LIKE $x } 1 do_execsql_test like3-8.$tn.4 { CREATE INDEX i1 ON t1(x); } do_execsql_test like3-8.$tn.5 { SELECT rowid FROM t1 WHERE x LIKE $x } 1 } } finish_test |
Changes to test/trace3.test.
︙ | ︙ | |||
338 339 340 341 342 343 344 345 346 | HAVING (1.0 - ((distance / 100.0) / CAST( length('A') - 1 AS REAL ))) >= 'F' } do_test 12.1.2 { sqlite3_finalize $STMT } {SQLITE_OK} finish_test | > > > > > > > > > > > > > > > > | 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 | HAVING (1.0 - ((distance / 100.0) / CAST( length('A') - 1 AS REAL ))) >= 'F' } do_test 12.1.2 { sqlite3_finalize $STMT } {SQLITE_OK} #------------------------------------------------------------------------- reset_db do_execsql_test 13.0 { CREATE TABLE T1(a, b); INSERT INTO t1 VALUES(1, 2), (3, 4); } proc trace_callback {args} {} db trace_v2 trace_callback profile do_test 13.1 { db eval { SELECT * FROM t1 } { db trace_v2 "" "" } set {} {} } {} finish_test |
Changes to tool/emcc.sh.in.
︙ | ︙ | |||
59 60 61 62 63 64 65 | emcc=`which emcc 2>/dev/null` if [ x = "x${emcc}" ]; then echo "emcc not found in PATH. Normally that's set up by ${EMSDK_ENV_SH}." 1>&2 exit 4 fi fi | | | 59 60 61 62 63 64 65 66 | emcc=`which emcc 2>/dev/null` if [ x = "x${emcc}" ]; then echo "emcc not found in PATH. Normally that's set up by ${EMSDK_ENV_SH}." 1>&2 exit 4 fi fi exec $emcc "$@" |
Changes to tool/mkshellc.tcl.
︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # This script should be tool/mkshellc.tcl. If the directory holding # the script is $DIR, then the component parts are located in $DIR/../src # and $DIR/../ext/misc. # set topdir [file dir [file dir [file normal $argv0]]] set out stdout fconfigure stdout -translation binary puts $out {/* DO NOT EDIT! ** This file is automatically generated by the script in the canonical ** SQLite source tree at tool/mkshellc.tcl. That script combines source ** code from various constituent source files of SQLite into this single ** "shell.c" file used to implement the SQLite command-line shell. ** ** Most of the code found below comes from the "src/shell.c.in" file in | > > > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # This script should be tool/mkshellc.tcl. If the directory holding # the script is $DIR, then the component parts are located in $DIR/../src # and $DIR/../ext/misc. # set topdir [file dir [file dir [file normal $argv0]]] set out stdout fconfigure stdout -translation binary if {[lindex $argv 0]!=""} { set out [open [lindex $argv 0] wb] } puts $out {/* DO NOT EDIT! ** This file is automatically generated by the script in the canonical ** SQLite source tree at tool/mkshellc.tcl. That script combines source ** code from various constituent source files of SQLite into this single ** "shell.c" file used to implement the SQLite command-line shell. ** ** Most of the code found below comes from the "src/shell.c.in" file in |
︙ | ︙ |
Changes to tool/mksqlite3c-noext.tcl.
︙ | ︙ | |||
53 54 55 56 57 58 59 | close $in # Open the output file and write a header comment at the beginning # of the file. # set out [open sqlite3.c w] # Force the output to use unix line endings, even on Windows. | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | close $in # Open the output file and write a header comment at the beginning # of the file. # set out [open sqlite3.c w] # Force the output to use unix line endings, even on Windows. fconfigure $out -translation binary set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1] puts $out [subst \ {/****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version $VERSION. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be |
︙ | ︙ |
Changes to tool/mksqlite3c.tcl.
︙ | ︙ | |||
84 85 86 87 88 89 90 | # Open the output file and write a header comment at the beginning # of the file. # set fname sqlite3.c if {$enable_recover} { set fname sqlite3r.c } set out [open $fname wb] # Force the output to use unix line endings, even on Windows. | | | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | # Open the output file and write a header comment at the beginning # of the file. # set fname sqlite3.c if {$enable_recover} { set fname sqlite3r.c } set out [open $fname wb] # Force the output to use unix line endings, even on Windows. fconfigure $out -translation binary set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1] puts $out [subst \ {/****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version $VERSION. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be |
︙ | ︙ | |||
126 127 128 129 130 131 132 | puts $out "** The content in this amalgamation comes from Fossil check-in" puts -nonewline $out "** [string range [lindex $res 0] 0 35]" if {[llength $res]==1} { puts $out "." } else { puts $out " with changes in files:\n**" foreach f [lrange $res 1 end] { | | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | puts $out "** The content in this amalgamation comes from Fossil check-in" puts -nonewline $out "** [string range [lindex $res 0] 0 35]" if {[llength $res]==1} { puts $out "." } else { puts $out " with changes in files:\n**" foreach f [lrange $res 1 end] { puts $out "** [string trim $f]" } } } else { puts $out "** The origin of the sources used to build this amalgamation" puts $out "** is unknown." } puts $out [subst {*/ |
︙ | ︙ |
Changes to tool/mksqlite3h.tcl.
︙ | ︙ | |||
20 21 22 23 24 25 26 | # 4) Replaces the string --VERSION-NUMBER-- with current library version, # formatted as an integer (e.g. "3006017"). # 5) Replaces the string --SOURCE-ID-- with the date and time and sha1 # hash of the fossil-scm manifest for the source tree. # 6) Adds the SQLITE_CALLBACK calling convention macro in front of all # callback declarations. # | | | > > > | > > > > > > > > > > > > > > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | # 4) Replaces the string --VERSION-NUMBER-- with current library version, # formatted as an integer (e.g. "3006017"). # 5) Replaces the string --SOURCE-ID-- with the date and time and sha1 # hash of the fossil-scm manifest for the source tree. # 6) Adds the SQLITE_CALLBACK calling convention macro in front of all # callback declarations. # # This script outputs to stdout unless the -o FILENAME option is used. # # Example usage: # # tclsh mksqlite3h.tcl ../sqlite [OPTIONS] # ^^^^^^^^^ # Root of source tree # # Where options are: # # --enable-recover Include the sqlite3recover extension # -o FILENAME Write results to FILENAME instead of stdout # --useapicall SQLITE_APICALL instead of SQLITE_CDECL # # Default output stream set out stdout # Get the source tree root directory from the command-line # set TOP [lindex $argv 0] # If the -o FILENAME option is present, use FILENAME for output. # set x [lsearch $argv -o] if {$x>0} { incr x set out [open [lindex $argv $x] wb] } # Enable use of SQLITE_APICALL macros at the right points? # set useapicall 0 # Include sqlite3recover.h? # set enable_recover 0 # Process command-line arguments if {[lsearch -regexp [lrange $argv 1 end] {^-+useapicall}] != -1} { set useapicall 1 } if {[lsearch -regexp [lrange $argv 1 end] {^-+enable-recover}] != -1} { set enable_recover 1 } |
︙ | ︙ | |||
84 85 86 87 88 89 90 | set declpattern4 \ {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3changegroup_[_a-zA-Z0-9]+)(\(.*)$} set declpattern5 \ {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3rebaser_[_a-zA-Z0-9]+)(\(.*)$} # Force the output to use unix line endings, even on Windows. | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | set declpattern4 \ {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3changegroup_[_a-zA-Z0-9]+)(\(.*)$} set declpattern5 \ {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3rebaser_[_a-zA-Z0-9]+)(\(.*)$} # Force the output to use unix line endings, even on Windows. fconfigure stdout -translation binary set filelist [subst { $TOP/src/sqlite.h.in $TOP/ext/rtree/sqlite3rtree.h $TOP/ext/session/sqlite3session.h $TOP/ext/fts5/fts5.h }] |
︙ | ︙ | |||
114 115 116 117 118 119 120 | } # Process the source files. # foreach file $filelist { set in [open $file rb] if {![regexp {sqlite\.h\.in} $file]} { | | | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | } # Process the source files. # foreach file $filelist { set in [open $file rb] if {![regexp {sqlite\.h\.in} $file]} { puts $out "/******** Begin file [file tail $file] *********/" } while {![eof $in]} { set line [string trimright [gets $in]] # File sqlite3rtree.h contains a line "#include <sqlite3.h>". Omit this # line when copying sqlite3rtree.h into sqlite3.h. |
︙ | ︙ | |||
157 158 159 160 161 162 163 | } } if {$useapicall} { set line [string map [list (*sqlite3_syscall_ptr) \ "(SQLITE_SYSAPI *sqlite3_syscall_ptr)"] $line] regsub {\(\*} $line {(SQLITE_CALLBACK *} line } | | | | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | } } if {$useapicall} { set line [string map [list (*sqlite3_syscall_ptr) \ "(SQLITE_SYSAPI *sqlite3_syscall_ptr)"] $line] regsub {\(\*} $line {(SQLITE_CALLBACK *} line } puts $out $line } close $in if {![regexp {sqlite\.h\.in} $file]} { puts $out "/******** End of [file tail $file] *********/" } } puts $out "#endif /* SQLITE3_H */" |
Changes to tool/split-sqlite3c.tcl.
︙ | ︙ | |||
11 12 13 14 15 16 17 | set MAX 32768 ;# Maximum number of lines per file. set BEGIN {^/\*+ Begin file ([a-zA-Z0-9_.]+) \*+/} set END {^/\*+ End of %s \*+/} set in [open sqlite3.c] set out1 [open sqlite3-all.c w] | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | set MAX 32768 ;# Maximum number of lines per file. set BEGIN {^/\*+ Begin file ([a-zA-Z0-9_.]+) \*+/} set END {^/\*+ End of %s \*+/} set in [open sqlite3.c] set out1 [open sqlite3-all.c w] fconfigure $out1 -translation binary # Copy the header from sqlite3.c into sqlite3-all.c # while {[gets $in line]} { if {[regexp $BEGIN $line]} break puts $out1 $line } |
︙ | ︙ |
Changes to tool/stripccomments.c.
︙ | ︙ | |||
107 108 109 110 111 112 113 | App.rc = 1; return; } break; } else if(slash == ch){ /* MARKER(("state 0 ==> 1 @ %d:%d\n", line, col)); */ | > > > > > > > > > > > > > > > > | > | 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | App.rc = 1; return; } break; } else if(slash == ch){ /* MARKER(("state 0 ==> 1 @ %d:%d\n", line, col)); */ if( '\\'==prev ){ /** JS regexes may contain slash-asterisks, as happened at: https://github.com/emscripten-core/emscripten/issues/23412 Such regexes will always necessarily be preceeded by a backslash, though. It is hypothetically possible for a legitimate comment slash-asterisk to appear immediately before a backslash, but that seems like an even rarer corner case than the JS regex case. */ fputc(ch, out); }else{ state = S_SLASH1; } break; } fputc(ch, out); break; case S_SLASH1: /* 1 slash */ /* MARKER(("SLASH1 @ %d:%d App.keepFirst=%d\n", line, col, App.keepFirst)); */ |
︙ | ︙ |