Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Bring the merge-info-html branch up to date with trunk, step 1 of 2. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | merge-info-html |
| Files: | files | file ages | folders |
| SHA3-256: |
1140b020de296a7724c5d444f1bb73d9 |
| User & Date: | stephan 2025-02-20 14:32:47.005 |
Context
|
2025-02-20
| ||
| 14:46 | Bring the merge-info-html branch up to date with trunk, step 2 of 2. ... (check-in: c2b1c2c9fa user: stephan tags: merge-info-html) | |
| 14:32 | Bring the merge-info-html branch up to date with trunk, step 1 of 2. ... (check-in: 1140b020de user: stephan tags: merge-info-html) | |
|
2025-02-19
| ||
| 17:10 | Add the --debug option to "fossil merge-info --tk". Document that and the --script option. ... (check-in: 97aee327ef user: drh tags: trunk) | |
|
2024-12-10
| ||
| 06:25 | Merge trunk into merge-info-html branch for mergestat improvements. ... (check-in: f0a48c8faa user: stephan tags: merge-info-html) | |
Changes
Changes to Dockerfile.
1 2 3 4 5 6 7 | # syntax=docker/dockerfile:1.3 # See www/containers.md for documentation on how to use this file. ## --------------------------------------------------------------------- ## STAGE 1: Build static Fossil binary ## --------------------------------------------------------------------- | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# syntax=docker/dockerfile:1.3
# See www/containers.md for documentation on how to use this file.
## ---------------------------------------------------------------------
## STAGE 1: Build static Fossil binary
## ---------------------------------------------------------------------
### We don't pin a more stable version of our base layer because we want
### to build with the latest tools and libraries available in case they
### fixed something that matters to us since the last build. Everything
### below depends on this layer, and so, alas, we toss this container's
### cache on Alpine's release schedule, roughly once a month.
FROM alpine:latest AS bld
WORKDIR /fsl
### Bake the build-time userland into a base layer so it only changes
### when the upstream image is updated or we change the package set.
RUN set -x \
&& apk update \
&& apk upgrade --no-cache \
&& apk add --no-cache \
gcc make \
linux-headers musl-dev \
openssl-dev openssl-libs-static \
zlib-dev zlib-static
### Build Fossil as a separate layer so we don't have to rebuild the
### userland for each iteration of Fossil's dev cycle.
###
### We must cope with a bizarre ADD misfeature here: it unpacks tarballs
### automatically when you give it a local file name but not if you give
### it a /tarball URL! It matters because we default to a URL in case
### you're building outside a Fossil checkout, but when building via the
### container-image target, we avoid a costly hit on fossil-scm.org by
### leveraging its DVCS nature via the "tarball" command and passing the
### resulting file's name in.
ARG FSLCFG=""
ARG FSLVER="trunk"
ARG FSLURL="https://fossil-scm.org/home/tarball/src?r=${FSLVER}"
ENV FSLSTB=/fsl/src.tar.gz
ADD $FSLURL $FSLSTB
RUN set -x \
&& if [ -d $FSLSTB ] ; \
|
| ︙ | ︙ |
Changes to Makefile.classic.
| ︙ | ︙ | |||
93 94 95 96 97 98 99 | # You should not need to change anything below this line ############################################################################### # # Automatic platform-specific options. HOST_OS_CMD = uname -s HOST_OS = $(HOST_OS_CMD:sh) | | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | # You should not need to change anything below this line ############################################################################### # # Automatic platform-specific options. HOST_OS_CMD = uname -s HOST_OS = $(HOST_OS_CMD:sh) LIB.SunOS= -lsocket -lnsl -lrt LIB += $(LIB.$(HOST_OS)) TCC.DragonFly += -DUSE_PREAD TCC.FreeBSD += -DUSE_PREAD TCC.NetBSD += -DUSE_PREAD TCC.OpenBSD += -DUSE_PREAD TCC += $(TCC.$(HOST_OS)) |
| ︙ | ︙ |
Changes to auto.def.
| ︙ | ︙ | |||
42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# This is useful for people wanting Fossil to use an external SQLite library
# to compare the one they have against the minimum required
if {[opt-bool print-minimum-sqlite-version]} {
puts [get-define MINIMUM_SQLITE_VERSION]
exit 0
}
set outOfTreeBuild 0
if {![file exists fossil.1]} {
puts "This appears to be an out-of-tree build."
set outOfTreeBuild 1
}
| > > > > > > > > > > > > > > | 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 |
# This is useful for people wanting Fossil to use an external SQLite library
# to compare the one they have against the minimum required
if {[opt-bool print-minimum-sqlite-version]} {
puts [get-define MINIMUM_SQLITE_VERSION]
exit 0
}
# Space characters have never been allowed in either the source
# tree nor the build directory. But the resulting error messages
# could be confusing. The following checks make the reason for the
# failure clear.
#
if {[string first " " $autosetup(srcdir)] != -1} {
user-error "The pathname of the source tree\
may not contain space characters"
}
if {[string first " " $autosetup(builddir)] != -1} {
user-error "The pathname of the build directory\
may not contain space characters"
}
set outOfTreeBuild 0
if {![file exists fossil.1]} {
puts "This appears to be an out-of-tree build."
set outOfTreeBuild 1
}
|
| ︙ | ︙ | |||
80 81 82 83 84 85 86 |
# Ironically, this means we may right now be running under either jimsh0
# or a version of tclsh that we find unsuitable below!
cc-check-progs tclsh
set hbtd /usr/local/Cellar/tcl-tk
if {[string equal false [get-define TCLSH]]} {
msg-result "WARNING: 'make test' will not run here."
} else {
| | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# Ironically, this means we may right now be running under either jimsh0
# or a version of tclsh that we find unsuitable below!
cc-check-progs tclsh
set hbtd /usr/local/Cellar/tcl-tk
if {[string equal false [get-define TCLSH]]} {
msg-result "WARNING: 'make test' will not run here."
} else {
set v [exec sh -c "echo 'puts \$tcl_version' | tclsh"]
if {[expr {$v >= 8.6}]} {
msg-result "Found Tclsh version $v in the PATH."
define TCLSH tclsh
} elseif {[file isdirectory $hbtd]} {
# This is a macOS system with the Homebrew version of Tcl/Tk
# installed. Select the newest version. It won't normally be
# in the PATH to avoid shadowing /usr/bin/tclsh, and even if it
|
| ︙ | ︙ | |||
102 103 104 105 106 107 108 |
msg-result "Using Homebrew Tcl/Tk version $path."
} else {
msg-result "WARNING: tclsh $v found; need >= 8.6 for 'make test'."
define TCLSH false ;# force "make test" failure via /usr/bin/false
}
}
| | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
msg-result "Using Homebrew Tcl/Tk version $path."
} else {
msg-result "WARNING: tclsh $v found; need >= 8.6 for 'make test'."
define TCLSH false ;# force "make test" failure via /usr/bin/false
}
}
define CFLAGS [get-env CFLAGS "-g -Os"]
define EXTRA_CFLAGS "-Wall"
define EXTRA_LDFLAGS ""
define USE_SYSTEM_SQLITE 0
define USE_LINENOISE 0
define USE_MMAN_H 0
define USE_SEE 0
define SQLITE3_ORIGIN 0
|
| ︙ | ︙ | |||
228 229 230 231 232 233 234 |
file delete ./conftest__
}
test_system_sqlite
}
proc is_mingw {} {
| > | > > | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
file delete ./conftest__
}
test_system_sqlite
}
proc is_mingw {} {
return [expr {
[string match *mingw* [get-define host]] &&
![file exists "/dev/null"]
}]
}
if {[is_mingw]} {
define-append EXTRA_CFLAGS -DBROKEN_MINGW_CMDLINE
define-append LIBS -lkernel32 -lws2_32
} else {
#
|
| ︙ | ︙ | |||
420 421 422 423 424 425 426 |
if {$ssldirs ne "none"} {
set found 0
if {$ssldirs eq "tree"} {
set ssldir [file dirname $autosetup(dir)]/compat/openssl
if {![file isdirectory $ssldir]} {
user-error "The OpenSSL in source tree directory does not exist"
}
| | | | | > > > > > > > > > | 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
if {$ssldirs ne "none"} {
set found 0
if {$ssldirs eq "tree"} {
set ssldir [file dirname $autosetup(dir)]/compat/openssl
if {![file isdirectory $ssldir]} {
user-error "The OpenSSL in source tree directory does not exist"
}
set msg "openssl in $ssldir"
set cflags "-I$ssldir/include"
set ldflags "-L$ssldir"
set ssllibs "$ssldir/libssl.a $ssldir/libcrypto.a -lpthread"
set found [check-for-openssl "openssl in source tree" "$cflags $ldflags" $ssllibs]
} else {
if {$ssldirs in {auto ""}} {
catch {
set cflags [exec pkg-config openssl --cflags-only-I]
set ldflags [exec pkg-config openssl --libs-only-L]
set found [check-for-openssl "ssl via pkg-config" "$cflags $ldflags"]
} msg
if {!$found} {
set ssldirs "{} /usr/sfw /usr/local/ssl /usr/lib/ssl /usr/ssl \
/usr/pkg /usr/local /usr /usr/local/opt/openssl \
/opt/homebrew/opt/openssl"
}
}
if {!$found} {
foreach dir $ssldirs {
if {$dir eq ""} {
set msg "system openssl"
set cflags ""
set ldflags ""
} else {
set msg "openssl in $dir"
set cflags "-I$dir/include"
set ldflags "-L$dir/lib"
}
if {[check-for-openssl $msg "$cflags $ldflags"]} {
incr found
break
}
if {$dir ne ""} {
set ldflags ""
set msg "static build of openssl in $dir"
set ssllibs "$dir/libssl.a $dir/libcrypto.a -lpthread"
if {[check-for-openssl $msg "$cflags $ldflags" $ssllibs]} {
incr found
break
}
}
}
}
}
if {$found} {
define FOSSIL_ENABLE_SSL
define-append EXTRA_CFLAGS $cflags
|
| ︙ | ︙ | |||
681 682 683 684 685 686 687 |
#
set tclconfig(TCL_LD_FLAGS) [string map [list -ldl ""] \
$tclconfig(TCL_LD_FLAGS)]
define-append EXTRA_LDFLAGS $tclconfig(TCL_LD_FLAGS)
define FOSSIL_ENABLE_TCL
}
| < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > | 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 |
#
set tclconfig(TCL_LD_FLAGS) [string map [list -ldl ""] \
$tclconfig(TCL_LD_FLAGS)]
define-append EXTRA_LDFLAGS $tclconfig(TCL_LD_FLAGS)
define FOSSIL_ENABLE_TCL
}
# Network functions require libraries on some systems
cc-check-function-in-lib gethostbyname nsl
if {![cc-check-function-in-lib socket {socket network}]} {
# Last resort, may be Windows
if {[is_mingw]} {
define-append LIBS -lwsock32
}
}
# Some systems (ex: SunOS) require -lrt in order to use nanosleep
cc-check-function-in-lib nanosleep rt
# The SMTP module requires special libraries and headers for MX DNS
# record lookups and such.
cc-check-includes arpa/nameser.h
cc-include-needs bind/resolv.h netinet/in.h
cc-check-includes bind/resolv.h
cc-check-includes resolv.h
|
| ︙ | ︙ | |||
742 743 744 745 746 747 748 | cc-check-functions utime cc-check-functions usleep cc-check-functions strchrnul cc-check-functions pledge cc-check-functions backtrace # Termux on Android adds "getpass(char *)" to unistd.h, so check this so we | | | 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 |
cc-check-functions utime
cc-check-functions usleep
cc-check-functions strchrnul
cc-check-functions pledge
cc-check-functions backtrace
# Termux on Android adds "getpass(char *)" to unistd.h, so check this so we
# guard against including it again; use cctest as cc-check-functions and
# cctest_function check for "getpass()" with no args and fail
if {[cctest -link 1 -includes {unistd.h} -code "getpass(0);"]} {
define FOSSIL_HAVE_GETPASS 1
msg-result "Found getpass() with unistd.h"
}
# Check for getloadavg(), and if it doesn't exist, define FOSSIL_OMIT_LOAD_AVERAGE
|
| ︙ | ︙ | |||
834 835 836 837 838 839 840 |
}
if {[opt-bool static]} {
# Linux can only infer the dependency on pthread from OpenSSL when
# doing dynamic linkage.
define-append LIBS -lpthread
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 |
}
if {[opt-bool static]} {
# Linux can only infer the dependency on pthread from OpenSSL when
# doing dynamic linkage.
define-append LIBS -lpthread
}
########################################################################
# @proj-check-emsdk
#
# Emscripten is used for doing in-tree builds of web-based WASM stuff,
# as opposed to WASI-based WASM or WASM binaries we import from other
# places. This is only set up for Unix-style OSes and is untested
# anywhere but Linux. Requires that the --with-emsdk flag be
# registered with autosetup.
#
# It looks for the SDK in the location specified by --with-emsdk.
# Values of "" or "auto" mean to check for the environment var EMSDK
# (which gets set by the emsdk_env.sh script from the SDK) or that
# same var passed to configure.
#
# If the given directory is found, it expects to find emsdk_env.sh in
# that directory, as well as the emcc compiler somewhere under there.
#
# If the --with-emsdk flag is explicitly provided and the SDK is not
# found then a fatal error is generated, otherwise failure to find the
# SDK is not fatal.
#
# Defines the following:
#
# - EMSDK_HOME = top dir of the emsdk or "".
# - EMSDK_ENV_SH = path to EMSDK_HOME/emsdk_env.sh or ""
# - BIN_EMCC = $EMSDK_HOME/upstream/emscripten/emcc or ""
# - HAVE_EMSDK = 0 or 1 (this function's return value)
#
# Returns 1 if EMSDK_ENV_SH is found, else 0. If EMSDK_HOME is not empty
# but BIN_EMCC is then emcc was not found in the EMSDK_HOME, in which
# case we have to rely on the fact that sourcing $EMSDK_ENV_SH from a
# shell will add emcc to the $PATH.
proc proj-check-emsdk {} {
set emsdkHome [opt-val with-emsdk]
define EMSDK_HOME ""
define EMSDK_ENV_SH ""
define BIN_EMCC ""
set hadValue [llength $emsdkHome]
msg-checking "Emscripten SDK? "
if {$emsdkHome in {"" "auto"}} {
# Check the environment. $EMSDK gets set by sourcing emsdk_env.sh.
set emsdkHome [get-env EMSDK ""]
}
set rc 0
if {$emsdkHome ne ""} {
define EMSDK_HOME $emsdkHome
set emsdkEnv "$emsdkHome/emsdk_env.sh"
if {[file exists $emsdkEnv]} {
msg-result "$emsdkHome"
define EMSDK_ENV_SH $emsdkEnv
set rc 1
set emcc "$emsdkHome/upstream/emscripten/emcc"
if {[file exists $emcc]} {
define BIN_EMCC $emcc
}
} else {
msg-result "emsdk_env.sh not found in $emsdkHome"
}
} else {
msg-result "not found"
}
if {$hadValue && 0 == $rc} {
# Fail if it was explicitly requested but not found
proj-fatal "Cannot find the Emscripten SDK"
}
define HAVE_EMSDK $rc
return $rc
}
if {[proj-check-emsdk]} {
define EMCC_WRAPPER $::autosetup(dir)/../tools/emcc.sh
define EMCC_OPT [get-env EMCC_OPT "-Oz"]; # optional flags to pass to emcc
make-template tools/emcc.sh.in
catch {exec chmod u+x tools/emcc.sh}
} else {
define EMCC_WRAPPER ""
define EMCC_OPT ""
catch {exec rm -f tools/emcc.sh}
}
# Tag container builds with a prefix of the checkin ID of the version
# of Fossil each one contains. This not only allows multiple images
# to coexist and multiple containers to be created unamgiguosly from
# them, it also changes the URL we fetch the source tarball from, so
|
| ︙ | ︙ |
Changes to extsrc/shell.c.
| ︙ | ︙ | |||
353 354 355 356 357 358 359 360 361 362 363 364 365 366 | ** in the CLI, or other context clues in other applications) for all ** other output channels. ** ** The default behavior, if neither of the above is defined is to ** use O_U8TEXT when writing to the Windows console (or anything ** else for which _isatty() returns true) and to use O_BINARY or O_TEXT ** for all other output channels. */ #if defined(SQLITE_U8TEXT_ONLY) # define UseWtextForOutput(fd) 1 # define UseWtextForInput(fd) 1 # define IsConsole(fd) _isatty(_fileno(fd)) #elif defined(SQLITE_U8TEXT_STDIO) # define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr) | > > > > > | 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 | ** in the CLI, or other context clues in other applications) for all ** other output channels. ** ** The default behavior, if neither of the above is defined is to ** use O_U8TEXT when writing to the Windows console (or anything ** else for which _isatty() returns true) and to use O_BINARY or O_TEXT ** for all other output channels. ** ** The SQLITE_USE_W32_FOR_CONSOLE_IO macro is also available. If ** defined, it forces the use of Win32 APIs for all console I/O, both ** input and output. This is necessary for some non-Microsoft run-times ** that implement stdio differently from Microsoft/Visual-Studio. */ #if defined(SQLITE_U8TEXT_ONLY) # define UseWtextForOutput(fd) 1 # define UseWtextForInput(fd) 1 # define IsConsole(fd) _isatty(_fileno(fd)) #elif defined(SQLITE_U8TEXT_STDIO) # define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr) |
| ︙ | ︙ | |||
455 456 457 458 459 460 461 |
/* When reading from the command-prompt in Windows, it is necessary
** to use _O_WTEXT input mode to read UTF-16 characters, then translate
** that into UTF-8. Otherwise, non-ASCII characters all get translated
** into '?'.
*/
wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) );
if( b1==0 ) return 0;
| | | | 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 |
/* When reading from the command-prompt in Windows, it is necessary
** to use _O_WTEXT input mode to read UTF-16 characters, then translate
** that into UTF-8. Otherwise, non-ASCII characters all get translated
** into '?'.
*/
wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) );
if( b1==0 ) return 0;
#ifdef SQLITE_USE_W32_FOR_CONSOLE_IO
DWORD nRead = 0;
if( IsConsole(in)
&& ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz-1, &nRead, 0)
){
b1[nRead] = 0;
}else
#endif
{
_setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
if( fgetws(b1, sz/4, in)==0 ){
|
| ︙ | ︙ | |||
533 534 535 536 537 538 539 |
*/
int sz = (int)strlen(z);
wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) );
if( b1==0 ) return 0;
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
b1[sz] = 0;
| | > | | | 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 |
*/
int sz = (int)strlen(z);
wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) );
if( b1==0 ) return 0;
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
b1[sz] = 0;
#ifdef SQLITE_USE_W32_FOR_CONSOLE_IO
DWORD nWr = 0;
if( IsConsole(out)
&& WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),b1,sz,&nWr,0)
){
/* If writing to the console, then the WriteConsoleW() is all we
** need to do. */
}else
#endif
{
/* As long as SQLITE_USE_W32_FOR_CONSOLE_IO is not defined, or for
** non-console I/O even if that macro is defined, write using the
** standard library. */
_setmode(_fileno(out), _O_U8TEXT);
if( UseBinaryWText(out) ){
piecemealOutput(b1, sz, out);
}else{
fputws(b1, out);
}
}
|
| ︙ | ︙ | |||
5287 5288 5289 5290 5291 5292 5293 |
for( nac=0; nac<4; ++nac ){
char c = (nac<nti)? *pIn++ : b64Numerals[0];
u8 bdp = BX_DV_PROTO(c);
switch( bdp ){
case ND:
/* Treat dark non-digits as pad, but they terminate decode too. */
ncIn = 0;
| | | | > > > | 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 |
for( nac=0; nac<4; ++nac ){
char c = (nac<nti)? *pIn++ : b64Numerals[0];
u8 bdp = BX_DV_PROTO(c);
switch( bdp ){
case ND:
/* Treat dark non-digits as pad, but they terminate decode too. */
ncIn = 0;
deliberate_fall_through; /* FALLTHRU */
case WS:
/* Treat whitespace as pad and terminate this group.*/
nti = nac;
deliberate_fall_through; /* FALLTHRU */
case PC:
bdp = 0;
--nbo;
deliberate_fall_through; /* FALLTHRU */
default: /* bdp is the digit value. */
qv = qv<<6 | bdp;
break;
}
}
switch( nbo ){
case 3:
pOut[2] = (qv) & 0xff;
deliberate_fall_through; /* FALLTHRU */
case 2:
pOut[1] = (qv>>8) & 0xff;
deliberate_fall_through; /* FALLTHRU */
case 1:
pOut[0] = (qv>>16) & 0xff;
break;
}
pOut += nbo;
}
return pOut;
}
/* This function does the work for the SQLite base64(x) UDF. */
|
| ︙ | ︙ | |||
5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 |
qv = 85 * qv + (c - cdo);
--nti;
}
nbo -= nti; /* Adjust for early (non-digit) end of group. */
switch( nbo ){
case 4:
*pOut++ = (qv >> 24)&0xff;
case 3:
*pOut++ = (qv >> 16)&0xff;
case 2:
*pOut++ = (qv >> 8)&0xff;
case 1:
*pOut++ = qv&0xff;
case 0:
break;
}
}
return pOut;
}
| > > > > | 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 |
qv = 85 * qv + (c - cdo);
--nti;
}
nbo -= nti; /* Adjust for early (non-digit) end of group. */
switch( nbo ){
case 4:
*pOut++ = (qv >> 24)&0xff;
/* FALLTHRU */
case 3:
*pOut++ = (qv >> 16)&0xff;
/* FALLTHRU */
case 2:
*pOut++ = (qv >> 8)&0xff;
/* FALLTHRU */
case 1:
*pOut++ = qv&0xff;
/* FALLTHRU */
case 0:
break;
}
}
return pOut;
}
|
| ︙ | ︙ | |||
7690 7691 7692 7693 7694 7695 7696 | return 0; } /* Free and reclaim all the memory used by a previously compiled ** regular expression. Applications should invoke this routine once ** for every call to re_compile() to avoid memory leaks. */ | | > | 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 |
return 0;
}
/* Free and reclaim all the memory used by a previously compiled
** regular expression. Applications should invoke this routine once
** for every call to re_compile() to avoid memory leaks.
*/
static void re_free(void *p){
ReCompiled *pRe = (ReCompiled*)p;
if( pRe ){
sqlite3_free(pRe->aOp);
sqlite3_free(pRe->aArg);
sqlite3_free(pRe);
}
}
|
| ︙ | ︙ | |||
8356 8357 8358 8359 8360 8361 8362 |
LONGLONG intervals;
HANDLE hFile;
LPWSTR zUnicodeName;
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
GetSystemTime(¤tTime);
SystemTimeToFileTime(¤tTime, &lastAccess);
| | | 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 |
LONGLONG intervals;
HANDLE hFile;
LPWSTR zUnicodeName;
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
GetSystemTime(¤tTime);
SystemTimeToFileTime(¤tTime, &lastAccess);
intervals = (mtime*10000000) + 116444736000000000;
lastWrite.dwLowDateTime = (DWORD)intervals;
lastWrite.dwHighDateTime = intervals >> 32;
zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
if( zUnicodeName==0 ){
return 1;
}
hFile = CreateFileW(
|
| ︙ | ︙ | |||
16342 16343 16344 16345 16346 16347 16348 16349 16350 16351 16352 16353 16354 16355 | #define VTR_DLERR 0x00200000 #define VTR_DLSYM 0x00400000 #define VTR_DLCLOSE 0x00800000 #define VTR_RAND 0x01000000 #define VTR_SLEEP 0x02000000 #define VTR_CURTIME 0x04000000 #define VTR_LASTERR 0x08000000 /* ** Method declarations for vfstrace_file. */ static int vfstraceClose(sqlite3_file*); static int vfstraceRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); static int vfstraceWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64); | > | 16356 16357 16358 16359 16360 16361 16362 16363 16364 16365 16366 16367 16368 16369 16370 | #define VTR_DLERR 0x00200000 #define VTR_DLSYM 0x00400000 #define VTR_DLCLOSE 0x00800000 #define VTR_RAND 0x01000000 #define VTR_SLEEP 0x02000000 #define VTR_CURTIME 0x04000000 #define VTR_LASTERR 0x08000000 #define VTR_FETCH 0x10000000 /* Also coverse xUnfetch */ /* ** Method declarations for vfstrace_file. */ static int vfstraceClose(sqlite3_file*); static int vfstraceRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); static int vfstraceWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64); |
| ︙ | ︙ | |||
16771 16772 16773 16774 16775 16776 16777 16778 16779 16780 16781 16782 16783 16784 |
{ "dlsym", VTR_DLSYM },
{ "dlclose", VTR_DLCLOSE },
{ "randomness", VTR_RAND },
{ "sleep", VTR_SLEEP },
{ "currenttime", VTR_CURTIME },
{ "currenttimeint64", VTR_CURTIME },
{ "getlasterror", VTR_LASTERR },
};
int onOff = 1;
while( zArg[0] ){
int jj, n;
while( zArg[0]!=0 && zArg[0]!='-' && zArg[0]!='+'
&& !isalpha(zArg[0]) ) zArg++;
if( zArg[0]==0 ) break;
| > | 16786 16787 16788 16789 16790 16791 16792 16793 16794 16795 16796 16797 16798 16799 16800 |
{ "dlsym", VTR_DLSYM },
{ "dlclose", VTR_DLCLOSE },
{ "randomness", VTR_RAND },
{ "sleep", VTR_SLEEP },
{ "currenttime", VTR_CURTIME },
{ "currenttimeint64", VTR_CURTIME },
{ "getlasterror", VTR_LASTERR },
{ "fetch", VTR_FETCH },
};
int onOff = 1;
while( zArg[0] ){
int jj, n;
while( zArg[0]!=0 && zArg[0]!='-' && zArg[0]!='+'
&& !isalpha(zArg[0]) ) zArg++;
if( zArg[0]==0 ) break;
|
| ︙ | ︙ | |||
16998 16999 17000 17001 17002 17003 17004 |
vfstraceOnOff(pInfo, VTR_SHMUNMAP);
vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)",
pInfo->zVfsName, p->zFName, delFlag);
rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
return rc;
}
| > > > > > > > > > > | > > > > > > > > > > > | 17014 17015 17016 17017 17018 17019 17020 17021 17022 17023 17024 17025 17026 17027 17028 17029 17030 17031 17032 17033 17034 17035 17036 17037 17038 17039 17040 17041 17042 17043 17044 17045 17046 17047 17048 17049 |
vfstraceOnOff(pInfo, VTR_SHMUNMAP);
vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)",
pInfo->zVfsName, p->zFName, delFlag);
rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
return rc;
}
static int vfstraceFetch(sqlite3_file *pFile, i64 iOff, int nAmt, void **pptr){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_FETCH);
vfstrace_printf(pInfo, "%s.xFetch(%s,iOff=%lld,nAmt=%d,p=%p)",
pInfo->zVfsName, p->zFName, iOff, nAmt, *pptr);
rc = p->pReal->pMethods->xFetch(p->pReal, iOff, nAmt, pptr);
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
return rc;
}
static int vfstraceUnfetch(sqlite3_file *pFile, i64 iOff, void *ptr){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_FETCH);
vfstrace_printf(pInfo, "%s.xUnfetch(%s,iOff=%lld,p=%p)",
pInfo->zVfsName, p->zFName, iOff, ptr);
rc = p->pReal->pMethods->xUnfetch(p->pReal, iOff, ptr);
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
return rc;
}
/*
** Open an vfstrace file handle.
*/
static int vfstraceOpen(
sqlite3_vfs *pVfs,
|
| ︙ | ︙ | |||
17045 17046 17047 17048 17049 17050 17051 17052 17053 17054 17055 17056 17057 17058 |
pNew->xDeviceCharacteristics = vfstraceDeviceCharacteristics;
if( pNew->iVersion>=2 ){
pNew->xShmMap = pSub->xShmMap ? vfstraceShmMap : 0;
pNew->xShmLock = pSub->xShmLock ? vfstraceShmLock : 0;
pNew->xShmBarrier = pSub->xShmBarrier ? vfstraceShmBarrier : 0;
pNew->xShmUnmap = pSub->xShmUnmap ? vfstraceShmUnmap : 0;
}
pFile->pMethods = pNew;
}
vfstrace_print_errcode(pInfo, " -> %s", rc);
if( pOutFlags ){
vfstrace_printf(pInfo, ", outFlags=0x%x\n", *pOutFlags);
}else{
vfstrace_printf(pInfo, "\n");
| > > > > | 17082 17083 17084 17085 17086 17087 17088 17089 17090 17091 17092 17093 17094 17095 17096 17097 17098 17099 |
pNew->xDeviceCharacteristics = vfstraceDeviceCharacteristics;
if( pNew->iVersion>=2 ){
pNew->xShmMap = pSub->xShmMap ? vfstraceShmMap : 0;
pNew->xShmLock = pSub->xShmLock ? vfstraceShmLock : 0;
pNew->xShmBarrier = pSub->xShmBarrier ? vfstraceShmBarrier : 0;
pNew->xShmUnmap = pSub->xShmUnmap ? vfstraceShmUnmap : 0;
}
if( pNew->iVersion>=3 ){
pNew->xFetch = pSub->xFetch ? vfstraceFetch : 0;
pNew->xUnfetch = pSub->xUnfetch ? vfstraceUnfetch : 0;
}
pFile->pMethods = pNew;
}
vfstrace_print_errcode(pInfo, " -> %s", rc);
if( pOutFlags ){
vfstrace_printf(pInfo, ", outFlags=0x%x\n", *pOutFlags);
}else{
vfstrace_printf(pInfo, "\n");
|
| ︙ | ︙ | |||
17160 17161 17162 17163 17164 17165 17166 |
/*
** Close the dynamic library handle pHandle.
*/
static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
vfstraceOnOff(pInfo, VTR_DLCLOSE);
| | | 17201 17202 17203 17204 17205 17206 17207 17208 17209 17210 17211 17212 17213 17214 17215 |
/*
** Close the dynamic library handle pHandle.
*/
static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
vfstraceOnOff(pInfo, VTR_DLCLOSE);
vfstrace_printf(pInfo, "%s.xDlClose()\n", pInfo->zVfsName);
pRoot->xDlClose(pRoot, pHandle);
}
/*
** Populate the buffer pointed to by zBufOut with nByte bytes of
** random data.
*/
|
| ︙ | ︙ | |||
27458 27459 27460 27461 27462 27463 27464 |
pAr->bGlob = 1;
break;
case AR_SWITCH_VERBOSE:
pAr->bVerbose = 1;
break;
case AR_SWITCH_APPEND:
pAr->bAppend = 1;
| | | 27499 27500 27501 27502 27503 27504 27505 27506 27507 27508 27509 27510 27511 27512 27513 |
pAr->bGlob = 1;
break;
case AR_SWITCH_VERBOSE:
pAr->bVerbose = 1;
break;
case AR_SWITCH_APPEND:
pAr->bAppend = 1;
deliberate_fall_through; /* FALLTHRU */
case AR_SWITCH_FILE:
pAr->zFile = zArg;
break;
case AR_SWITCH_DIRECTORY:
pAr->zDir = zArg;
break;
}
|
| ︙ | ︙ | |||
28846 28847 28848 28849 28850 28851 28852 28853 28854 28855 28856 28857 28858 28859 |
}else
if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbconfig", n)==0 ){
static const struct DbConfigChoices {
const char *zName;
int op;
} aDbConfig[] = {
{ "defensive", SQLITE_DBCONFIG_DEFENSIVE },
{ "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
{ "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
{ "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
{ "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
| > > > | 28887 28888 28889 28890 28891 28892 28893 28894 28895 28896 28897 28898 28899 28900 28901 28902 28903 |
}else
if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbconfig", n)==0 ){
static const struct DbConfigChoices {
const char *zName;
int op;
} aDbConfig[] = {
{ "attach_create", SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE },
{ "attach_write", SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE },
{ "comments", SQLITE_DBCONFIG_ENABLE_COMMENTS },
{ "defensive", SQLITE_DBCONFIG_DEFENSIVE },
{ "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL },
{ "dqs_dml", SQLITE_DBCONFIG_DQS_DML },
{ "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY },
{ "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG },
{ "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER },
{ "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW },
|
| ︙ | ︙ | |||
30200 30201 30202 30203 30204 30205 30206 30207 30208 30209 30210 30211 30212 30213 |
sqlite3_free(zFile);
goto meta_command_exit;
}
}
if( zFile==0 ){
zFile = sqlite3_mprintf("stdout");
}
if( bOnce ){
p->outCount = 2;
}else{
p->outCount = 0;
}
output_reset(p);
#ifndef SQLITE_NOHAVE_SYSTEM
| > | 30244 30245 30246 30247 30248 30249 30250 30251 30252 30253 30254 30255 30256 30257 30258 |
sqlite3_free(zFile);
goto meta_command_exit;
}
}
if( zFile==0 ){
zFile = sqlite3_mprintf("stdout");
}
shell_check_oom(zFile);
if( bOnce ){
p->outCount = 2;
}else{
p->outCount = 0;
}
output_reset(p);
#ifndef SQLITE_NOHAVE_SYSTEM
|
| ︙ | ︙ | |||
30242 30243 30244 30245 30246 30247 30248 30249 30250 30251 30252 30253 30254 30255 30256 30257 30258 30259 30260 |
#ifdef SQLITE_OMIT_POPEN
eputz("Error: pipes are not supported in this OS\n");
rc = 1;
output_redir(p, stdout);
#else
FILE *pfPipe = sqlite3_popen(zFile + 1, "w");
if( pfPipe==0 ){
sqlite3_fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
rc = 1;
}else{
output_redir(p, pfPipe);
if( zBom ) sqlite3_fputs(zBom, pfPipe);
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
}
#endif
}else{
FILE *pfFile = output_file_open(zFile);
if( pfFile==0 ){
if( cli_strcmp(zFile,"off")!=0 ){
| > > | | 30287 30288 30289 30290 30291 30292 30293 30294 30295 30296 30297 30298 30299 30300 30301 30302 30303 30304 30305 30306 30307 30308 30309 30310 30311 30312 30313 30314 30315 |
#ifdef SQLITE_OMIT_POPEN
eputz("Error: pipes are not supported in this OS\n");
rc = 1;
output_redir(p, stdout);
#else
FILE *pfPipe = sqlite3_popen(zFile + 1, "w");
if( pfPipe==0 ){
assert( stderr!=NULL );
sqlite3_fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
rc = 1;
}else{
output_redir(p, pfPipe);
if( zBom ) sqlite3_fputs(zBom, pfPipe);
sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
}
#endif
}else{
FILE *pfFile = output_file_open(zFile);
if( pfFile==0 ){
if( cli_strcmp(zFile,"off")!=0 ){
assert( stderr!=NULL );
sqlite3_fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
}
rc = 1;
} else {
output_redir(p, pfFile);
if( zBom ) sqlite3_fputs(zBom, pfFile);
if( bPlain && eMode=='w' ){
sqlite3_fputs(
|
| ︙ | ︙ | |||
30358 30359 30360 30361 30362 30363 30364 30365 30366 30367 30368 30369 30370 30371 |
if( rx!=SQLITE_OK ){
sqlite3_fprintf(p->out, "Error: %s\n", sqlite3_errmsg(p->db));
sqlite3_finalize(pStmt);
pStmt = 0;
rc = 1;
}
}
sqlite3_step(pStmt);
sqlite3_finalize(pStmt);
}else
/* .parameter unset NAME
** Remove the NAME binding from the parameter binding table, if it
** exists.
| > | 30405 30406 30407 30408 30409 30410 30411 30412 30413 30414 30415 30416 30417 30418 30419 |
if( rx!=SQLITE_OK ){
sqlite3_fprintf(p->out, "Error: %s\n", sqlite3_errmsg(p->db));
sqlite3_finalize(pStmt);
pStmt = 0;
rc = 1;
}
}
bind_prepared_stmt(p, pStmt);
sqlite3_step(pStmt);
sqlite3_finalize(pStmt);
}else
/* .parameter unset NAME
** Remove the NAME binding from the parameter binding table, if it
** exists.
|
| ︙ | ︙ | |||
31592 31593 31594 31595 31596 31597 31598 31599 31600 31601 31602 31603 31604 31605 |
{ 0x00400000, 1, "ReleaseReg" },
{ 0x00800000, 1, "FlttnUnionAll" },
{ 0x01000000, 1, "IndexedEXpr" },
{ 0x02000000, 1, "Coroutines" },
{ 0x04000000, 1, "NullUnusedCols" },
{ 0x08000000, 1, "OnePass" },
{ 0x10000000, 1, "OrderBySubq" },
{ 0xffffffff, 0, "All" },
};
unsigned int curOpt;
unsigned int newOpt;
unsigned int m;
int ii;
int nOff;
| > | 31640 31641 31642 31643 31644 31645 31646 31647 31648 31649 31650 31651 31652 31653 31654 |
{ 0x00400000, 1, "ReleaseReg" },
{ 0x00800000, 1, "FlttnUnionAll" },
{ 0x01000000, 1, "IndexedEXpr" },
{ 0x02000000, 1, "Coroutines" },
{ 0x04000000, 1, "NullUnusedCols" },
{ 0x08000000, 1, "OnePass" },
{ 0x10000000, 1, "OrderBySubq" },
{ 0x20000000, 1, "StarQuery" },
{ 0xffffffff, 0, "All" },
};
unsigned int curOpt;
unsigned int newOpt;
unsigned int m;
int ii;
int nOff;
|
| ︙ | ︙ | |||
32146 32147 32148 32149 32150 32151 32152 |
CONTINUE_PROMPT_AWAITS(pst, "/*");
qss = QSS_SETV(qss, cWait);
goto TermScan;
}
break;
case '[':
cin = ']';
| | | 32195 32196 32197 32198 32199 32200 32201 32202 32203 32204 32205 32206 32207 32208 32209 |
CONTINUE_PROMPT_AWAITS(pst, "/*");
qss = QSS_SETV(qss, cWait);
goto TermScan;
}
break;
case '[':
cin = ']';
deliberate_fall_through; /* FALLTHRU */
case '`': case '\'': case '"':
cWait = cin;
qss = QSS_HasDark | cWait;
CONTINUE_PROMPT_AWAITC(pst, cin);
goto TermScan;
case '(':
CONTINUE_PAREN_INCR(pst, 1);
|
| ︙ | ︙ | |||
32181 32182 32183 32184 32185 32186 32187 |
goto PlainScan;
case '`': case '\'': case '"':
if(*zLine==cWait){
/* Swallow doubled end-delimiter.*/
++zLine;
continue;
}
| | | 32230 32231 32232 32233 32234 32235 32236 32237 32238 32239 32240 32241 32242 32243 32244 |
goto PlainScan;
case '`': case '\'': case '"':
if(*zLine==cWait){
/* Swallow doubled end-delimiter.*/
++zLine;
continue;
}
deliberate_fall_through; /* FALLTHRU */
case ']':
CONTINUE_PROMPT_AWAITC(pst, 0);
qss = QSS_SETV(qss, 0);
goto PlainScan;
default: assert(0);
}
}
|
| ︙ | ︙ |
Changes to extsrc/sqlite3.c.
1 2 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.50.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines ** the programming interface to the SQLite library. (If you do not have ** the "sqlite3.h" header file at hand, you will find a copy embedded within ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed ** if you want a wrapper to interface SQLite with your choice of programming ** language. The code for the "sqlite3" command-line shell is also in a ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in ** 57caa3136d1bfca06e4f2285734a4977b8d3 with changes in files: ** ** */ #ifndef SQLITE_AMALGAMATION #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE |
| ︙ | ︙ | |||
461 462 463 464 465 466 467 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.50.0" #define SQLITE_VERSION_NUMBER 3050000 #define SQLITE_SOURCE_ID "2025-02-18 01:16:26 57caa3136d1bfca06e4f2285734a4977b8d3fa1f75bf87453b975867e9de38fc" /* ** 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 |
| ︙ | ︙ | |||
2304 2305 2306 2307 2308 2309 2310 | ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** the entire mutexing subsystem is omitted from the build and hence calls to ** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will ** return [SQLITE_ERROR].</dd> ** ** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt> ** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine | | | | | | | > > > | 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 |
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine
** the default size of [lookaside memory] on each [database connection].
** The first argument is the
** size of each lookaside buffer slot ("sz") and the second is the number of
** slots allocated to each database connection ("cnt").)^
** ^(SQLITE_CONFIG_LOOKASIDE sets the <i>default</i> lookaside size.
** The [SQLITE_DBCONFIG_LOOKASIDE] option to [sqlite3_db_config()] can
** be used to change the lookaside configuration on individual connections.)^
** The [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to change the
** default lookaside configuration at compile-time.
** </dd>
**
** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is
** a pointer to an [sqlite3_pcache_methods2] object. This object specifies
** the interface to a custom page cache implementation.)^
** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd>
**
|
| ︙ | ︙ | |||
2526 2527 2528 2529 2530 2531 2532 | #define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ #define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */ /* ** CAPI3REF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that | > > | > > > > > > | | > > > > > > > | < | | > | > > > > > > > > > > | | | < | < | | > > > > > > > > > > | > | 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 |
#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */
/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second parameter to the [sqlite3_db_config()] interface.
**
** The [sqlite3_db_config()] interface is a var-args functions. It takes a
** variable number of parameters, though always at least two. The number of
** parameters passed into sqlite3_db_config() depends on which of these
** constants is given as the second parameter. This documentation page
** refers to parameters beyond the second as "arguments". Thus, when this
** page says "the N-th argument" it means "the N-th parameter past the
** configuration option" or "the (N+2)-th parameter to sqlite3_db_config()".
**
** New configuration options may be added in future releases of SQLite.
** Existing configuration options might be discontinued. Applications
** should check the return code from [sqlite3_db_config()] to make sure that
** the call worked. ^The [sqlite3_db_config()] interface will return a
** non-zero [error code] if a discontinued or unsupported configuration option
** is invoked.
**
** <dl>
** [[SQLITE_DBCONFIG_LOOKASIDE]]
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
** <dd> The SQLITE_DBCONFIG_LOOKASIDE option is used to adjust the
** configuration of the [lookaside memory allocator] within a database
** connection.
** The arguments to the SQLITE_DBCONFIG_LOOKASIDE option are <i>not</i>
** in the [DBCONFIG arguments|usual format].
** The SQLITE_DBCONFIG_LOOKASIDE option takes three arguments, not two,
** so that a call to [sqlite3_db_config()] that uses SQLITE_DBCONFIG_LOOKASIDE
** should have a total of five parameters.
** <ol>
** <li><p>The first argument ("buf") is a
** pointer to a memory buffer to use for lookaside memory.
** The first argument may be NULL in which case SQLite will allocate the
** lookaside buffer itself using [sqlite3_malloc()].
** <li><P>The second argument ("sz") is the
** size of each lookaside buffer slot. Lookaside is disabled if "sz"
** is less than 8. The "sz" argument should be a multiple of 8 less than
** 65536. If "sz" does not meet this constraint, it is reduced in size until
** it does.
** <li><p>The third argument ("cnt") is the number of slots. Lookaside is disabled
** if "cnt"is less than 1. The "cnt" value will be reduced, if necessary, so
** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt"
** parameter is usually chosen so that the product of "sz" and "cnt" is less
** than 1,000,000.
** </ol>
** <p>If the "buf" argument is not NULL, then it must
** point to a memory buffer with a size that is greater than
** or equal to the product of "sz" and "cnt".
** The buffer must be aligned to an 8-byte boundary.
** The lookaside memory
** configuration for a database connection can only be changed when that
** connection is not currently using lookaside memory, or in other words
** when the value returned by [SQLITE_DBSTATUS_LOOKASIDE_USED] is zero.
** Any attempt to change the lookaside memory configuration when lookaside
** memory is in use leaves the configuration unchanged and returns
** [SQLITE_BUSY].
** If the "buf" argument is NULL and an attempt
** to allocate memory based on "sz" and "cnt" fails, then
** lookaside is silently disabled.
** <p>
** The [SQLITE_CONFIG_LOOKASIDE] configuration option can be used to set the
** default lookaside configuration at initialization. The
** [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to set the default lookaside
** configuration at compile-time. Typical values for lookaside are 1200 for
** "sz" and 40 to 100 for "cnt".
** </dd>
**
** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
** <dd> ^This option is used to enable or disable the enforcement of
** [foreign key constraints]. This is the same setting that is
** enabled or disabled by the [PRAGMA foreign_keys] statement.
** The first argument is an integer which is 0 to disable FK enforcement,
** positive to enable FK enforcement or negative to leave FK enforcement
** unchanged. The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether FK enforcement is off or on
** following this call. The second parameter may be a NULL pointer, in
** which case the FK enforcement setting is not reported back. </dd>
**
|
| ︙ | ︙ | |||
2584 2585 2586 2587 2588 2589 2590 | ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. ** ** <p>Originally this option disabled all triggers. ^(However, since ** SQLite version 3.35.0, TEMP triggers are still allowed even if ** this option is off. So, in other words, this option now only disables | | | | | > > > > | | | | | | | > | | > | > | | | | 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 | ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. ** ** <p>Originally this option disabled all triggers. ^(However, since ** SQLite version 3.35.0, TEMP triggers are still allowed even if ** this option is off. So, in other words, this option now only disables ** triggers in the main database schema or in the schemas of [ATTACH]-ed ** databases.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] ** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt> ** <dd> ^This option is used to enable or disable [CREATE VIEW | views]. ** There must be two additional arguments. ** The first argument is an integer which is 0 to disable views, ** positive to enable views or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the view setting is not reported back. ** ** <p>Originally this option disabled all views. ^(However, since ** SQLite version 3.35.0, TEMP views are still allowed even if ** this option is off. So, in other words, this option now only disables ** views in the main database schema or in the schemas of ATTACH-ed ** databases.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> ** <dd> ^This option is used to enable or disable the ** [fts3_tokenizer()] function which is part of the ** [FTS3] full-text search engine extension. ** There must be two additional arguments. ** The first argument is an integer which is 0 to disable fts3_tokenizer() or ** positive to enable fts3_tokenizer() or negative to leave the setting ** unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the new setting is not reported back. </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]] ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt> ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()] ** interface independently of the [load_extension()] SQL function. ** The [sqlite3_enable_load_extension()] API enables or disables both the ** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. ** There must be two additional arguments. ** When the first argument to this interface is 1, then only the C-API is ** enabled and the SQL function remains disabled. If the first argument to ** this interface is 0, then both the C-API and the SQL function are disabled. ** If the first argument is -1, then no changes are made to state of either the ** C-API or the SQL function. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface ** is disabled or enabled following this call. The second parameter may ** be a NULL pointer, in which case the new setting is not reported back. ** </dd> ** ** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt> ** <dd> ^This option is used to change the name of the "main" database ** schema. This option does not follow the ** [DBCONFIG arguments|usual SQLITE_DBCONFIG argument format]. ** This option takes exactly one additional argument so that the ** [sqlite3_db_config()] call has a total of three parameters. The ** extra argument must be a pointer to a constant UTF8 string which ** will become the new schema name in place of "main". ^SQLite does ** not make a copy of the new main schema name string, so the application ** must ensure that the argument passed into SQLITE_DBCONFIG MAINDBNAME ** is unchanged until after the database connection closes. ** </dd> ** ** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt> ** <dd> Usually, when a database in [WAL mode] is closed or detached from a ** database handle, SQLite checks if if there are other connections to the ** same database, and if there are no other database connection (if the ** connection being closed is the last open connection to the database), ** then SQLite performs a [checkpoint] before closing the connection and ** deletes the WAL file. The SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE option can ** be used to override that behavior. The first argument passed to this ** operation (the third parameter to [sqlite3_db_config()]) is an integer ** which is positive to disable checkpoints-on-close, or zero (the default) ** to enable them, and negative to leave the setting unchanged. ** The second argument (the fourth parameter) is a pointer to an integer ** into which is written 0 or 1 to indicate whether checkpoints-on-close ** have been disabled - 0 if they are not disabled, 1 if they are. ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt> ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates ** the [query planner stability guarantee] (QPSG). When the QPSG is active, |
| ︙ | ︙ | |||
2815 2816 2817 2818 2819 2820 2821 | ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt> ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() ** statistics. For statistics to be collected, the flag must be set on ** the database handle both when the SQL statement is prepared and when it ** is stepped. The flag is set (collection of statistics is enabled) | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 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 | ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt> ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() ** statistics. For statistics to be collected, the flag must be set on ** the database handle both when the SQL statement is prepared and when it ** is stepped. The flag is set (collection of statistics is enabled) ** by default. <p>This option takes two arguments: an integer and a pointer to ** an integer.. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the statement scanstatus option. If the second argument ** is not NULL, then the value of the statement scanstatus setting after ** processing the first argument is written into the integer that the second ** argument points to. ** </dd> ** ** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]] ** <dt>SQLITE_DBCONFIG_REVERSE_SCANORDER</dt> ** <dd>The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order ** in which tables and indexes are scanned so that the scans start at the end ** and work toward the beginning rather than starting at the beginning and ** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the ** same as setting [PRAGMA reverse_unordered_selects]. <p>This option takes ** two arguments which are an integer and a pointer to an integer. The first ** argument is 1, 0, or -1 to enable, disable, or leave unchanged the ** reverse scan order flag, respectively. If the second argument is not NULL, ** then 0 or 1 is written into the integer that the second argument points to ** depending on if the reverse scan order flag is set after processing the ** first argument. ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE]] ** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE</dt> ** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE option enables or disables ** the ability of the [ATTACH DATABASE] SQL command to create a new database ** file if the database filed named in the ATTACH command does not already ** exist. This ability of ATTACH to create a new database is enabled by ** default. Applications can disable or reenable the ability for ATTACH to ** create new database files using this DBCONFIG option.<p> ** This option takes two arguments which are an integer and a pointer ** to an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the attach-create flag, respectively. If the second ** argument is not NULL, then 0 or 1 is written into the integer that the ** second argument points to depending on if the attach-create flag is set ** after processing the first argument. ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE]] ** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE</dt> ** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE option enables or disables the ** ability of the [ATTACH DATABASE] SQL command to open a database for writing. ** This capability is enabled by default. Applications can disable or ** reenable this capability using the current DBCONFIG option. If the ** the this capability is disabled, the [ATTACH] command will still work, ** but the database will be opened read-only. If this option is disabled, ** then the ability to create a new database using [ATTACH] is also disabled, ** regardless of the value of the [SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE] ** option.<p> ** This option takes two arguments which are an integer and a pointer ** to an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the ability to ATTACH another database for writing, ** respectively. If the second argument is not NULL, then 0 or 1 is written ** into the integer to which the second argument points, depending on whether ** the ability to ATTACH a read/write database is enabled or disabled ** after processing the first argument. ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_COMMENTS]] ** <dt>SQLITE_DBCONFIG_ENABLE_COMMENTS</dt> ** <dd>The SQLITE_DBCONFIG_ENABLE_COMMENTS option enables or disables the ** ability to include comments in SQL text. Comments are enabled by default. ** An application can disable or reenable comments in SQL text using this ** DBCONFIG option.<p> ** This option takes two arguments which are an integer and a pointer ** to an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the ability to use comments in SQL text, ** respectively. If the second argument is not NULL, then 0 or 1 is written ** into the integer that the second argument points to depending on if ** comments are allowed in SQL text after processing the first argument. ** </dd> ** ** </dl> ** ** [[DBCONFIG arguments]] <h3>Arguments To SQLITE_DBCONFIG Options</h3> ** ** <p>Most of the SQLITE_DBCONFIG options take two arguments, so that the ** overall call to [sqlite3_db_config()] has a total of four parameters. ** The first argument (the third parameter to sqlite3_db_config()) is a integer. ** The second argument is a pointer to an integer. If the first argument is 1, ** then the option becomes enabled. If the first integer argument is 0, then the ** option is disabled. If the first argument is -1, then the option setting ** is unchanged. The second argument, the pointer to an integer, may be NULL. ** If the second argument is not NULL, then a value of 0 or 1 is written into ** the integer to which the second argument points, depending on whether the ** setting is disabled or enabled after applying any changes specified by ** the first argument. ** ** <p>While most SQLITE_DBCONFIG options use the argument format ** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME] ** and [SQLITE_DBCONFIG_LOOKASIDE] options are different. See the ** documentation of those exceptional options for details. */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ |
| ︙ | ︙ | |||
2860 2861 2862 2863 2864 2865 2866 | #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ #define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ #define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ | > > > | | 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 | #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ #define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ #define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 /* int int* */ #define SQLITE_DBCONFIG_MAX 1022 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes ** METHOD: sqlite3 ** ** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result |
| ︙ | ︙ | |||
11063 11064 11065 11066 11067 11068 11069 | ** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Serialize a database ** | | | > | 11179 11180 11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 11192 11193 11194 11195 | ** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Serialize a database ** ** The sqlite3_serialize(D,S,P,F) interface returns a pointer to ** memory that is a serialization of the S database on ** [database connection] D. If S is a NULL pointer, the main database is used. ** If P is not a NULL pointer, then the size of the database in bytes ** is written into *P. ** ** For an ordinary on-disk database file, the serialization is just a ** copy of the disk file. For an in-memory database or a "TEMP" database, ** the serialization is the same sequence of bytes which would be written ** to disk if that database where backed up to disk. |
| ︙ | ︙ | |||
12230 12231 12232 12233 12234 12235 12236 | int nA, /* Number of bytes in buffer pA */ void *pA, /* Pointer to buffer containing changeset A */ int nB, /* Number of bytes in buffer pB */ void *pB, /* Pointer to buffer containing changeset B */ int *pnOut, /* OUT: Number of bytes in output changeset */ void **ppOut /* OUT: Buffer containing output changeset */ ); | < < < < < < < < < < < < < | 12347 12348 12349 12350 12351 12352 12353 12354 12355 12356 12357 12358 12359 12360 | int nA, /* Number of bytes in buffer pA */ void *pA, /* Pointer to buffer containing changeset A */ int nB, /* Number of bytes in buffer pB */ void *pB, /* Pointer to buffer containing changeset B */ int *pnOut, /* OUT: Number of bytes in output changeset */ void **ppOut /* OUT: Buffer containing output changeset */ ); /* ** CAPI3REF: Changegroup Handle ** ** A changegroup is an object used to combine two or more ** [changesets] or [patchsets] */ |
| ︙ | ︙ | |||
14044 14045 14046 14047 14048 14049 14050 14051 14052 | */ #ifndef SQLITE_MAX_VDBE_OP # define SQLITE_MAX_VDBE_OP 250000000 #endif /* ** The maximum number of arguments to an SQL function. */ #ifndef SQLITE_MAX_FUNCTION_ARG | > > > > | | 14148 14149 14150 14151 14152 14153 14154 14155 14156 14157 14158 14159 14160 14161 14162 14163 14164 14165 14166 14167 14168 | */ #ifndef SQLITE_MAX_VDBE_OP # define SQLITE_MAX_VDBE_OP 250000000 #endif /* ** The maximum number of arguments to an SQL function. ** ** This value has a hard upper limit of 32767 due to storage ** constraints (it needs to fit inside a i16). We keep it ** lower than that to prevent abuse. */ #ifndef SQLITE_MAX_FUNCTION_ARG # define SQLITE_MAX_FUNCTION_ARG 1000 #endif /* ** The suggested maximum number of in-memory pages to use for ** the main database table and for temporary tables. ** ** IMPLEMENTATION-OF: R-30185-15359 The default suggested cache size is -2000, |
| ︙ | ︙ | |||
14646 14647 14648 14649 14650 14651 14652 14653 14654 14655 14656 14657 14658 14659 |
** Again, this structure is intended to be opaque, but it can't really
** be opaque because it is used by macros.
*/
struct HashElem {
HashElem *next, *prev; /* Next and previous elements in the table */
void *data; /* Data associated with this element */
const char *pKey; /* Key associated with this element */
};
/*
** Access routines. To delete, insert a NULL pointer.
*/
SQLITE_PRIVATE void sqlite3HashInit(Hash*);
SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, void *pData);
| > | 14754 14755 14756 14757 14758 14759 14760 14761 14762 14763 14764 14765 14766 14767 14768 |
** Again, this structure is intended to be opaque, but it can't really
** be opaque because it is used by macros.
*/
struct HashElem {
HashElem *next, *prev; /* Next and previous elements in the table */
void *data; /* Data associated with this element */
const char *pKey; /* Key associated with this element */
unsigned int h; /* hash for pKey */
};
/*
** Access routines. To delete, insert a NULL pointer.
*/
SQLITE_PRIVATE void sqlite3HashInit(Hash*);
SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, void *pData);
|
| ︙ | ︙ | |||
14869 14870 14871 14872 14873 14874 14875 | #define TK_SELECT_COLUMN 178 #define TK_IF_NULL_ROW 179 #define TK_ASTERISK 180 #define TK_SPAN 181 #define TK_ERROR 182 #define TK_QNUMBER 183 #define TK_SPACE 184 | > | | 14978 14979 14980 14981 14982 14983 14984 14985 14986 14987 14988 14989 14990 14991 14992 14993 | #define TK_SELECT_COLUMN 178 #define TK_IF_NULL_ROW 179 #define TK_ASTERISK 180 #define TK_SPAN 181 #define TK_ERROR 182 #define TK_QNUMBER 183 #define TK_SPACE 184 #define TK_COMMENT 185 #define TK_ILLEGAL 186 /************** End of parse.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> |
| ︙ | ︙ | |||
15083 15084 15085 15086 15087 15088 15089 15090 15091 15092 15093 15094 15095 15096 | typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ typedef UINT16_TYPE u16; /* 2-byte unsigned integer */ typedef INT16_TYPE i16; /* 2-byte signed integer */ typedef UINT8_TYPE u8; /* 1-byte unsigned integer */ typedef INT8_TYPE i8; /* 1-byte signed integer */ /* ** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value ** that can be stored in a u32 without loss of data. The value ** is 0x00000000ffffffff. But because of quirks of some compilers, we ** have to specify the value in the less intuitive manner shown: */ #define SQLITE_MAX_U32 ((((u64)1)<<32)-1) | > > > > > | 15193 15194 15195 15196 15197 15198 15199 15200 15201 15202 15203 15204 15205 15206 15207 15208 15209 15210 15211 | typedef sqlite_uint64 u64; /* 8-byte unsigned integer */ typedef UINT32_TYPE u32; /* 4-byte unsigned integer */ typedef UINT16_TYPE u16; /* 2-byte unsigned integer */ typedef INT16_TYPE i16; /* 2-byte signed integer */ typedef UINT8_TYPE u8; /* 1-byte unsigned integer */ typedef INT8_TYPE i8; /* 1-byte signed integer */ /* A bitfield type for use inside of structures. Always follow with :N where ** N is the number of bits. */ typedef unsigned bft; /* Bit Field Type */ /* ** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value ** that can be stored in a u32 without loss of data. The value ** is 0x00000000ffffffff. But because of quirks of some compilers, we ** have to specify the value in the less intuitive manner shown: */ #define SQLITE_MAX_U32 ((((u64)1)<<32)-1) |
| ︙ | ︙ | |||
15121 15122 15123 15124 15125 15126 15127 15128 15129 15130 15131 15132 15133 15134 | ** ** The LogEst can be negative to indicate fractional values. ** Examples: ** ** 0.5 -> -10 0.1 -> -33 0.0625 -> -40 */ typedef INT16_TYPE LogEst; /* ** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer */ #ifndef SQLITE_PTRSIZE # if defined(__SIZEOF_POINTER__) # define SQLITE_PTRSIZE __SIZEOF_POINTER__ | > > | 15236 15237 15238 15239 15240 15241 15242 15243 15244 15245 15246 15247 15248 15249 15250 15251 | ** ** The LogEst can be negative to indicate fractional values. ** Examples: ** ** 0.5 -> -10 0.1 -> -33 0.0625 -> -40 */ typedef INT16_TYPE LogEst; #define LOGEST_MIN (-32768) #define LOGEST_MAX (32767) /* ** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer */ #ifndef SQLITE_PTRSIZE # if defined(__SIZEOF_POINTER__) # define SQLITE_PTRSIZE __SIZEOF_POINTER__ |
| ︙ | ︙ | |||
15249 15250 15251 15252 15253 15254 15255 15256 15257 15258 15259 15260 15261 15262 | ** These macros are designed to work correctly on both 32-bit and 64-bit ** compilers. */ #define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) #define LARGEST_UINT64 (0xffffffff|(((u64)0xffffffff)<<32)) #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) /* ** Round up a number to the next larger multiple of 8. This is used ** to force 8-byte alignment on 64-bit architectures. ** ** ROUND8() always does the rounding, for any argument. ** ** ROUND8P() assumes that the argument is already an integer number of | > > > > > > > > | 15366 15367 15368 15369 15370 15371 15372 15373 15374 15375 15376 15377 15378 15379 15380 15381 15382 15383 15384 15385 15386 15387 | ** These macros are designed to work correctly on both 32-bit and 64-bit ** compilers. */ #define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) #define LARGEST_UINT64 (0xffffffff|(((u64)0xffffffff)<<32)) #define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) /* ** Macro SMXV(n) return the maximum value that can be held in variable n, ** assuming n is a signed integer type. UMXV(n) is similar for unsigned ** integer types. */ #define SMXV(n) ((((i64)1)<<(sizeof(n)-1))-1) #define UMXV(n) ((((i64)1)<<(sizeof(n)))-1) /* ** Round up a number to the next larger multiple of 8. This is used ** to force 8-byte alignment on 64-bit architectures. ** ** ROUND8() always does the rounding, for any argument. ** ** ROUND8P() assumes that the argument is already an integer number of |
| ︙ | ︙ | |||
15391 15392 15393 15394 15395 15396 15397 | ** ** (---any--) Top-level block structure ** 0x-------F High-level debug messages ** 0x----FFF- More detail ** 0xFFFF---- Low-level debug messages ** ** 0x00000001 Code generation | | > > | 15516 15517 15518 15519 15520 15521 15522 15523 15524 15525 15526 15527 15528 15529 15530 15531 15532 15533 15534 15535 15536 15537 15538 15539 15540 15541 15542 15543 15544 15545 15546 15547 15548 15549 15550 | ** ** (---any--) Top-level block structure ** 0x-------F High-level debug messages ** 0x----FFF- More detail ** 0xFFFF---- Low-level debug messages ** ** 0x00000001 Code generation ** 0x00000002 Solver (Use 0x40000 for less detail) ** 0x00000004 Solver costs ** 0x00000008 WhereLoop inserts ** ** 0x00000010 Display sqlite3_index_info xBestIndex calls ** 0x00000020 Range an equality scan metrics ** 0x00000040 IN operator decisions ** 0x00000080 WhereLoop cost adjustments ** 0x00000100 ** 0x00000200 Covering index decisions ** 0x00000400 OR optimization ** 0x00000800 Index scanner ** 0x00001000 More details associated with code generation ** 0x00002000 ** 0x00004000 Show all WHERE terms at key points ** 0x00008000 Show the full SELECT statement at key places ** ** 0x00010000 Show more detail when printing WHERE terms ** 0x00020000 Show WHERE terms returned from whereScanNext() ** 0x00040000 Solver overview messages ** 0x00080000 Star-query heuristic */ /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. ** |
| ︙ | ︙ | |||
16047 16048 16049 16050 16051 16052 16053 16054 16055 16056 16057 16058 16059 16060 | #define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */ #define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */ #define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */ #define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */ #define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */ #define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */ #define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ /* ** Flags that make up the mask passed to sqlite3PagerGet(). */ #define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */ #define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */ | > > > > > > > > > > > > > > > > | 16174 16175 16176 16177 16178 16179 16180 16181 16182 16183 16184 16185 16186 16187 16188 16189 16190 16191 16192 16193 16194 16195 16196 16197 16198 16199 16200 16201 16202 16203 |
#define PAGER_JOURNALMODE_QUERY (-1) /* Query the value of journalmode */
#define PAGER_JOURNALMODE_DELETE 0 /* Commit by deleting journal file */
#define PAGER_JOURNALMODE_PERSIST 1 /* Commit by zeroing journal header */
#define PAGER_JOURNALMODE_OFF 2 /* Journal omitted. */
#define PAGER_JOURNALMODE_TRUNCATE 3 /* Commit by truncating journal */
#define PAGER_JOURNALMODE_MEMORY 4 /* In-memory journal file */
#define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */
#define isWalMode(x) ((x)==PAGER_JOURNALMODE_WAL)
/*
** The argument to this macro is a file descriptor (type sqlite3_file*).
** Return 0 if it is not open, or non-zero (but not 1) if it is.
**
** This is so that expressions can be written as:
**
** if( isOpen(pPager->jfd) ){ ...
**
** instead of
**
** if( pPager->jfd->pMethods ){ ...
*/
#define isOpen(pFd) ((pFd)->pMethods!=0)
/*
** Flags that make up the mask passed to sqlite3PagerGet().
*/
#define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */
#define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */
|
| ︙ | ︙ | |||
16686 16687 16688 16689 16690 16691 16692 16693 16694 16695 16696 16697 16698 16699 |
/*
** 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 */
};
/*
| > | 16829 16830 16831 16832 16833 16834 16835 16836 16837 16838 16839 16840 16841 16842 16843 |
/*
** 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 */
};
/*
|
| ︙ | ︙ | |||
18016 18017 18018 18019 18020 18021 18022 18023 18024 18025 18026 18027 18028 18029 |
#define SQLITE_EnableView 0x80000000 /* Enable the use of views */
#define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */
/* DELETE, or UPDATE and return */
/* the count using a callback. */
#define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */
#define SQLITE_ReadUncommit HI(0x00004) /* READ UNCOMMITTED in shared-cache */
#define SQLITE_FkNoAction HI(0x00008) /* Treat all FK as NO ACTION */
/* Flags used only if debugging */
#ifdef SQLITE_DEBUG
#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
#define SQLITE_VdbeTrace HI(0x0400000) /* True to trace VDBE execution */
#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */
| > > > | 18160 18161 18162 18163 18164 18165 18166 18167 18168 18169 18170 18171 18172 18173 18174 18175 18176 |
#define SQLITE_EnableView 0x80000000 /* Enable the use of views */
#define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */
/* DELETE, or UPDATE and return */
/* the count using a callback. */
#define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */
#define SQLITE_ReadUncommit HI(0x00004) /* READ UNCOMMITTED in shared-cache */
#define SQLITE_FkNoAction HI(0x00008) /* Treat all FK as NO ACTION */
#define SQLITE_AttachCreate HI(0x00010) /* ATTACH allowed to create new dbs */
#define SQLITE_AttachWrite HI(0x00020) /* ATTACH allowed to open for write */
#define SQLITE_Comments HI(0x00040) /* Enable SQL comments */
/* Flags used only if debugging */
#ifdef SQLITE_DEBUG
#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
#define SQLITE_VdbeTrace HI(0x0400000) /* True to trace VDBE execution */
#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */
|
| ︙ | ︙ | |||
18075 18076 18077 18078 18079 18080 18081 18082 18083 18084 18085 18086 18087 18088 | #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. */ #define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) #define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) | > | 18222 18223 18224 18225 18226 18227 18228 18229 18230 18231 18232 18233 18234 18235 18236 | #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ #define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_OrderBySubq 0x10000000 /* ORDER BY in subquery helps outer */ #define SQLITE_StarQuery 0x20000000 /* Heurists for star queries */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. */ #define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) #define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) |
| ︙ | ︙ | |||
18111 18112 18113 18114 18115 18116 18117 |
** For per-connection application-defined functions, a pointer to this
** structure is held in the db->aHash hash table.
**
** The u.pHash field is used by the global built-ins. The u.pDestructor
** field is used by per-connection app-def functions.
*/
struct FuncDef {
| | | 18259 18260 18261 18262 18263 18264 18265 18266 18267 18268 18269 18270 18271 18272 18273 |
** For per-connection application-defined functions, a pointer to this
** structure is held in the db->aHash hash table.
**
** The u.pHash field is used by the global built-ins. The u.pDestructor
** field is used by per-connection app-def functions.
*/
struct FuncDef {
i16 nArg; /* Number of arguments. -1 means unlimited */
u32 funcFlags; /* Some combination of SQLITE_FUNC_* */
void *pUserData; /* User data parameter */
FuncDef *pNext; /* Next function with same name */
void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */
void (*xFinalize)(sqlite3_context*); /* Agg finalizer */
void (*xValue)(sqlite3_context*); /* Current agg value */
void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */
|
| ︙ | ︙ | |||
18604 18605 18606 18607 18608 18609 18610 18611 18612 18613 18614 18615 18616 18617 |
int nArg; /* Number of arguments to the module */
char **azArg; /* 0: module 1: schema 2: vtab name 3...: args */
VTable *p; /* List of VTable objects. */
} vtab;
} u;
Trigger *pTrigger; /* List of triggers on this object */
Schema *pSchema; /* Schema that contains this table */
};
/*
** Allowed values for Table.tabFlags.
**
** TF_OOOHidden applies to tables or view that have hidden columns that are
** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING
| > | 18752 18753 18754 18755 18756 18757 18758 18759 18760 18761 18762 18763 18764 18765 18766 |
int nArg; /* Number of arguments to the module */
char **azArg; /* 0: module 1: schema 2: vtab name 3...: args */
VTable *p; /* List of VTable objects. */
} vtab;
} u;
Trigger *pTrigger; /* List of triggers on this object */
Schema *pSchema; /* Schema that contains this table */
u8 aHx[16]; /* Column aHt[K%sizeof(aHt)] might have hash K */
};
/*
** Allowed values for Table.tabFlags.
**
** TF_OOOHidden applies to tables or view that have hidden columns that are
** followed by non-hidden columns. Example: "CREATE VIRTUAL TABLE x USING
|
| ︙ | ︙ | |||
19404 19405 19406 19407 19408 19409 19410 |
**
** INSERT INTO t(a,b,c) ...
**
** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
*/
struct IdList {
int nId; /* Number of identifiers on the list */
| < < < < < | 19553 19554 19555 19556 19557 19558 19559 19560 19561 19562 19563 19564 19565 19566 19567 19568 |
**
** INSERT INTO t(a,b,c) ...
**
** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
*/
struct IdList {
int nId; /* Number of identifiers on the list */
struct IdList_item {
char *zName; /* Name of the identifier */
} a[1];
};
/*
** Allowed values for IdList.eType, which determines which value of the a.u4
** is valid.
*/
|
| ︙ | ︙ | |||
20006 20007 20008 20009 20010 20011 20012 |
** list.
*/
struct Parse {
sqlite3 *db; /* The main database structure */
char *zErrMsg; /* An error message */
Vdbe *pVdbe; /* An engine for executing database bytecode */
int rc; /* Return code from execution */
| | < < < > > > > > > > > > > < < < | < < < < < < < < < < < > > > > > > > > > > > > > < < | 20150 20151 20152 20153 20154 20155 20156 20157 20158 20159 20160 20161 20162 20163 20164 20165 20166 20167 20168 20169 20170 20171 20172 20173 20174 20175 20176 20177 20178 20179 20180 20181 20182 20183 20184 20185 20186 20187 20188 20189 20190 20191 20192 20193 20194 20195 20196 20197 20198 20199 20200 20201 20202 20203 20204 20205 20206 20207 20208 20209 20210 20211 20212 20213 20214 20215 20216 20217 20218 20219 20220 20221 20222 20223 20224 20225 20226 20227 20228 20229 20230 20231 20232 20233 20234 20235 20236 20237 20238 20239 20240 20241 20242 20243 20244 20245 20246 20247 20248 20249 20250 20251 20252 20253 20254 20255 20256 20257 20258 20259 20260 20261 |
** list.
*/
struct Parse {
sqlite3 *db; /* The main database structure */
char *zErrMsg; /* An error message */
Vdbe *pVdbe; /* An engine for executing database bytecode */
int rc; /* Return code from execution */
LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
u8 nested; /* Number of nested calls to the parser/code generator */
u8 nTempReg; /* Number of temporary registers in aTempReg[] */
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
u8 mayAbort; /* True if statement may throw an ABORT exception */
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
u8 disableLookaside; /* Number of times lookaside has been disabled */
u8 prepFlags; /* SQLITE_PREPARE_* flags */
u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */
u8 mSubrtnSig; /* mini Bloom filter on available SubrtnSig.selId */
u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
u8 bReturning; /* Coding a RETURNING trigger */
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
u8 disableTriggers; /* True to disable triggers */
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */
#endif
#ifdef SQLITE_DEBUG
u8 ifNotExists; /* Might be true if IF NOT EXISTS. Assert()s only */
u8 isCreate; /* CREATE TABLE, INDEX, or VIEW (but not TRIGGER)
** and ALTER TABLE ADD COLUMN. */
#endif
bft colNamesSet :1; /* TRUE after OP_ColumnName has been issued to pVdbe */
bft bHasWith :1; /* True if statement contains WITH */
bft okConstFactor :1; /* OK to factor out constants */
bft checkSchema :1; /* Causes schema cookie check after an error */
int nRangeReg; /* Size of the temporary register block */
int iRangeReg; /* First register in temporary register block */
int nErr; /* Number of errors seen */
int nTab; /* Number of previously allocated VDBE cursors */
int nMem; /* Number of memory cells used so far */
int szOpAlloc; /* Bytes of memory space allocated for Vdbe.aOp[] */
int iSelfTab; /* Table associated with an index on expr, or negative
** of the base register during check-constraint eval */
int nLabel; /* The *negative* of the number of labels used */
int nLabelAlloc; /* Number of slots in aLabel */
int *aLabel; /* Space to hold the labels */
ExprList *pConstExpr;/* Constant expressions */
IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */
IndexedExpr *pIdxPartExpr; /* Exprs constrained by index WHERE clauses */
yDbMask writeMask; /* Start a write transaction on these databases */
yDbMask cookieMask; /* Bitmask of schema verified databases */
int nMaxArg; /* Max args to xUpdate and xFilter vtab methods */
int nSelect; /* Number of SELECT stmts. Counter for Select.selId */
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */
#endif
#ifndef SQLITE_OMIT_SHARED_CACHE
int nTableLock; /* Number of locks in aTableLock */
TableLock *aTableLock; /* Required table locks for shared-cache mode */
#endif
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
Parse *pToplevel; /* Parse structure for main program (or NULL) */
Table *pTriggerTab; /* Table triggers are being coded for */
TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */
ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */
/**************************************************************************
** Fields above must be initialized to zero. The fields that follow,
** down to the beginning of the recursive section, do not need to be
** initialized as they will be set before being used. The boundary is
** determined by offsetof(Parse,aTempReg).
**************************************************************************/
int aTempReg[8]; /* Holding area for temporary registers */
Parse *pOuterParse; /* Outer Parse object when nested */
Token sNameToken; /* Token with unqualified schema object name */
u32 oldmask; /* Mask of old.* columns referenced */
u32 newmask; /* Mask of new.* columns referenced */
union {
struct { /* These fields available when isCreate is true */
int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */
int regRowid; /* Register holding rowid of CREATE TABLE entry */
int regRoot; /* Register holding root page for new objects */
Token constraintName; /* Name of the constraint currently being parsed */
} cr;
struct { /* These fields available to all other statements */
Returning *pReturning; /* The RETURNING clause */
} d;
} u1;
/************************************************************************
** Above is constant between recursions. Below is reset before and after
** each recursion. The boundary between these two regions is determined
** using offsetof(Parse,sLastToken) so the sLastToken field must be the
** first field in the recursive region.
************************************************************************/
Token sLastToken; /* The last token parsed */
ynVar nVar; /* Number of '?' variables seen in the SQL so far */
u8 iPkSortOrder; /* ASC or DESC for INTEGER PRIMARY KEY */
u8 explain; /* True if the EXPLAIN flag is found on the query */
u8 eParseMode; /* PARSE_MODE_XXX constant */
#ifndef SQLITE_OMIT_VIRTUALTABLE
int nVtabLock; /* Number of virtual tables to lock */
#endif
int nHeight; /* Expression tree height of current sub-select */
int addrExplain; /* Address of current OP_Explain opcode */
VList *pVList; /* Mapping between variable names and numbers */
Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */
const char *zTail; /* All SQL text past the last semicolon parsed */
Table *pNewTable; /* A table being constructed by CREATE TABLE */
Index *pNewIndex; /* An index being constructed by CREATE INDEX.
** Also used to hold redundant UNIQUE constraints
** during a RENAME COLUMN */
|
| ︙ | ︙ | |||
23557 23558 23559 23560 23561 23562 23563 23564 23565 23566 23567 23568 23569 23570 | int szMalloc; /* Size of the zMalloc allocation */ u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ u16 mScopyFlags; /* flags value immediately after the shallow copy */ #endif }; /* ** Size of struct Mem not including the Mem.zMalloc member or anything that ** follows. */ | > | 23705 23706 23707 23708 23709 23710 23711 23712 23713 23714 23715 23716 23717 23718 23719 | int szMalloc; /* Size of the zMalloc allocation */ u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ u16 mScopyFlags; /* flags value immediately after the shallow copy */ u8 bScopy; /* The pScopyFrom of some other Mem *might* point here */ #endif }; /* ** Size of struct Mem not including the Mem.zMalloc member or anything that ** follows. */ |
| ︙ | ︙ | |||
23706 23707 23708 23709 23710 23711 23712 | FuncDef *pFunc; /* Pointer to function information */ Mem *pMem; /* Memory cell used to store aggregate context */ Vdbe *pVdbe; /* The VM that owns this context */ int iOp; /* Instruction number of OP_Function */ int isError; /* Error code returned by the function. */ u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ | | < < < < | 23855 23856 23857 23858 23859 23860 23861 23862 23863 23864 23865 23866 23867 23868 23869 23870 23871 23872 | FuncDef *pFunc; /* Pointer to function information */ Mem *pMem; /* Memory cell used to store aggregate context */ Vdbe *pVdbe; /* The VM that owns this context */ int iOp; /* Instruction number of OP_Function */ int isError; /* Error code returned by the function. */ u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ u16 argc; /* Number of arguments */ sqlite3_value *argv[1]; /* Argument set */ }; /* The ScanStatus object holds a single value for the ** sqlite3_stmt_scanstatus() interface. ** ** aAddrRange[]: ** This array is used by ScanStatus elements associated with EQP ** notes that make an SQLITE_SCANSTAT_NCYCLE value available. It is |
| ︙ | ︙ | |||
23774 23775 23776 23777 23778 23779 23780 |
i64 nChange; /* Number of db changes made since last reset */
int iStatement; /* Statement number (or 0 if has no opened stmt) */
i64 iCurrentTime; /* Value of julianday('now') for this statement */
i64 nFkConstraint; /* Number of imm. FK constraints this VM */
i64 nStmtDefCons; /* Number of def. constraints when stmt started */
i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
Mem *aMem; /* The memory locations */
| | > | 23919 23920 23921 23922 23923 23924 23925 23926 23927 23928 23929 23930 23931 23932 23933 23934 23935 23936 23937 23938 23939 23940 23941 23942 23943 23944 23945 23946 23947 23948 23949 23950 23951 23952 23953 |
i64 nChange; /* Number of db changes made since last reset */
int iStatement; /* Statement number (or 0 if has no opened stmt) */
i64 iCurrentTime; /* Value of julianday('now') for this statement */
i64 nFkConstraint; /* Number of imm. FK constraints this VM */
i64 nStmtDefCons; /* Number of def. constraints when stmt started */
i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
Mem *aMem; /* The memory locations */
Mem **apArg; /* Arguments xUpdate and xFilter vtab methods */
VdbeCursor **apCsr; /* One element of this array for each open cursor */
Mem *aVar; /* Values for the OP_Variable opcode. */
/* When allocating a new Vdbe object, all of the fields below should be
** initialized to zero or NULL */
Op *aOp; /* Space to hold the virtual machine's program */
int nOp; /* Number of instructions in the program */
int nOpAlloc; /* Slots allocated for aOp[] */
Mem *aColName; /* Column names to return */
Mem *pResultRow; /* Current output row */
char *zErrMsg; /* Error message written here */
VList *pVList; /* Name of variables */
#ifndef SQLITE_OMIT_TRACE
i64 startTime; /* Time when query started - used for profiling */
#endif
#ifdef SQLITE_DEBUG
int rcApp; /* errcode set by sqlite3_result_error_code() */
u32 nWrite; /* Number of write operations that have occurred */
int napArg; /* Size of the apArg[] array */
#endif
u16 nResColumn; /* Number of columns in one row of the result set */
u16 nResAlloc; /* Column slots allocated to aColName[] */
u8 errorAction; /* Recovery action to do in case of an error */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
u8 prepFlags; /* SQLITE_PREPARE_* flags */
u8 eVdbeState; /* On of the VDBE_*_STATE values */
|
| ︙ | ︙ | |||
24655 24656 24657 24658 24659 24660 24661 24662 24663 24664 24665 24666 24667 24668 |
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;
| > > > | 24801 24802 24803 24804 24805 24806 24807 24808 24809 24810 24811 24812 24813 24814 24815 24816 24817 |
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;
|
| ︙ | ︙ | |||
25862 25863 25864 25865 25866 25867 25868 |
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;
| | | 26011 26012 26013 26014 26015 26016 26017 26018 26019 26020 26021 26022 26023 26024 26025 |
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;
}
|
| ︙ | ︙ | |||
32422 32423 32424 32425 32426 32427 32428 |
** Finish off a string by making sure it is zero-terminated.
** Return a pointer to the resulting string. Return a NULL
** pointer if any kind of error was encountered.
*/
static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){
char *zText;
assert( p->mxAlloc>0 && !isMalloced(p) );
| | | 32571 32572 32573 32574 32575 32576 32577 32578 32579 32580 32581 32582 32583 32584 32585 |
** Finish off a string by making sure it is zero-terminated.
** Return a pointer to the resulting string. Return a NULL
** pointer if any kind of error was encountered.
*/
static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){
char *zText;
assert( p->mxAlloc>0 && !isMalloced(p) );
zText = sqlite3DbMallocRaw(p->db, 1+(u64)p->nChar );
if( zText ){
memcpy(zText, p->zText, p->nChar+1);
p->printfFlags |= SQLITE_PRINTF_MALLOCED;
}else{
sqlite3StrAccumSetError(p, SQLITE_NOMEM);
}
p->zText = zText;
|
| ︙ | ︙ | |||
33030 33031 33032 33033 33034 33035 33036 |
if( pItem->fg.jointype & JT_LTORJ ){
sqlite3_str_appendf(&x, " LTORJ");
}
if( pItem->fg.fromDDL ){
sqlite3_str_appendf(&x, " DDL");
}
if( pItem->fg.isCte ){
| > | > > | 33179 33180 33181 33182 33183 33184 33185 33186 33187 33188 33189 33190 33191 33192 33193 33194 33195 33196 |
if( pItem->fg.jointype & JT_LTORJ ){
sqlite3_str_appendf(&x, " LTORJ");
}
if( pItem->fg.fromDDL ){
sqlite3_str_appendf(&x, " DDL");
}
if( pItem->fg.isCte ){
static const char *aMat[] = {",MAT", "", ",NO-MAT"};
sqlite3_str_appendf(&x, " CteUse=%d%s",
pItem->u2.pCteUse->nUse,
aMat[pItem->u2.pCteUse->eM10d]);
}
if( pItem->fg.isOn || (pItem->fg.isUsing==0 && pItem->u3.pOn!=0) ){
sqlite3_str_appendf(&x, " isOn");
}
if( pItem->fg.isTabFunc ) sqlite3_str_appendf(&x, " isTabFunc");
if( pItem->fg.isCorrelated ) sqlite3_str_appendf(&x, " isCorrelated");
if( pItem->fg.isMaterialized ) sqlite3_str_appendf(&x, " isMaterialized");
|
| ︙ | ︙ | |||
33061 33062 33063 33064 33065 33066 33067 |
if( pItem->fg.isSubquery ){
assert( n==1 );
if( pItem->pSTab ){
Table *pTab = pItem->pSTab;
sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1);
}
assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) );
| < < < | 33213 33214 33215 33216 33217 33218 33219 33220 33221 33222 33223 33224 33225 33226 |
if( pItem->fg.isSubquery ){
assert( n==1 );
if( pItem->pSTab ){
Table *pTab = pItem->pSTab;
sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1);
}
assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem) );
sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0);
}
if( pItem->fg.isTabFunc ){
sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
}
sqlite3TreeViewPop(&pView);
}
|
| ︙ | ︙ | |||
33793 33794 33795 33796 33797 33798 33799 |
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; i<pList->nId; i++){
char *zName = pList->a[i].zName;
int moreToFollow = i<pList->nId - 1;
if( zName==0 ) zName = "(null)";
sqlite3TreeViewPush(&pView, moreToFollow);
sqlite3TreeViewLine(pView, 0);
| < | < < < < < < < < < < < < < | 33942 33943 33944 33945 33946 33947 33948 33949 33950 33951 33952 33953 33954 33955 33956 |
sqlite3TreeViewLine(pView, "%s", zLabel);
for(i=0; i<pList->nId; i++){
char *zName = pList->a[i].zName;
int moreToFollow = i<pList->nId - 1;
if( zName==0 ) zName = "(null)";
sqlite3TreeViewPush(&pView, moreToFollow);
sqlite3TreeViewLine(pView, 0);
fprintf(stdout, "%s\n", zName);
sqlite3TreeViewPop(&pView);
}
}
}
SQLITE_PRIVATE void sqlite3TreeViewIdList(
TreeView *pView,
const IdList *pList,
|
| ︙ | ︙ | |||
36288 36289 36290 36291 36292 36293 36294 |
j--;
}
}
}
}
p->z = &p->zBuf[i+1];
assert( i+p->n < sizeof(p->zBuf) );
| > | > > > | 36423 36424 36425 36426 36427 36428 36429 36430 36431 36432 36433 36434 36435 36436 36437 36438 36439 36440 36441 |
j--;
}
}
}
}
p->z = &p->zBuf[i+1];
assert( i+p->n < sizeof(p->zBuf) );
assert( p->n>0 );
while( p->z[p->n-1]=='0' ){
p->n--;
assert( p->n>0 );
}
}
/*
** Try to convert z into an unsigned 32-bit integer. Return true on
** success and false if there is an error.
**
** Only decimal notation is accepted.
|
| ︙ | ︙ | |||
37074 37075 37076 37077 37078 37079 37080 |
}
/*
** The hashing function.
*/
static unsigned int strHash(const char *z){
unsigned int h = 0;
| < | | > > > > > | > > > | 37213 37214 37215 37216 37217 37218 37219 37220 37221 37222 37223 37224 37225 37226 37227 37228 37229 37230 37231 37232 37233 37234 37235 37236 37237 37238 37239 |
}
/*
** The hashing function.
*/
static unsigned int strHash(const char *z){
unsigned int h = 0;
while( z[0] ){ /*OPTIMIZATION-IF-TRUE*/
/* Knuth multiplicative hashing. (Sorting & Searching, p. 510).
** 0x9e3779b1 is 2654435761 which is the closest prime number to
** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2.
**
** Only bits 0xdf for ASCII and bits 0xbf for EBCDIC each octet are
** hashed since the omitted bits determine the upper/lower case difference.
*/
#ifdef SQLITE_EBCDIC
h += 0xbf & (unsigned char)*(z++);
#else
h += 0xdf & (unsigned char)*(z++);
#endif
h *= 0x9e3779b1;
}
return h;
}
/* Link pNew element into the hash table pH. If pEntry!=0 then also
|
| ︙ | ︙ | |||
37152 37153 37154 37155 37156 37157 37158 |
if( new_ht==0 ) return 0;
sqlite3_free(pH->ht);
pH->ht = new_ht;
pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht);
memset(new_ht, 0, new_size*sizeof(struct _ht));
for(elem=pH->first, pH->first=0; elem; elem = next_elem){
| < | | > < | < | | | < | | 37298 37299 37300 37301 37302 37303 37304 37305 37306 37307 37308 37309 37310 37311 37312 37313 37314 37315 37316 37317 37318 37319 37320 37321 37322 37323 37324 37325 37326 37327 37328 37329 37330 37331 37332 37333 37334 37335 37336 37337 37338 37339 37340 37341 37342 37343 37344 37345 37346 37347 37348 37349 37350 37351 37352 37353 37354 37355 37356 37357 37358 37359 37360 37361 37362 37363 37364 37365 37366 37367 37368 37369 37370 37371 37372 |
if( new_ht==0 ) return 0;
sqlite3_free(pH->ht);
pH->ht = new_ht;
pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht);
memset(new_ht, 0, new_size*sizeof(struct _ht));
for(elem=pH->first, pH->first=0; elem; elem = next_elem){
next_elem = elem->next;
insertElement(pH, &new_ht[elem->h % new_size], elem);
}
return 1;
}
/* This function (for internal use only) locates an element in an
** hash table that matches the given key. If no element is found,
** a pointer to a static null element with HashElem.data==0 is returned.
** If pH is not NULL, then the hash for this key is written to *pH.
*/
static HashElem *findElementWithHash(
const Hash *pH, /* The pH to be searched */
const char *pKey, /* The key we are searching for */
unsigned int *pHash /* Write the hash value here */
){
HashElem *elem; /* Used to loop thru the element list */
unsigned int count; /* Number of elements left to test */
unsigned int h; /* The computed hash */
static HashElem nullElement = { 0, 0, 0, 0, 0 };
h = strHash(pKey);
if( pH->ht ){ /*OPTIMIZATION-IF-TRUE*/
struct _ht *pEntry;
pEntry = &pH->ht[h % pH->htsize];
elem = pEntry->chain;
count = pEntry->count;
}else{
elem = pH->first;
count = pH->count;
}
if( pHash ) *pHash = h;
while( count ){
assert( elem!=0 );
if( h==elem->h && sqlite3StrICmp(elem->pKey,pKey)==0 ){
return elem;
}
elem = elem->next;
count--;
}
return &nullElement;
}
/* Remove a single entry from the hash table given a pointer to that
** element and a hash on the element's key.
*/
static void removeElement(
Hash *pH, /* The pH containing "elem" */
HashElem *elem /* The element to be removed from the pH */
){
struct _ht *pEntry;
if( elem->prev ){
elem->prev->next = elem->next;
}else{
pH->first = elem->next;
}
if( elem->next ){
elem->next->prev = elem->prev;
}
if( pH->ht ){
pEntry = &pH->ht[elem->h % pH->htsize];
if( pEntry->chain==elem ){
pEntry->chain = elem->next;
}
assert( pEntry->count>0 );
pEntry->count--;
}
sqlite3_free( elem );
|
| ︙ | ︙ | |||
37266 37267 37268 37269 37270 37271 37272 |
assert( pH!=0 );
assert( pKey!=0 );
elem = findElementWithHash(pH,pKey,&h);
if( elem->data ){
void *old_data = elem->data;
if( data==0 ){
| | > | | < < | < | | 37409 37410 37411 37412 37413 37414 37415 37416 37417 37418 37419 37420 37421 37422 37423 37424 37425 37426 37427 37428 37429 37430 37431 37432 37433 37434 37435 37436 37437 37438 37439 37440 |
assert( pH!=0 );
assert( pKey!=0 );
elem = findElementWithHash(pH,pKey,&h);
if( elem->data ){
void *old_data = elem->data;
if( data==0 ){
removeElement(pH,elem);
}else{
elem->data = data;
elem->pKey = pKey;
}
return old_data;
}
if( data==0 ) return 0;
new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) );
if( new_elem==0 ) return data;
new_elem->pKey = pKey;
new_elem->h = h;
new_elem->data = data;
pH->count++;
if( pH->count>=5 && pH->count > 2*pH->htsize ){
rehash(pH, pH->count*3);
}
insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem);
return 0;
}
/************** End of hash.c ************************************************/
/************** Begin file opcodes.c *****************************************/
/* Automatically generated. Do not edit */
/* See the tool/mkopcodec.tcl script for details. */
|
| ︙ | ︙ | |||
40148 40149 40150 40151 40152 40153 40154 |
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;
| | | 40289 40290 40291 40292 40293 40294 40295 40296 40297 40298 40299 40300 40301 40302 40303 |
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;
|
| ︙ | ︙ | |||
50696 50697 50698 50699 50700 50701 50702 | /* Allocate space for the new sqlite3_shm object. Also speculatively ** allocate space for a new winShmNode and filename. */ p = sqlite3MallocZero( sizeof(*p) ); if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; nName = sqlite3Strlen30(pDbFd->zPath); | | | 50837 50838 50839 50840 50841 50842 50843 50844 50845 50846 50847 50848 50849 50850 50851 |
/* Allocate space for the new sqlite3_shm object. Also speculatively
** allocate space for a new winShmNode and filename.
*/
p = sqlite3MallocZero( sizeof(*p) );
if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT;
nName = sqlite3Strlen30(pDbFd->zPath);
pNew = sqlite3MallocZero( sizeof(*pShmNode) + (i64)nName + 17 );
if( pNew==0 ){
sqlite3_free(p);
return SQLITE_IOERR_NOMEM_BKPT;
}
pNew->zFilename = (char*)&pNew[1];
sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
|
| ︙ | ︙ | |||
51517 51518 51519 51520 51521 51522 51523 |
static char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
size_t i, j;
DWORD pid;
int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
| | | > | 51658 51659 51660 51661 51662 51663 51664 51665 51666 51667 51668 51669 51670 51671 51672 51673 51674 51675 51676 51677 51678 51679 51680 51681 51682 51683 51684 51685 |
static char zChars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789";
size_t i, j;
DWORD pid;
int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
i64 nMax, nBuf, nDir, nLen;
char *zBuf;
/* It's odd to simulate an io-error here, but really this is just
** using the io-error infrastructure to test that SQLite handles this
** function failing.
*/
SimulateIOError( return SQLITE_IOERR );
/* Allocate a temporary buffer to store the fully qualified file
** name for the temporary file. If this fails, we cannot continue.
*/
nMax = pVfs->mxPathname;
nBuf = 2 + (i64)nMax;
zBuf = sqlite3MallocZero( nBuf );
if( !zBuf ){
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
return SQLITE_IOERR_NOMEM_BKPT;
}
/* Figure out the effective temporary directory. First, check if one
|
| ︙ | ︙ | |||
52388 52389 52390 52391 52392 52393 52394 |
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
** NOTE: We are dealing with a relative path name and the data
** directory has been set. Therefore, use it as the basis
** for converting the relative path name to an absolute
** one by prepending the data directory and a slash.
*/
| | | 52530 52531 52532 52533 52534 52535 52536 52537 52538 52539 52540 52541 52542 52543 52544 |
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
/*
** NOTE: We are dealing with a relative path name and the data
** directory has been set. Therefore, use it as the basis
** for converting the relative path name to an absolute
** one by prepending the data directory and a slash.
*/
char *zOut = sqlite3MallocZero( 1+(u64)pVfs->mxPathname );
if( !zOut ){
return SQLITE_IOERR_NOMEM_BKPT;
}
if( cygwin_conv_path(
(osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){
sqlite3_free(zOut);
|
| ︙ | ︙ | |||
52483 52484 52485 52486 52487 52488 52489 |
LPWSTR zTemp;
nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
if( nByte==0 ){
sqlite3_free(zConverted);
return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
"winFullPathname1", zRelative);
}
| < | | < | | | 52625 52626 52627 52628 52629 52630 52631 52632 52633 52634 52635 52636 52637 52638 52639 52640 52641 52642 52643 52644 52645 52646 52647 52648 52649 52650 52651 52652 52653 52654 52655 52656 52657 52658 52659 52660 52661 52662 52663 52664 52665 52666 52667 52668 52669 |
LPWSTR zTemp;
nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
if( nByte==0 ){
sqlite3_free(zConverted);
return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
"winFullPathname1", zRelative);
}
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) + 3*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
return SQLITE_IOERR_NOMEM_BKPT;
}
nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte+3, zTemp, 0);
if( nByte==0 ){
sqlite3_free(zConverted);
sqlite3_free(zTemp);
return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
"winFullPathname2", zRelative);
}
sqlite3_free(zConverted);
zOut = winUnicodeToUtf8(zTemp);
sqlite3_free(zTemp);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
char *zTemp;
nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
if( nByte==0 ){
sqlite3_free(zConverted);
return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
"winFullPathname3", zRelative);
}
zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) + 3*sizeof(zTemp[0]) );
if( zTemp==0 ){
sqlite3_free(zConverted);
return SQLITE_IOERR_NOMEM_BKPT;
}
nByte = osGetFullPathNameA((char*)zConverted, nByte+3, zTemp, 0);
if( nByte==0 ){
sqlite3_free(zConverted);
sqlite3_free(zTemp);
return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
"winFullPathname4", zRelative);
}
sqlite3_free(zConverted);
|
| ︙ | ︙ | |||
53544 53545 53546 53547 53548 53549 53550 |
if( strcmp(memdb_g.apMemStore[i]->zFName,zName)==0 ){
p = memdb_g.apMemStore[i];
break;
}
}
if( p==0 ){
MemStore **apNew;
| | | | 53684 53685 53686 53687 53688 53689 53690 53691 53692 53693 53694 53695 53696 53697 53698 53699 53700 53701 53702 53703 53704 |
if( strcmp(memdb_g.apMemStore[i]->zFName,zName)==0 ){
p = memdb_g.apMemStore[i];
break;
}
}
if( p==0 ){
MemStore **apNew;
p = sqlite3Malloc( sizeof(*p) + (i64)szName + 3 );
if( p==0 ){
sqlite3_mutex_leave(pVfsMutex);
return SQLITE_NOMEM;
}
apNew = sqlite3Realloc(memdb_g.apMemStore,
sizeof(apNew[0])*(1+(i64)memdb_g.nMemStore) );
if( apNew==0 ){
sqlite3_free(p);
sqlite3_mutex_leave(pVfsMutex);
return SQLITE_NOMEM;
}
apNew[memdb_g.nMemStore++] = p;
memdb_g.apMemStore = apNew;
|
| ︙ | ︙ | |||
54260 54261 54262 54263 54264 54265 54266 | int rc = -1; int i, nx, pc, op; void *pTmpSpace; /* Allocate the Bitvec to be tested and a linear array of ** bits to act as the reference */ pBitvec = sqlite3BitvecCreate( sz ); | | | 54400 54401 54402 54403 54404 54405 54406 54407 54408 54409 54410 54411 54412 54413 54414 | int rc = -1; int i, nx, pc, op; void *pTmpSpace; /* Allocate the Bitvec to be tested and a linear array of ** bits to act as the reference */ pBitvec = sqlite3BitvecCreate( sz ); pV = sqlite3MallocZero( (7+(i64)sz)/8 + 1 ); pTmpSpace = sqlite3_malloc64(BITVEC_SZ); if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; /* NULL pBitvec tests */ sqlite3BitvecSet(0, 1); sqlite3BitvecClear(0, 1, pTmpSpace); |
| ︙ | ︙ | |||
55807 55808 55809 55810 55811 55812 55813 |
** This function is used to resize the hash table used by the cache passed
** as the first argument.
**
** The PCache mutex must be held when this function is called.
*/
static void pcache1ResizeHash(PCache1 *p){
PgHdr1 **apNew;
| | | | | 55947 55948 55949 55950 55951 55952 55953 55954 55955 55956 55957 55958 55959 55960 55961 55962 55963 55964 55965 55966 |
** This function is used to resize the hash table used by the cache passed
** as the first argument.
**
** The PCache mutex must be held when this function is called.
*/
static void pcache1ResizeHash(PCache1 *p){
PgHdr1 **apNew;
u64 nNew;
u32 i;
assert( sqlite3_mutex_held(p->pGroup->mutex) );
nNew = 2*(u64)p->nHash;
if( nNew<256 ){
nNew = 256;
}
pcache1LeaveMutex(p->pGroup);
if( p->nHash ){ sqlite3BeginBenignMalloc(); }
apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);
|
| ︙ | ︙ | |||
56035 56036 56037 56038 56039 56040 56041 |
** Implementation of the sqlite3_pcache.xCreate method.
**
** Allocate a new cache.
*/
static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
PCache1 *pCache; /* The newly created page cache */
PGroup *pGroup; /* The group the new page cache will belong to */
| | | 56175 56176 56177 56178 56179 56180 56181 56182 56183 56184 56185 56186 56187 56188 56189 |
** Implementation of the sqlite3_pcache.xCreate method.
**
** Allocate a new cache.
*/
static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
PCache1 *pCache; /* The newly created page cache */
PGroup *pGroup; /* The group the new page cache will belong to */
i64 sz; /* Bytes of memory required to allocate the new cache */
assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
assert( szExtra < 300 );
sz = sizeof(PCache1) + sizeof(PGroup)*pcache1.separateCache;
pCache = (PCache1 *)sqlite3MallocZero(sz);
if( pCache ){
|
| ︙ | ︙ | |||
58012 58013 58014 58015 58016 58017 58018 | */ #if SQLITE_MAX_MMAP_SIZE>0 # define USEFETCH(x) ((x)->bUseFetch) #else # define USEFETCH(x) 0 #endif | < < < < < < < < < < < < < < | | 58152 58153 58154 58155 58156 58157 58158 58159 58160 58161 58162 58163 58164 58165 58166 58167 58168 58169 58170 58171 58172 58173 58174 58175 58176 58177 58178 58179 58180 58181 58182 58183 58184 58185 |
*/
#if SQLITE_MAX_MMAP_SIZE>0
# define USEFETCH(x) ((x)->bUseFetch)
#else
# define USEFETCH(x) 0
#endif
#ifdef SQLITE_DIRECT_OVERFLOW_READ
/*
** Return true if page pgno can be read directly from the database file
** by the b-tree layer. This is the case if:
**
** (1) the database file is open
** (2) the VFS for the database is able to do unaligned sub-page reads
** (3) there are no dirty pages in the cache, and
** (4) the desired page is not currently in the wal file.
*/
SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){
assert( pPager!=0 );
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) */
}
|
| ︙ | ︙ | |||
58528 58529 58530 58531 58532 58533 58534 | ** ** If it is determined that no super-journal file name is present ** zSuper[0] is set to 0 and SQLITE_OK returned. ** ** If an error occurs while reading from the journal file, an SQLite ** error code is returned. */ | | | 58654 58655 58656 58657 58658 58659 58660 58661 58662 58663 58664 58665 58666 58667 58668 |
**
** If it is determined that no super-journal file name is present
** zSuper[0] is set to 0 and SQLITE_OK returned.
**
** If an error occurs while reading from the journal file, an SQLite
** error code is returned.
*/
static int readSuperJournal(sqlite3_file *pJrnl, char *zSuper, u64 nSuper){
int rc; /* Return code */
u32 len; /* Length in bytes of super-journal name */
i64 szJ; /* Total size in bytes of journal file pJrnl */
u32 cksum; /* MJ checksum value read from journal */
u32 u; /* Unsigned loop counter */
unsigned char aMagic[8]; /* A buffer to hold the magic header */
zSuper[0] = '\0';
|
| ︙ | ︙ | |||
59311 59312 59313 59314 59315 59316 59317 |
** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
*/
rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
}
}
pPager->journalOff = 0;
}else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
| | | 59437 59438 59439 59440 59441 59442 59443 59444 59445 59446 59447 59448 59449 59450 59451 |
** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
*/
rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
}
}
pPager->journalOff = 0;
}else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
|| (pPager->exclusiveMode && pPager->journalMode<PAGER_JOURNALMODE_WAL)
){
rc = zeroJournalHdr(pPager, hasSuper||pPager->tempFile);
pPager->journalOff = 0;
}else{
/* This branch may be executed with Pager.journalMode==MEMORY if
** a hot-journal was just rolled back. In this case the journal
** file should be closed and deleted. If this connection writes to
|
| ︙ | ︙ | |||
59764 59765 59766 59767 59768 59769 59770 | sqlite3_file *pSuper; /* Malloc'd super-journal file descriptor */ sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ char *zSuperJournal = 0; /* Contents of super-journal file */ i64 nSuperJournal; /* Size of super-journal file */ char *zJournal; /* Pointer to one journal within MJ file */ char *zSuperPtr; /* Space to hold super-journal filename */ char *zFree = 0; /* Free this buffer */ | | | | > > > | 59890 59891 59892 59893 59894 59895 59896 59897 59898 59899 59900 59901 59902 59903 59904 59905 59906 59907 59908 59909 59910 59911 59912 59913 59914 59915 59916 59917 59918 59919 59920 59921 59922 59923 59924 59925 59926 59927 59928 59929 59930 59931 59932 59933 59934 |
sqlite3_file *pSuper; /* Malloc'd super-journal file descriptor */
sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */
char *zSuperJournal = 0; /* Contents of super-journal file */
i64 nSuperJournal; /* Size of super-journal file */
char *zJournal; /* Pointer to one journal within MJ file */
char *zSuperPtr; /* Space to hold super-journal filename */
char *zFree = 0; /* Free this buffer */
i64 nSuperPtr; /* Amount of space allocated to zSuperPtr[] */
/* Allocate space for both the pJournal and pSuper file descriptors.
** If successful, open the super-journal file for reading.
*/
pSuper = (sqlite3_file *)sqlite3MallocZero(2 * (i64)pVfs->szOsFile);
if( !pSuper ){
rc = SQLITE_NOMEM_BKPT;
pJournal = 0;
}else{
const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_SUPER_JOURNAL);
rc = sqlite3OsOpen(pVfs, zSuper, pSuper, flags, 0);
pJournal = (sqlite3_file *)(((u8 *)pSuper) + pVfs->szOsFile);
}
if( rc!=SQLITE_OK ) goto delsuper_out;
/* Load the entire super-journal file into space obtained from
** sqlite3_malloc() and pointed to by zSuperJournal. Also obtain
** sufficient space (in zSuperPtr) to hold the names of super-journal
** files extracted from regular rollback-journals.
*/
rc = sqlite3OsFileSize(pSuper, &nSuperJournal);
if( rc!=SQLITE_OK ) goto delsuper_out;
nSuperPtr = 1 + (i64)pVfs->mxPathname;
assert( nSuperJournal>=0 && nSuperPtr>0 );
zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2);
if( !zFree ){
rc = SQLITE_NOMEM_BKPT;
goto delsuper_out;
}else{
assert( nSuperJournal<=0x7fffffff );
}
zFree[0] = zFree[1] = zFree[2] = zFree[3] = 0;
zSuperJournal = &zFree[4];
zSuperPtr = &zSuperJournal[nSuperJournal+2];
rc = sqlite3OsRead(pSuper, zSuperJournal, (int)nSuperJournal, 0);
if( rc!=SQLITE_OK ) goto delsuper_out;
zSuperJournal[nSuperJournal] = 0;
|
| ︙ | ︙ | |||
60052 60053 60054 60055 60056 60057 60058 | ** TODO: Technically the following is an error because it assumes that ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c, ** mxPathname is 512, which is the same as the minimum allowable value ** for pageSize. */ zSuper = pPager->pTmpSpace; | | | 60181 60182 60183 60184 60185 60186 60187 60188 60189 60190 60191 60192 60193 60194 60195 |
** TODO: Technically the following is an error because it assumes that
** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
** mxPathname is 512, which is the same as the minimum allowable value
** for pageSize.
*/
zSuper = pPager->pTmpSpace;
rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname);
if( rc==SQLITE_OK && zSuper[0] ){
rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res);
}
zSuper = 0;
if( rc!=SQLITE_OK || !res ){
goto end_playback;
}
|
| ︙ | ︙ | |||
60191 60192 60193 60194 60195 60196 60197 |
if( rc==SQLITE_OK ){
/* Leave 4 bytes of space before the super-journal filename in memory.
** This is because it may end up being passed to sqlite3OsOpen(), in
** which case it requires 4 0x00 bytes in memory immediately before
** the filename. */
zSuper = &pPager->pTmpSpace[4];
| | | 60320 60321 60322 60323 60324 60325 60326 60327 60328 60329 60330 60331 60332 60333 60334 |
if( rc==SQLITE_OK ){
/* Leave 4 bytes of space before the super-journal filename in memory.
** This is because it may end up being passed to sqlite3OsOpen(), in
** which case it requires 4 0x00 bytes in memory immediately before
** the filename. */
zSuper = &pPager->pTmpSpace[4];
rc = readSuperJournal(pPager->jfd, zSuper, 1+(i64)pPager->pVfs->mxPathname);
testcase( rc!=SQLITE_OK );
}
if( rc==SQLITE_OK
&& (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
){
rc = sqlite3PagerSync(pPager, 0);
}
|
| ︙ | ︙ | |||
61961 61962 61963 61964 61965 61966 61967 61968 61969 61970 61971 61972 61973 61974 | char *zPathname = 0; /* Full path to database file */ int nPathname = 0; /* Number of bytes in zPathname */ int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ const char *zUri = 0; /* URI args to copy */ int nUriByte = 1; /* Number of bytes of URI args at *zUri */ /* Figure out how much space is required for each journal file-handle ** (there are two of them, the main journal and the sub-journal). */ journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); /* Set the output variable to NULL in case an error occurs. */ *ppPager = 0; | > | 62090 62091 62092 62093 62094 62095 62096 62097 62098 62099 62100 62101 62102 62103 62104 | char *zPathname = 0; /* Full path to database file */ int nPathname = 0; /* Number of bytes in zPathname */ int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ const char *zUri = 0; /* URI args to copy */ int nUriByte = 1; /* Number of bytes of URI args at *zUri */ /* Figure out how much space is required for each journal file-handle ** (there are two of them, the main journal and the sub-journal). */ journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); /* Set the output variable to NULL in case an error occurs. */ *ppPager = 0; |
| ︙ | ︙ | |||
61987 61988 61989 61990 61991 61992 61993 |
/* Compute and store the full pathname in an allocated buffer pointed
** to by zPathname, length nPathname. Or, if this is a temporary file,
** leave both nPathname and zPathname set to 0.
*/
if( zFilename && zFilename[0] ){
const char *z;
| | | | 62117 62118 62119 62120 62121 62122 62123 62124 62125 62126 62127 62128 62129 62130 62131 62132 |
/* Compute and store the full pathname in an allocated buffer pointed
** to by zPathname, length nPathname. Or, if this is a temporary file,
** leave both nPathname and zPathname set to 0.
*/
if( zFilename && zFilename[0] ){
const char *z;
nPathname = pVfs->mxPathname + 1;
zPathname = sqlite3DbMallocRaw(0, 2*(i64)nPathname);
if( zPathname==0 ){
return SQLITE_NOMEM_BKPT;
}
zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_OK_SYMLINK ){
|
| ︙ | ︙ | |||
62075 62076 62077 62078 62079 62080 62081 |
** changes here, be sure to change it there as well.
*/
assert( SQLITE_PTRSIZE==sizeof(Pager*) );
pPtr = (u8 *)sqlite3MallocZero(
ROUND8(sizeof(*pPager)) + /* Pager structure */
ROUND8(pcacheSize) + /* PCache object */
ROUND8(pVfs->szOsFile) + /* The main db file */
| | | | | | | 62205 62206 62207 62208 62209 62210 62211 62212 62213 62214 62215 62216 62217 62218 62219 62220 62221 62222 62223 62224 62225 62226 |
** changes here, be sure to change it there as well.
*/
assert( SQLITE_PTRSIZE==sizeof(Pager*) );
pPtr = (u8 *)sqlite3MallocZero(
ROUND8(sizeof(*pPager)) + /* Pager structure */
ROUND8(pcacheSize) + /* PCache object */
ROUND8(pVfs->szOsFile) + /* The main db file */
(u64)journalFileSize * 2 + /* The two journal files */
SQLITE_PTRSIZE + /* Space to hold a pointer */
4 + /* Database prefix */
(u64)nPathname + 1 + /* database filename */
(u64)nUriByte + /* query parameters */
(u64)nPathname + 8 + 1 + /* Journal filename */
#ifndef SQLITE_OMIT_WAL
(u64)nPathname + 4 + 1 + /* WAL filename */
#endif
3 /* Terminator */
);
assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
if( !pPtr ){
sqlite3DbFree(0, zPathname);
return SQLITE_NOMEM_BKPT;
|
| ︙ | ︙ | |||
65788 65789 65790 65791 65792 65793 65794 |
int iPage, /* The page we seek */
volatile u32 **ppPage /* Write the page pointer here */
){
int rc = SQLITE_OK;
/* Enlarge the pWal->apWiData[] array if required */
if( pWal->nWiData<=iPage ){
| | | 65918 65919 65920 65921 65922 65923 65924 65925 65926 65927 65928 65929 65930 65931 65932 |
int iPage, /* The page we seek */
volatile u32 **ppPage /* Write the page pointer here */
){
int rc = SQLITE_OK;
/* Enlarge the pWal->apWiData[] array if required */
if( pWal->nWiData<=iPage ){
sqlite3_int64 nByte = sizeof(u32*)*(1+(i64)iPage);
volatile u32 **apNew;
apNew = (volatile u32 **)sqlite3Realloc((void *)pWal->apWiData, nByte);
if( !apNew ){
*ppPage = 0;
return SQLITE_NOMEM_BKPT;
}
memset((void*)&apNew[pWal->nWiData], 0,
|
| ︙ | ︙ | |||
68021 68022 68023 68024 68025 68026 68027 |
** checkpoint process do as much work as possible. This routine might
** update values of the aReadMark[] array in the header, but if it does
** so it takes care to hold an exclusive lock on the corresponding
** WAL_READ_LOCK() while changing values.
*/
static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){
volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */
| < < < < | 68151 68152 68153 68154 68155 68156 68157 68158 68159 68160 68161 68162 68163 68164 68165 |
** checkpoint process do as much work as possible. This routine might
** update values of the aReadMark[] array in the header, but if it does
** so it takes care to hold an exclusive lock on the corresponding
** WAL_READ_LOCK() while changing values.
*/
static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){
volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */
int rc = SQLITE_OK; /* Return code */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
int nBlockTmout = 0;
#endif
assert( pWal->readLock<0 ); /* Not currently locked */
/* useWal may only be set for read/write connections */
|
| ︙ | ︙ | |||
68131 68132 68133 68134 68135 68136 68137 |
}
}
assert( pWal->nWiData>0 );
assert( pWal->apWiData[0]!=0 );
pInfo = walCkptInfo(pWal);
SEH_INJECT_FAULT;
| > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | 68257 68258 68259 68260 68261 68262 68263 68264 68265 68266 68267 68268 68269 68270 68271 68272 68273 68274 68275 68276 68277 68278 68279 68280 68281 68282 68283 68284 68285 68286 68287 68288 68289 68290 68291 68292 68293 68294 68295 68296 68297 68298 68299 68300 68301 68302 68303 68304 68305 68306 68307 68308 68309 68310 68311 68312 68313 68314 68315 68316 68317 68318 68319 68320 68321 68322 68323 68324 68325 68326 68327 68328 68329 68330 68331 68332 68333 68334 68335 68336 68337 68338 68339 68340 68341 68342 68343 68344 68345 68346 68347 68348 68349 68350 68351 68352 68353 68354 68355 68356 68357 68358 68359 68360 68361 68362 68363 68364 68365 68366 68367 68368 68369 68370 68371 68372 68373 68374 68375 68376 68377 68378 68379 68380 68381 68382 68383 68384 68385 68386 68387 68388 68389 68390 68391 68392 68393 68394 68395 68396 68397 68398 68399 68400 68401 68402 68403 68404 68405 68406 68407 68408 68409 68410 68411 |
}
}
assert( pWal->nWiData>0 );
assert( pWal->apWiData[0]!=0 );
pInfo = walCkptInfo(pWal);
SEH_INJECT_FAULT;
{
u32 mxReadMark; /* Largest aReadMark[] value */
int mxI; /* Index of largest aReadMark[] value */
int i; /* Loop counter */
u32 mxFrame; /* Wal frame to lock to */
if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame
#ifdef SQLITE_ENABLE_SNAPSHOT
&& ((pWal->bGetSnapshot==0 && pWal->pSnapshot==0) || pWal->hdr.mxFrame==0)
#endif
){
/* The WAL has been completely backfilled (or it is empty).
** and can be safely ignored.
*/
rc = walLockShared(pWal, WAL_READ_LOCK(0));
walShmBarrier(pWal);
if( rc==SQLITE_OK ){
if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr,sizeof(WalIndexHdr)) ){
/* It is not safe to allow the reader to continue here if frames
** may have been appended to the log before READ_LOCK(0) was obtained.
** When holding READ_LOCK(0), the reader ignores the entire log file,
** which implies that the database file contains a trustworthy
** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from
** happening, this is usually correct.
**
** However, if frames have been appended to the log (or if the log
** is wrapped and written for that matter) before the READ_LOCK(0)
** is obtained, that is not necessarily true. A checkpointer may
** have started to backfill the appended frames but crashed before
** it finished. Leaving a corrupt image in the database file.
*/
walUnlockShared(pWal, WAL_READ_LOCK(0));
return WAL_RETRY;
}
pWal->readLock = 0;
return SQLITE_OK;
}else if( rc!=SQLITE_BUSY ){
return rc;
}
}
/* If we get this far, it means that the reader will want to use
** the WAL to get at content from recent commits. The job now is
** to select one of the aReadMark[] entries that is closest to
** but not exceeding pWal->hdr.mxFrame and lock that entry.
*/
mxReadMark = 0;
mxI = 0;
mxFrame = pWal->hdr.mxFrame;
#ifdef SQLITE_ENABLE_SNAPSHOT
if( pWal->pSnapshot && pWal->pSnapshot->mxFrame<mxFrame ){
mxFrame = pWal->pSnapshot->mxFrame;
}
#endif
for(i=1; i<WAL_NREADER; i++){
u32 thisMark = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT;
if( mxReadMark<=thisMark && thisMark<=mxFrame ){
assert( thisMark!=READMARK_NOT_USED );
mxReadMark = thisMark;
mxI = i;
}
}
if( (pWal->readOnly & WAL_SHM_RDONLY)==0
&& (mxReadMark<mxFrame || mxI==0)
){
for(i=1; i<WAL_NREADER; i++){
rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
if( rc==SQLITE_OK ){
AtomicStore(pInfo->aReadMark+i,mxFrame);
mxReadMark = mxFrame;
mxI = i;
walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
break;
}else if( rc!=SQLITE_BUSY ){
return rc;
}
}
}
if( mxI==0 ){
assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT;
}
(void)walEnableBlockingMs(pWal, nBlockTmout);
rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
walDisableBlocking(pWal);
if( rc ){
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ){
*pCnt |= WAL_RETRY_BLOCKED_MASK;
}
#else
assert( rc!=SQLITE_BUSY_TIMEOUT );
#endif
assert((rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT);
return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc;
}
/* Now that the read-lock has been obtained, check that neither the
** value in the aReadMark[] array or the contents of the wal-index
** header have changed.
**
** It is necessary to check that the wal-index header did not change
** between the time it was read and when the shared-lock was obtained
** on WAL_READ_LOCK(mxI) was obtained to account for the possibility
** that the log file may have been wrapped by a writer, or that frames
** that occur later in the log than pWal->hdr.mxFrame may have been
** copied into the database by a checkpointer. If either of these things
** happened, then reading the database with the current value of
** pWal->hdr.mxFrame risks reading a corrupted snapshot. So, retry
** instead.
**
** Before checking that the live wal-index header has not changed
** since it was read, set Wal.minFrame to the first frame in the wal
** file that has not yet been checkpointed. This client will not need
** to read any frames earlier than minFrame from the wal file - they
** can be safely read directly from the database file.
**
** Because a ShmBarrier() call is made between taking the copy of
** nBackfill and checking that the wal-header in shared-memory still
** matches the one cached in pWal->hdr, it is guaranteed that the
** checkpointer that set nBackfill was not working with a wal-index
** header newer than that cached in pWal->hdr. If it were, that could
** cause a problem. The checkpointer could omit to checkpoint
** a version of page X that lies before pWal->minFrame (call that version
** A) on the basis that there is a newer version (version B) of the same
** page later in the wal file. But if version B happens to like past
** frame pWal->hdr.mxFrame - then the client would incorrectly assume
** that it can read version A from the database file. However, since
** we can guarantee that the checkpointer that set nBackfill could not
** see any pages past pWal->hdr.mxFrame, this problem does not come up.
*/
pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT;
walShmBarrier(pWal);
if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark
|| memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
){
walUnlockShared(pWal, WAL_READ_LOCK(mxI));
return WAL_RETRY;
}else{
assert( mxReadMark<=pWal->hdr.mxFrame );
pWal->readLock = (i16)mxI;
}
}
return rc;
}
#ifdef SQLITE_ENABLE_SNAPSHOT
/*
** This function does the work of sqlite3WalSnapshotRecover().
|
| ︙ | ︙ | |||
71410 71411 71412 71413 71414 71415 71416 |
** that the current key is corrupt. In that case, it is possible that
** the sqlite3VdbeRecordUnpack() function may overread the buffer by
** up to the size of 1 varint plus 1 8-byte value when the cursor
** position is restored. Hence the 17 bytes of padding allocated
** below. */
void *pKey;
pCur->nKey = sqlite3BtreePayloadSize(pCur);
| | | 71542 71543 71544 71545 71546 71547 71548 71549 71550 71551 71552 71553 71554 71555 71556 |
** that the current key is corrupt. In that case, it is possible that
** the sqlite3VdbeRecordUnpack() function may overread the buffer by
** up to the size of 1 varint plus 1 8-byte value when the cursor
** position is restored. Hence the 17 bytes of padding allocated
** below. */
void *pKey;
pCur->nKey = sqlite3BtreePayloadSize(pCur);
pKey = sqlite3Malloc( ((i64)pCur->nKey) + 9 + 8 );
if( pKey ){
rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey);
if( rc==SQLITE_OK ){
memset(((u8*)pKey)+pCur->nKey, 0, 9+8);
pCur->pKey = pKey;
}else{
sqlite3_free(pKey);
|
| ︙ | ︙ | |||
76781 76782 76783 76784 76785 76786 76787 |
testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */
testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */
testcase( nCell==2 ); /* Minimum legal index key size */
if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){
rc = SQLITE_CORRUPT_PAGE(pPage);
goto moveto_index_finish;
}
| | | 76913 76914 76915 76916 76917 76918 76919 76920 76921 76922 76923 76924 76925 76926 76927 |
testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */
testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */
testcase( nCell==2 ); /* Minimum legal index key size */
if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){
rc = SQLITE_CORRUPT_PAGE(pPage);
goto moveto_index_finish;
}
pCellKey = sqlite3Malloc( (u64)nCell+(u64)nOverrun );
if( pCellKey==0 ){
rc = SQLITE_NOMEM_BKPT;
goto moveto_index_finish;
}
pCur->ix = (u16)idx;
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */
|
| ︙ | ︙ | |||
81970 81971 81972 81973 81974 81975 81976 81977 81978 81979 81980 81981 81982 81983 |
** Just before the shared-btree is closed, the function passed as the
** xFree argument when the memory allocation was made is invoked on the
** blob of allocated memory. The xFree function should not call sqlite3_free()
** on the memory, the btree layer does that.
*/
SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){
BtShared *pBt = p->pBt;
sqlite3BtreeEnter(p);
if( !pBt->pSchema && nBytes ){
pBt->pSchema = sqlite3DbMallocZero(0, nBytes);
pBt->xFreeSchema = xFree;
}
sqlite3BtreeLeave(p);
return pBt->pSchema;
| > | 82102 82103 82104 82105 82106 82107 82108 82109 82110 82111 82112 82113 82114 82115 82116 |
** Just before the shared-btree is closed, the function passed as the
** xFree argument when the memory allocation was made is invoked on the
** blob of allocated memory. The xFree function should not call sqlite3_free()
** on the memory, the btree layer does that.
*/
SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){
BtShared *pBt = p->pBt;
assert( nBytes==0 || nBytes==sizeof(Schema) );
sqlite3BtreeEnter(p);
if( !pBt->pSchema && nBytes ){
pBt->pSchema = sqlite3DbMallocZero(0, nBytes);
pBt->xFreeSchema = xFree;
}
sqlite3BtreeLeave(p);
return pBt->pSchema;
|
| ︙ | ︙ | |||
83272 83273 83274 83275 83276 83277 83278 |
*/
SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){
if( (pMem->flags & (MEM_Str|MEM_Term|MEM_Ephem|MEM_Static))!=MEM_Str ){
/* pMem must be a string, and it cannot be an ephemeral or static string */
return;
}
if( pMem->enc!=SQLITE_UTF8 ) return;
| | | 83405 83406 83407 83408 83409 83410 83411 83412 83413 83414 83415 83416 83417 83418 83419 |
*/
SQLITE_PRIVATE void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){
if( (pMem->flags & (MEM_Str|MEM_Term|MEM_Ephem|MEM_Static))!=MEM_Str ){
/* pMem must be a string, and it cannot be an ephemeral or static string */
return;
}
if( pMem->enc!=SQLITE_UTF8 ) return;
assert( pMem->z!=0 );
if( pMem->flags & MEM_Dyn ){
if( pMem->xDel==sqlite3_free
&& sqlite3_msize(pMem->z) >= (u64)(pMem->n+1)
){
pMem->z[pMem->n] = 0;
pMem->flags |= MEM_Term;
return;
|
| ︙ | ︙ | |||
83991 83992 83993 83994 83995 83996 83997 |
**
** This is used for testing and debugging only - to help ensure that shallow
** copies (created by OP_SCopy) are not misused.
*/
SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
int i;
Mem *pX;
| > | | | | | | | | | | | | | | | | | | | | > > | 84124 84125 84126 84127 84128 84129 84130 84131 84132 84133 84134 84135 84136 84137 84138 84139 84140 84141 84142 84143 84144 84145 84146 84147 84148 84149 84150 84151 84152 84153 84154 84155 84156 84157 84158 84159 84160 84161 |
**
** This is used for testing and debugging only - to help ensure that shallow
** copies (created by OP_SCopy) are not misused.
*/
SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
int i;
Mem *pX;
if( pMem->bScopy ){
for(i=1, pX=pVdbe->aMem+1; i<pVdbe->nMem; i++, pX++){
if( pX->pScopyFrom==pMem ){
u16 mFlags;
if( pVdbe->db->flags & SQLITE_VdbeTrace ){
sqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n",
(int)(pX - pVdbe->aMem), (int)(pMem - pVdbe->aMem));
}
/* If pX is marked as a shallow copy of pMem, then try to verify that
** no significant changes have been made to pX since the OP_SCopy.
** A significant change would indicated a missed call to this
** function for pX. Minor changes, such as adding or removing a
** dual type, are allowed, as long as the underlying value is the
** same. */
mFlags = pMem->flags & pX->flags & pX->mScopyFlags;
assert( (mFlags&(MEM_Int|MEM_IntReal))==0 || pMem->u.i==pX->u.i );
/* pMem is the register that is changing. But also mark pX as
** undefined so that we can quickly detect the shallow-copy error */
pX->flags = MEM_Undefined;
pX->pScopyFrom = 0;
}
}
pMem->bScopy = 0;
}
pMem->pScopyFrom = 0;
}
#endif /* SQLITE_DEBUG */
/*
** Make an shallow copy of pFrom into pTo. Prior contents of
|
| ︙ | ︙ | |||
84382 84383 84384 84385 84386 84387 84388 |
static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
#ifdef SQLITE_ENABLE_STAT4
if( p ){
UnpackedRecord *pRec = p->ppRec[0];
if( pRec==0 ){
Index *pIdx = p->pIdx; /* Index being probed */
| | | 84518 84519 84520 84521 84522 84523 84524 84525 84526 84527 84528 84529 84530 84531 84532 |
static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
#ifdef SQLITE_ENABLE_STAT4
if( p ){
UnpackedRecord *pRec = p->ppRec[0];
if( pRec==0 ){
Index *pIdx = p->pIdx; /* Index being probed */
i64 nByte; /* Bytes of space to allocate */
int i; /* Counter variable */
int nCol = pIdx->nColumn; /* Number of index columns including rowid */
nByte = sizeof(Mem) * nCol + ROUND8(sizeof(UnpackedRecord));
pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte);
if( pRec ){
pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx);
|
| ︙ | ︙ | |||
84448 84449 84450 84451 84452 84453 84454 |
u8 enc, /* Encoding to use */
u8 aff, /* Affinity to use */
sqlite3_value **ppVal, /* Write the new value here */
struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */
){
sqlite3_context ctx; /* Context object for function invocation */
sqlite3_value **apVal = 0; /* Function arguments */
| | | 84584 84585 84586 84587 84588 84589 84590 84591 84592 84593 84594 84595 84596 84597 84598 |
u8 enc, /* Encoding to use */
u8 aff, /* Affinity to use */
sqlite3_value **ppVal, /* Write the new value here */
struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */
){
sqlite3_context ctx; /* Context object for function invocation */
sqlite3_value **apVal = 0; /* Function arguments */
int nVal = 0; /* Number of function arguments */
FuncDef *pFunc = 0; /* Function definition */
sqlite3_value *pVal = 0; /* New value */
int rc = SQLITE_OK; /* Return code */
ExprList *pList = 0; /* Function arguments */
int i; /* Iterator variable */
assert( pCtx!=0 );
|
| ︙ | ︙ | |||
85727 85728 85729 85730 85731 85732 85733 |
p->iAddr++;
if( p->iAddr==nOp ){
p->iSub++;
p->iAddr = 0;
}
if( pRet->p4type==P4_SUBPROGRAM ){
| | | 85863 85864 85865 85866 85867 85868 85869 85870 85871 85872 85873 85874 85875 85876 85877 |
p->iAddr++;
if( p->iAddr==nOp ){
p->iSub++;
p->iAddr = 0;
}
if( pRet->p4type==P4_SUBPROGRAM ){
i64 nByte = (1+(u64)p->nSub)*sizeof(SubProgram*);
int j;
for(j=0; j<p->nSub; j++){
if( p->apSub[j]==pRet->p4.pProgram ) break;
}
if( j==p->nSub ){
p->apSub = sqlite3DbReallocOrFree(v->db, p->apSub, nByte);
if( !p->apSub ){
|
| ︙ | ︙ | |||
85857 85858 85859 85860 85861 85862 85863 | /* ** This routine is called after all opcodes have been inserted. It loops ** through all the opcodes and fixes up some details. ** ** (1) For each jump instruction with a negative P2 value (a label) ** resolve the P2 value to an actual address. ** | | | | | | 85993 85994 85995 85996 85997 85998 85999 86000 86001 86002 86003 86004 86005 86006 86007 86008 86009 86010 86011 86012 86013 86014 86015 86016 86017 86018 86019 86020 86021 86022 |
/*
** This routine is called after all opcodes have been inserted. It loops
** through all the opcodes and fixes up some details.
**
** (1) For each jump instruction with a negative P2 value (a label)
** resolve the P2 value to an actual address.
**
** (2) Compute the maximum number of arguments used by the xUpdate/xFilter
** methods of any virtual table and store that value in *pMaxVtabArgs.
**
** (3) Update the Vdbe.readOnly and Vdbe.bIsReader flags to accurately
** indicate what the prepared statement actually does.
**
** (4) (discontinued)
**
** (5) Reclaim the memory allocated for storing labels.
**
** This routine will only function correctly if the mkopcodeh.tcl generator
** script numbers the opcodes correctly. Changes to this routine must be
** coordinated with changes to mkopcodeh.tcl.
*/
static void resolveP2Values(Vdbe *p, int *pMaxVtabArgs){
int nMaxVtabArgs = *pMaxVtabArgs;
Op *pOp;
Parse *pParse = p->pParse;
int *aLabel = pParse->aLabel;
assert( pParse->db->mallocFailed==0 ); /* tag-20230419-1 */
p->readOnly = 1;
p->bIsReader = 0;
|
| ︙ | ︙ | |||
85917 85918 85919 85920 85921 85922 85923 |
}
case OP_Init: {
assert( pOp->p2>=0 );
goto resolve_p2_values_loop_exit;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
case OP_VUpdate: {
| | > > > > | | 86053 86054 86055 86056 86057 86058 86059 86060 86061 86062 86063 86064 86065 86066 86067 86068 86069 86070 86071 86072 86073 86074 86075 86076 86077 86078 86079 |
}
case OP_Init: {
assert( pOp->p2>=0 );
goto resolve_p2_values_loop_exit;
}
#ifndef SQLITE_OMIT_VIRTUALTABLE
case OP_VUpdate: {
if( pOp->p2>nMaxVtabArgs ) nMaxVtabArgs = pOp->p2;
break;
}
case OP_VFilter: {
int n;
/* The instruction immediately prior to VFilter will be an
** OP_Integer that sets the "argc" value for the VFilter. See
** the code where OP_VFilter is generated at tag-20250207a. */
assert( (pOp - p->aOp) >= 3 );
assert( pOp[-1].opcode==OP_Integer );
assert( pOp[-1].p2==pOp->p3+1 );
n = pOp[-1].p1;
if( n>nMaxVtabArgs ) nMaxVtabArgs = n;
/* Fall through into the default case */
/* no break */ deliberate_fall_through
}
#endif
default: {
if( pOp->p2<0 ){
/* The mkopcodeh.tcl script has so arranged things that the only
|
| ︙ | ︙ | |||
85966 85967 85968 85969 85970 85971 85972 |
}
resolve_p2_values_loop_exit:
if( aLabel ){
sqlite3DbNNFreeNN(p->db, pParse->aLabel);
pParse->aLabel = 0;
}
pParse->nLabel = 0;
| | | 86106 86107 86108 86109 86110 86111 86112 86113 86114 86115 86116 86117 86118 86119 86120 |
}
resolve_p2_values_loop_exit:
if( aLabel ){
sqlite3DbNNFreeNN(p->db, pParse->aLabel);
pParse->aLabel = 0;
}
pParse->nLabel = 0;
*pMaxVtabArgs = nMaxVtabArgs;
assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
}
#ifdef SQLITE_DEBUG
/*
** Check to see if a subroutine contains a jump to a location outside of
** the subroutine. If a jump outside the subroutine is detected, add code
|
| ︙ | ︙ | |||
86195 86196 86197 86198 86199 86200 86201 |
int addrExplain, /* Address of OP_Explain (or 0) */
int addrLoop, /* Address of loop counter */
int addrVisit, /* Address of rows visited counter */
LogEst nEst, /* Estimated number of output rows */
const char *zName /* Name of table or index being scanned */
){
if( IS_STMT_SCANSTATUS(p->db) ){
| | | 86335 86336 86337 86338 86339 86340 86341 86342 86343 86344 86345 86346 86347 86348 86349 |
int addrExplain, /* Address of OP_Explain (or 0) */
int addrLoop, /* Address of loop counter */
int addrVisit, /* Address of rows visited counter */
LogEst nEst, /* Estimated number of output rows */
const char *zName /* Name of table or index being scanned */
){
if( IS_STMT_SCANSTATUS(p->db) ){
i64 nByte = (1+(i64)p->nScan) * sizeof(ScanStatus);
ScanStatus *aNew;
aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
if( aNew ){
ScanStatus *pNew = &aNew[p->nScan++];
memset(pNew, 0, sizeof(ScanStatus));
pNew->addrExplain = addrExplain;
pNew->addrLoop = addrLoop;
|
| ︙ | ︙ | |||
87145 87146 87147 87148 87149 87150 87151 87152 87153 87154 87155 87156 87157 87158 87159 87160 87161 87162 87163 87164 87165 87166 87167 87168 87169 87170 87171 87172 87173 87174 87175 87176 87177 87178 87179 87180 87181 87182 87183 |
** Mem.db = db
** Mem.szMalloc = 0
**
** All other fields of Mem can safely remain uninitialized for now. They
** will be initialized before use.
*/
static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
if( N>0 ){
do{
p->flags = flags;
p->db = db;
p->szMalloc = 0;
#ifdef SQLITE_DEBUG
p->pScopyFrom = 0;
#endif
p++;
}while( (--N)>0 );
}
}
/*
** Release auxiliary memory held in an array of N Mem elements.
**
** After this routine returns, all Mem elements in the array will still
** be valid. Those Mem elements that were not holding auxiliary resources
** will be unchanged. Mem elements which had something freed will be
** set to MEM_Undefined.
*/
static void releaseMemArray(Mem *p, int N){
if( p && N ){
Mem *pEnd = &p[N];
sqlite3 *db = p->db;
if( db->pnBytesFreed ){
do{
if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
}while( (++p)<pEnd );
return;
}
do{
| > > > | 87285 87286 87287 87288 87289 87290 87291 87292 87293 87294 87295 87296 87297 87298 87299 87300 87301 87302 87303 87304 87305 87306 87307 87308 87309 87310 87311 87312 87313 87314 87315 87316 87317 87318 87319 87320 87321 87322 87323 87324 87325 87326 |
** Mem.db = db
** Mem.szMalloc = 0
**
** All other fields of Mem can safely remain uninitialized for now. They
** will be initialized before use.
*/
static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){
assert( db!=0 );
if( N>0 ){
do{
p->flags = flags;
p->db = db;
p->szMalloc = 0;
#ifdef SQLITE_DEBUG
p->pScopyFrom = 0;
p->bScopy = 0;
#endif
p++;
}while( (--N)>0 );
}
}
/*
** Release auxiliary memory held in an array of N Mem elements.
**
** After this routine returns, all Mem elements in the array will still
** be valid. Those Mem elements that were not holding auxiliary resources
** will be unchanged. Mem elements which had something freed will be
** set to MEM_Undefined.
*/
static void releaseMemArray(Mem *p, int N){
if( p && N ){
Mem *pEnd = &p[N];
sqlite3 *db = p->db;
assert( db!=0 );
if( db->pnBytesFreed ){
do{
if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
}while( (++p)<pEnd );
return;
}
do{
|
| ︙ | ︙ | |||
87641 87642 87643 87644 87645 87646 87647 |
Vdbe *p, /* The VDBE */
Parse *pParse /* Parsing context */
){
sqlite3 *db; /* The database connection */
int nVar; /* Number of parameters */
int nMem; /* Number of VM memory registers */
int nCursor; /* Number of cursors required */
| | > | 87784 87785 87786 87787 87788 87789 87790 87791 87792 87793 87794 87795 87796 87797 87798 87799 87800 87801 87802 87803 87804 87805 87806 87807 |
Vdbe *p, /* The VDBE */
Parse *pParse /* Parsing context */
){
sqlite3 *db; /* The database connection */
int nVar; /* Number of parameters */
int nMem; /* Number of VM memory registers */
int nCursor; /* Number of cursors required */
int nArg; /* Max number args to xFilter or xUpdate */
int n; /* Loop counter */
struct ReusableSpace x; /* Reusable bulk memory */
assert( p!=0 );
assert( p->nOp>0 );
assert( pParse!=0 );
assert( p->eVdbeState==VDBE_INIT_STATE );
assert( pParse==p->pParse );
assert( pParse->db==p->db );
p->pVList = pParse->pVList;
pParse->pVList = 0;
db = p->db;
assert( db->mallocFailed==0 );
nVar = pParse->nVar;
nMem = pParse->nMem;
nCursor = pParse->nTab;
|
| ︙ | ︙ | |||
87712 87713 87714 87715 87716 87717 87718 87719 87720 87721 87722 87723 87724 87725 |
if( !db->mallocFailed ){
p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
}
}
if( db->mallocFailed ){
p->nVar = 0;
p->nCursor = 0;
p->nMem = 0;
}else{
p->nCursor = nCursor;
| > > > | 87856 87857 87858 87859 87860 87861 87862 87863 87864 87865 87866 87867 87868 87869 87870 87871 87872 |
if( !db->mallocFailed ){
p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
}
}
#ifdef SQLITE_DEBUG
p->napArg = nArg;
#endif
if( db->mallocFailed ){
p->nVar = 0;
p->nCursor = 0;
p->nMem = 0;
}else{
p->nCursor = nCursor;
|
| ︙ | ︙ | |||
89209 89210 89211 89212 89213 89214 89215 89216 89217 89218 89219 89220 89221 89222 |
** If an OOM error occurs, NULL is returned.
*/
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
KeyInfo *pKeyInfo /* Description of the record */
){
UnpackedRecord *p; /* Unpacked record to return */
int nByte; /* Number of bytes required for *p */
nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
if( !p ) return 0;
p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))];
assert( pKeyInfo->aSortFlags!=0 );
p->pKeyInfo = pKeyInfo;
p->nField = pKeyInfo->nKeyField + 1;
| > | 89356 89357 89358 89359 89360 89361 89362 89363 89364 89365 89366 89367 89368 89369 89370 |
** If an OOM error occurs, NULL is returned.
*/
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(
KeyInfo *pKeyInfo /* Description of the record */
){
UnpackedRecord *p; /* Unpacked record to return */
int nByte; /* Number of bytes required for *p */
assert( sizeof(UnpackedRecord) + sizeof(Mem)*65536 < 0x7fffffff );
nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1);
p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte);
if( !p ) return 0;
p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))];
assert( pKeyInfo->aSortFlags!=0 );
p->pKeyInfo = pKeyInfo;
p->nField = pKeyInfo->nKeyField + 1;
|
| ︙ | ︙ | |||
90615 90616 90617 90618 90619 90620 90621 |
** 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 );
| < | 90763 90764 90765 90766 90767 90768 90769 90770 90771 90772 90773 90774 90775 90776 |
** 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);
|
| ︙ | ︙ | |||
91335 91336 91337 91338 91339 91340 91341 |
** 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
| | | 91482 91483 91484 91485 91486 91487 91488 91489 91490 91491 91492 91493 91494 91495 91496 |
** 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{
|
| ︙ | ︙ | |||
91846 91847 91848 91849 91850 91851 91852 91853 91854 91855 91856 91857 91858 91859 |
/* .szMalloc = */ (int)0,
/* .uTemp = */ (u32)0,
/* .zMalloc = */ (char*)0,
/* .xDel = */ (void(*)(void*))0,
#ifdef SQLITE_DEBUG
/* .pScopyFrom = */ (Mem*)0,
/* .mScopyFlags= */ 0,
#endif
};
return &nullMem;
}
/*
** Check to see if column iCol of the given statement is valid. If
| > | 91993 91994 91995 91996 91997 91998 91999 92000 92001 92002 92003 92004 92005 92006 92007 |
/* .szMalloc = */ (int)0,
/* .uTemp = */ (u32)0,
/* .zMalloc = */ (char*)0,
/* .xDel = */ (void(*)(void*))0,
#ifdef SQLITE_DEBUG
/* .pScopyFrom = */ (Mem*)0,
/* .mScopyFlags= */ 0,
/* .bScopy = */ 0,
#endif
};
return &nullMem;
}
/*
** Check to see if column iCol of the given statement is valid. If
|
| ︙ | ︙ | |||
91887 91888 91889 91890 91891 91892 91893 | ** ** Specifically, this is called from within: ** ** sqlite3_column_int() ** sqlite3_column_int64() ** sqlite3_column_text() ** sqlite3_column_text16() | | | 92035 92036 92037 92038 92039 92040 92041 92042 92043 92044 92045 92046 92047 92048 92049 |
**
** Specifically, this is called from within:
**
** sqlite3_column_int()
** sqlite3_column_int64()
** sqlite3_column_text()
** sqlite3_column_text16()
** sqlite3_column_double()
** sqlite3_column_bytes()
** sqlite3_column_bytes16()
** sqlite3_column_blob()
*/
static void columnMallocFailure(sqlite3_stmt *pStmt)
{
/* If malloc() failed during an encoding conversion within an
|
| ︙ | ︙ | |||
92728 92729 92730 92731 92732 92733 92734 92735 92736 92737 92738 92739 92740 92741 92742 92743 92744 92745 92746 92747 92748 |
** This function is called from within a pre-update callback to retrieve
** a field of the row currently being updated or deleted.
*/
SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p;
Mem *pMem;
int rc = SQLITE_OK;
#ifdef SQLITE_ENABLE_API_ARMOR
if( db==0 || ppValue==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
p = db->pPreUpdate;
/* Test that this call is being made from within an SQLITE_DELETE or
** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
if( !p || p->op==SQLITE_INSERT ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_old_out;
}
if( p->pPk ){
| > | > > | | 92876 92877 92878 92879 92880 92881 92882 92883 92884 92885 92886 92887 92888 92889 92890 92891 92892 92893 92894 92895 92896 92897 92898 92899 92900 92901 92902 92903 92904 92905 92906 92907 92908 92909 |
** This function is called from within a pre-update callback to retrieve
** a field of the row currently being updated or deleted.
*/
SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p;
Mem *pMem;
int rc = SQLITE_OK;
int iStore = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( db==0 || ppValue==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
p = db->pPreUpdate;
/* Test that this call is being made from within an SQLITE_DELETE or
** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */
if( !p || p->op==SQLITE_INSERT ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_old_out;
}
if( p->pPk ){
iStore = sqlite3TableColumnToIndex(p->pPk, iIdx);
}else{
iStore = sqlite3TableColumnToStorage(p->pTab, iIdx);
}
if( iStore>=p->pCsr->nField || iStore<0 ){
rc = SQLITE_RANGE;
goto preupdate_old_out;
}
if( iIdx==p->pTab->iPKey ){
*ppValue = pMem = &p->oldipk;
sqlite3VdbeMemSetInt64(pMem, p->iKey1);
|
| ︙ | ︙ | |||
92775 92776 92777 92778 92779 92780 92781 |
if( rc!=SQLITE_OK ){
sqlite3DbFree(db, aRec);
goto preupdate_old_out;
}
p->aRecord = aRec;
}
| | | > > | | 92926 92927 92928 92929 92930 92931 92932 92933 92934 92935 92936 92937 92938 92939 92940 92941 92942 92943 92944 92945 92946 92947 92948 92949 |
if( rc!=SQLITE_OK ){
sqlite3DbFree(db, aRec);
goto preupdate_old_out;
}
p->aRecord = aRec;
}
pMem = *ppValue = &p->pUnpacked->aMem[iStore];
if( iStore>=p->pUnpacked->nField ){
/* This occurs when the table has been extended using ALTER TABLE
** ADD COLUMN. The value to return is the default value of the column. */
Column *pCol = &p->pTab->aCol[iIdx];
if( pCol->iDflt>0 ){
if( p->apDflt==0 ){
int nByte;
assert( sizeof(sqlite3_value*)*UMXV(p->pTab->nCol) < 0x7fffffff );
nByte = sizeof(sqlite3_value*)*p->pTab->nCol;
p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte);
if( p->apDflt==0 ) goto preupdate_old_out;
}
if( p->apDflt[iIdx]==0 ){
sqlite3_value *pVal = 0;
Expr *pDflt;
assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) );
|
| ︙ | ︙ | |||
92880 92881 92882 92883 92884 92885 92886 92887 92888 92889 92890 92891 92892 92893 92894 92895 92896 92897 92898 |
** This function is called from within a pre-update callback to retrieve
** a field of the row currently being updated or inserted.
*/
SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p;
int rc = SQLITE_OK;
Mem *pMem;
#ifdef SQLITE_ENABLE_API_ARMOR
if( db==0 || ppValue==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
p = db->pPreUpdate;
if( !p || p->op==SQLITE_DELETE ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_new_out;
}
if( p->pPk && p->op!=SQLITE_UPDATE ){
| > | > > > | | | | > | | | | | 93033 93034 93035 93036 93037 93038 93039 93040 93041 93042 93043 93044 93045 93046 93047 93048 93049 93050 93051 93052 93053 93054 93055 93056 93057 93058 93059 93060 93061 93062 93063 93064 93065 93066 93067 93068 93069 93070 93071 93072 93073 93074 93075 93076 93077 93078 93079 93080 93081 93082 93083 93084 93085 93086 93087 93088 93089 93090 93091 93092 93093 93094 93095 93096 93097 93098 93099 93100 93101 93102 93103 93104 93105 93106 93107 93108 93109 93110 93111 93112 |
** This function is called from within a pre-update callback to retrieve
** a field of the row currently being updated or inserted.
*/
SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){
PreUpdate *p;
int rc = SQLITE_OK;
Mem *pMem;
int iStore = 0;
#ifdef SQLITE_ENABLE_API_ARMOR
if( db==0 || ppValue==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
p = db->pPreUpdate;
if( !p || p->op==SQLITE_DELETE ){
rc = SQLITE_MISUSE_BKPT;
goto preupdate_new_out;
}
if( p->pPk && p->op!=SQLITE_UPDATE ){
iStore = sqlite3TableColumnToIndex(p->pPk, iIdx);
}else{
iStore = sqlite3TableColumnToStorage(p->pTab, iIdx);
}
if( iStore>=p->pCsr->nField || iStore<0 ){
rc = SQLITE_RANGE;
goto preupdate_new_out;
}
if( p->op==SQLITE_INSERT ){
/* For an INSERT, memory cell p->iNewReg contains the serialized record
** that is being inserted. Deserialize it. */
UnpackedRecord *pUnpack = p->pNewUnpacked;
if( !pUnpack ){
Mem *pData = &p->v->aMem[p->iNewReg];
rc = ExpandBlob(pData);
if( rc!=SQLITE_OK ) goto preupdate_new_out;
pUnpack = vdbeUnpackRecord(&p->keyinfo, pData->n, pData->z);
if( !pUnpack ){
rc = SQLITE_NOMEM;
goto preupdate_new_out;
}
p->pNewUnpacked = pUnpack;
}
pMem = &pUnpack->aMem[iStore];
if( iIdx==p->pTab->iPKey ){
sqlite3VdbeMemSetInt64(pMem, p->iKey2);
}else if( iStore>=pUnpack->nField ){
pMem = (sqlite3_value *)columnNullValue();
}
}else{
/* For an UPDATE, memory cell (p->iNewReg+1+iStore) contains the required
** value. Make a copy of the cell contents and return a pointer to it.
** It is not safe to return a pointer to the memory cell itself as the
** caller may modify the value text encoding.
*/
assert( p->op==SQLITE_UPDATE );
if( !p->aNew ){
assert( sizeof(Mem)*UMXV(p->pCsr->nField) < 0x7fffffff );
p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem)*p->pCsr->nField);
if( !p->aNew ){
rc = SQLITE_NOMEM;
goto preupdate_new_out;
}
}
assert( iStore>=0 && iStore<p->pCsr->nField );
pMem = &p->aNew[iStore];
if( pMem->flags==0 ){
if( iIdx==p->pTab->iPKey ){
sqlite3VdbeMemSetInt64(pMem, p->iKey2);
}else{
rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iStore]);
if( rc!=SQLITE_OK ) goto preupdate_new_out;
}
}
}
*ppValue = pMem;
preupdate_new_out:
|
| ︙ | ︙ | |||
93698 93699 93700 93701 93702 93703 93704 | ** ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from ** the top of the register space. Cursor 1 is at Mem[p->nMem-1]. ** Cursor 2 is at Mem[p->nMem-2]. And so forth. */ Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; | | | 93856 93857 93858 93859 93860 93861 93862 93863 93864 93865 93866 93867 93868 93869 93870 |
**
** The memory cell for cursor 0 is aMem[0]. The rest are allocated from
** the top of the register space. Cursor 1 is at Mem[p->nMem-1].
** Cursor 2 is at Mem[p->nMem-2]. And so forth.
*/
Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem;
i64 nByte;
VdbeCursor *pCx = 0;
nByte =
ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField +
(eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);
assert( iCur>=0 && iCur<p->nCursor );
if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
|
| ︙ | ︙ | |||
93726 93727 93728 93729 93730 93731 93732 |
sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
}
pMem->z = pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, nByte);
if( pMem->zMalloc==0 ){
pMem->szMalloc = 0;
return 0;
}
| | | 93884 93885 93886 93887 93888 93889 93890 93891 93892 93893 93894 93895 93896 93897 93898 |
sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
}
pMem->z = pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, nByte);
if( pMem->zMalloc==0 ){
pMem->szMalloc = 0;
return 0;
}
pMem->szMalloc = (int)nByte;
}
p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc;
memset(pCx, 0, offsetof(VdbeCursor,pAltCursor));
pCx->eCurType = eCurType;
pCx->nField = nField;
pCx->aOffset = &pCx->aType[nField];
|
| ︙ | ︙ | |||
94029 94030 94031 94032 94033 94034 94035 94036 94037 94038 94039 94040 94041 94042 |
}
if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
}
static void registerTrace(int iReg, Mem *p){
printf("R[%d] = ", iReg);
memTracePrint(p);
if( p->pScopyFrom ){
printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg]));
}
printf("\n");
sqlite3VdbeCheckMemInvariants(p);
}
/**/ void sqlite3PrintMem(Mem *pMem){
memTracePrint(pMem);
| > | 94187 94188 94189 94190 94191 94192 94193 94194 94195 94196 94197 94198 94199 94200 94201 |
}
if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
}
static void registerTrace(int iReg, Mem *p){
printf("R[%d] = ", iReg);
memTracePrint(p);
if( p->pScopyFrom ){
assert( p->pScopyFrom->bScopy );
printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg]));
}
printf("\n");
sqlite3VdbeCheckMemInvariants(p);
}
/**/ void sqlite3PrintMem(Mem *pMem){
memTracePrint(pMem);
|
| ︙ | ︙ | |||
95012 95013 95014 95015 95016 95017 95018 95019 95020 95021 95022 95023 95024 95025 |
memAboutToChange(p, pOut);
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
pIn1->pScopyFrom = 0;
{ int i;
for(i=1; i<p->nMem; i++){
if( aMem[i].pScopyFrom==pIn1 ){
aMem[i].pScopyFrom = pOut;
}
}
}
#endif
Deephemeralize(pOut);
REGISTER_TRACE(p2++, pOut);
| > | 95171 95172 95173 95174 95175 95176 95177 95178 95179 95180 95181 95182 95183 95184 95185 |
memAboutToChange(p, pOut);
sqlite3VdbeMemMove(pOut, pIn1);
#ifdef SQLITE_DEBUG
pIn1->pScopyFrom = 0;
{ int i;
for(i=1; i<p->nMem; i++){
if( aMem[i].pScopyFrom==pIn1 ){
assert( aMem[i].bScopy );
aMem[i].pScopyFrom = pOut;
}
}
}
#endif
Deephemeralize(pOut);
REGISTER_TRACE(p2++, pOut);
|
| ︙ | ︙ | |||
95084 95085 95086 95087 95088 95089 95090 95091 95092 95093 95094 95095 95096 95097 | pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; assert( pOut!=pIn1 ); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); #ifdef SQLITE_DEBUG pOut->pScopyFrom = pIn1; pOut->mScopyFlags = pIn1->flags; #endif break; } /* Opcode: IntCopy P1 P2 * * * ** Synopsis: r[P2]=r[P1] ** | > | 95244 95245 95246 95247 95248 95249 95250 95251 95252 95253 95254 95255 95256 95257 95258 | pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; assert( pOut!=pIn1 ); sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); #ifdef SQLITE_DEBUG pOut->pScopyFrom = pIn1; pOut->mScopyFlags = pIn1->flags; pIn1->bScopy = 1; #endif break; } /* Opcode: IntCopy P1 P2 * * * ** Synopsis: r[P2]=r[P1] ** |
| ︙ | ︙ | |||
100744 100745 100746 100747 100748 100749 100750 |
**
** P4 is a pointer to the VM containing the trigger program.
**
** If P5 is non-zero, then recursive program invocation is enabled.
*/
case OP_Program: { /* jump0 */
int nMem; /* Number of memory registers for sub-program */
| | | 100905 100906 100907 100908 100909 100910 100911 100912 100913 100914 100915 100916 100917 100918 100919 |
**
** P4 is a pointer to the VM containing the trigger program.
**
** If P5 is non-zero, then recursive program invocation is enabled.
*/
case OP_Program: { /* jump0 */
int nMem; /* Number of memory registers for sub-program */
i64 nByte; /* Bytes of runtime space required for sub-program */
Mem *pRt; /* Register to allocate runtime space */
Mem *pMem; /* Used to iterate through memory cells */
Mem *pEnd; /* Last memory cell in new array */
VdbeFrame *pFrame; /* New vdbe frame to execute in */
SubProgram *pProgram; /* Sub-program to execute */
void *t; /* Token identifying trigger */
|
| ︙ | ︙ | |||
100795 100796 100797 100798 100799 100800 100801 |
*/
nMem = pProgram->nMem + pProgram->nCsr;
assert( nMem>0 );
if( pProgram->nCsr==0 ) nMem++;
nByte = ROUND8(sizeof(VdbeFrame))
+ nMem * sizeof(Mem)
+ pProgram->nCsr * sizeof(VdbeCursor*)
| | | | 100956 100957 100958 100959 100960 100961 100962 100963 100964 100965 100966 100967 100968 100969 100970 100971 100972 100973 100974 100975 100976 100977 100978 |
*/
nMem = pProgram->nMem + pProgram->nCsr;
assert( nMem>0 );
if( pProgram->nCsr==0 ) nMem++;
nByte = ROUND8(sizeof(VdbeFrame))
+ nMem * sizeof(Mem)
+ pProgram->nCsr * sizeof(VdbeCursor*)
+ (7 + (i64)pProgram->nOp)/8;
pFrame = sqlite3DbMallocZero(db, nByte);
if( !pFrame ){
goto no_mem;
}
sqlite3VdbeMemRelease(pRt);
pRt->flags = MEM_Blob|MEM_Dyn;
pRt->z = (char*)pFrame;
pRt->n = (int)nByte;
pRt->xDel = sqlite3VdbeFrameMemDel;
pFrame->v = p;
pFrame->nChildMem = nMem;
pFrame->nChildCsr = pProgram->nCsr;
pFrame->pc = (int)(pOp - aOp);
pFrame->aMem = p->aMem;
|
| ︙ | ︙ | |||
100902 100903 100904 100905 100906 100907 100908 |
**
** Increment a "constraint counter" by P2 (P2 may be negative or positive).
** If P1 is non-zero, the database constraint counter is incremented
** (deferred foreign key constraints). Otherwise, if P1 is zero, the
** statement counter is incremented (immediate foreign key constraints).
*/
case OP_FkCounter: {
| > > > | | < < | | > | 101063 101064 101065 101066 101067 101068 101069 101070 101071 101072 101073 101074 101075 101076 101077 101078 101079 101080 101081 101082 101083 101084 |
**
** Increment a "constraint counter" by P2 (P2 may be negative or positive).
** If P1 is non-zero, the database constraint counter is incremented
** (deferred foreign key constraints). Otherwise, if P1 is zero, the
** statement counter is incremented (immediate foreign key constraints).
*/
case OP_FkCounter: {
if( pOp->p1 ){
db->nDeferredCons += pOp->p2;
}else{
if( db->flags & SQLITE_DeferFKs ){
db->nDeferredImmCons += pOp->p2;
}else{
p->nFkConstraint += pOp->p2;
}
}
break;
}
/* Opcode: FkIfZero P1 P2 * * *
** Synopsis: if fkctr[P1]==0 goto P2
**
|
| ︙ | ︙ | |||
101782 101783 101784 101785 101786 101787 101788 101789 101790 101791 101792 101793 101794 101795 |
/* Grab the index number and argc parameters */
assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
nArg = (int)pArgc->u.i;
iQuery = (int)pQuery->u.i;
/* Invoke the xFilter method */
apArg = p->apArg;
for(i = 0; i<nArg; i++){
apArg[i] = &pArgc[i+1];
}
rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc ) goto abort_due_to_error;
res = pModule->xEof(pVCur);
| > | 101945 101946 101947 101948 101949 101950 101951 101952 101953 101954 101955 101956 101957 101958 101959 |
/* Grab the index number and argc parameters */
assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
nArg = (int)pArgc->u.i;
iQuery = (int)pQuery->u.i;
/* Invoke the xFilter method */
apArg = p->apArg;
assert( nArg<=p->napArg );
for(i = 0; i<nArg; i++){
apArg[i] = &pArgc[i+1];
}
rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc ) goto abort_due_to_error;
res = pModule->xEof(pVCur);
|
| ︙ | ︙ | |||
101992 101993 101994 101995 101996 101997 101998 101999 102000 102001 102002 102003 102004 102005 |
pModule = pVtab->pModule;
nArg = pOp->p2;
assert( pOp->p4type==P4_VTAB );
if( ALWAYS(pModule->xUpdate) ){
u8 vtabOnConflict = db->vtabOnConflict;
apArg = p->apArg;
pX = &aMem[pOp->p3];
for(i=0; i<nArg; i++){
assert( memIsValid(pX) );
memAboutToChange(p, pX);
apArg[i] = pX;
pX++;
}
db->vtabOnConflict = pOp->p5;
| > | 102156 102157 102158 102159 102160 102161 102162 102163 102164 102165 102166 102167 102168 102169 102170 |
pModule = pVtab->pModule;
nArg = pOp->p2;
assert( pOp->p4type==P4_VTAB );
if( ALWAYS(pModule->xUpdate) ){
u8 vtabOnConflict = db->vtabOnConflict;
apArg = p->apArg;
pX = &aMem[pOp->p3];
assert( nArg<=p->napArg );
for(i=0; i<nArg; i++){
assert( memIsValid(pX) );
memAboutToChange(p, pX);
apArg[i] = pX;
pX++;
}
db->vtabOnConflict = pOp->p5;
|
| ︙ | ︙ | |||
102837 102838 102839 102840 102841 102842 102843 |
sqlite3BtreeLeaveAll(db);
goto blob_open_out;
}
pBlob->pTab = pTab;
pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName;
/* Now search pTab for the exact column. */
| < | < < < | | 103002 103003 103004 103005 103006 103007 103008 103009 103010 103011 103012 103013 103014 103015 103016 103017 |
sqlite3BtreeLeaveAll(db);
goto blob_open_out;
}
pBlob->pTab = pTab;
pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName;
/* Now search pTab for the exact column. */
iCol = sqlite3ColumnIndex(pTab, zColumn);
if( iCol<0 ){
sqlite3DbFree(db, zErr);
zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn);
rc = SQLITE_ERROR;
sqlite3BtreeLeaveAll(db);
goto blob_open_out;
}
|
| ︙ | ︙ | |||
104104 104105 104106 104107 104108 104109 104110 |
VdbeCursor *pCsr /* Cursor that holds the new sorter */
){
int pgsz; /* Page size of main database */
int i; /* Used to iterate through aTask[] */
VdbeSorter *pSorter; /* The new sorter */
KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */
int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */
| | | 104265 104266 104267 104268 104269 104270 104271 104272 104273 104274 104275 104276 104277 104278 104279 |
VdbeCursor *pCsr /* Cursor that holds the new sorter */
){
int pgsz; /* Page size of main database */
int i; /* Used to iterate through aTask[] */
VdbeSorter *pSorter; /* The new sorter */
KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */
int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */
i64 sz; /* Size of pSorter in bytes */
int rc = SQLITE_OK;
#if SQLITE_MAX_WORKER_THREADS==0
# define nWorker 0
#else
int nWorker;
#endif
|
| ︙ | ︙ | |||
104132 104133 104134 104135 104136 104137 104138 104139 104140 104141 104142 104143 104144 104145 |
nWorker = SORTER_MAX_MERGE_COUNT-1;
}
#endif
assert( pCsr->pKeyInfo );
assert( !pCsr->isEphemeral );
assert( pCsr->eCurType==CURTYPE_SORTER );
szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*);
sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
pCsr->uc.pSorter = pSorter;
if( pSorter==0 ){
rc = SQLITE_NOMEM_BKPT;
| > > | 104293 104294 104295 104296 104297 104298 104299 104300 104301 104302 104303 104304 104305 104306 104307 104308 |
nWorker = SORTER_MAX_MERGE_COUNT-1;
}
#endif
assert( pCsr->pKeyInfo );
assert( !pCsr->isEphemeral );
assert( pCsr->eCurType==CURTYPE_SORTER );
assert( sizeof(KeyInfo) + UMXV(pCsr->pKeyInfo->nKeyField)*sizeof(CollSeq*)
< 0x7fffffff );
szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*);
sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
pCsr->uc.pSorter = pSorter;
if( pSorter==0 ){
rc = SQLITE_NOMEM_BKPT;
|
| ︙ | ︙ | |||
104345 104346 104347 104348 104349 104350 104351 |
** nReader PmaReader inputs.
**
** nReader is automatically rounded up to the next power of two.
** nReader may not exceed SORTER_MAX_MERGE_COUNT even after rounding up.
*/
static MergeEngine *vdbeMergeEngineNew(int nReader){
int N = 2; /* Smallest power of two >= nReader */
| | | 104508 104509 104510 104511 104512 104513 104514 104515 104516 104517 104518 104519 104520 104521 104522 |
** nReader PmaReader inputs.
**
** nReader is automatically rounded up to the next power of two.
** nReader may not exceed SORTER_MAX_MERGE_COUNT even after rounding up.
*/
static MergeEngine *vdbeMergeEngineNew(int nReader){
int N = 2; /* Smallest power of two >= nReader */
i64 nByte; /* Total bytes of space to allocate */
MergeEngine *pNew; /* Pointer to allocated object to return */
assert( nReader<=SORTER_MAX_MERGE_COUNT );
while( N<nReader ) N += N;
nByte = sizeof(MergeEngine) + N * (sizeof(int) + sizeof(PmaReader));
|
| ︙ | ︙ | |||
107388 107389 107390 107391 107392 107393 107394 | sqlite3 *db = pParse->db; /* The database connection */ SrcItem *pItem; /* Use for looping over pSrcList items */ SrcItem *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ Schema *pSchema = 0; /* Schema of the expression */ int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ Table *pTab = 0; /* Table holding the row */ | < | 107551 107552 107553 107554 107555 107556 107557 107558 107559 107560 107561 107562 107563 107564 | sqlite3 *db = pParse->db; /* The database connection */ SrcItem *pItem; /* Use for looping over pSrcList items */ SrcItem *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ Schema *pSchema = 0; /* Schema of the expression */ int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ Table *pTab = 0; /* Table holding the row */ ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */ const char *zCol = pRight->u.zToken; assert( pNC ); /* the name context cannot be NULL. */ assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ assert( zDb==0 || zTab!=0 ); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); |
| ︙ | ︙ | |||
107439 107440 107441 107442 107443 107444 107445 |
assert( pNC && cnt==0 );
do{
ExprList *pEList;
SrcList *pSrcList = pNC->pSrcList;
if( pSrcList ){
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
| < | 107601 107602 107603 107604 107605 107606 107607 107608 107609 107610 107611 107612 107613 107614 |
assert( pNC && cnt==0 );
do{
ExprList *pEList;
SrcList *pSrcList = pNC->pSrcList;
if( pSrcList ){
for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
pTab = pItem->pSTab;
assert( pTab!=0 && pTab->zName!=0 );
assert( pTab->nCol>0 || pParse->nErr );
assert( (int)pItem->fg.isNestedFrom == IsNestedFrom(pItem));
if( pItem->fg.isNestedFrom ){
/* In this case, pItem is a subquery that has been formed from a
** parenthesized subset of the FROM clause terms. Example:
|
| ︙ | ︙ | |||
107527 107528 107529 107530 107531 107532 107533 |
if( !isValidSchemaTableName(zTab, pTab, zDb) ) continue;
}
assert( ExprUseYTab(pExpr) );
if( IN_RENAME_OBJECT && pItem->zAlias ){
sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
}
}
| | < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < < | 107688 107689 107690 107691 107692 107693 107694 107695 107696 107697 107698 107699 107700 107701 107702 107703 107704 107705 107706 107707 107708 107709 107710 107711 107712 107713 107714 107715 107716 107717 107718 107719 107720 107721 107722 107723 107724 107725 107726 107727 107728 107729 107730 107731 107732 107733 |
if( !isValidSchemaTableName(zTab, pTab, zDb) ) continue;
}
assert( ExprUseYTab(pExpr) );
if( IN_RENAME_OBJECT && pItem->zAlias ){
sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
}
}
j = sqlite3ColumnIndex(pTab, zCol);
if( j>=0 ){
if( cnt>0 ){
if( pItem->fg.isUsing==0
|| sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
){
/* Two or more tables have the same column name which is
** not joined by USING. This is an error. Signal as much
** by clearing pFJMatch and letting cnt go above 1. */
sqlite3ExprListDelete(db, pFJMatch);
pFJMatch = 0;
}else
if( (pItem->fg.jointype & JT_RIGHT)==0 ){
/* An INNER or LEFT JOIN. Use the left-most table */
continue;
}else
if( (pItem->fg.jointype & JT_LEFT)==0 ){
/* A RIGHT JOIN. Use the right-most table */
cnt = 0;
sqlite3ExprListDelete(db, pFJMatch);
pFJMatch = 0;
}else{
/* For a FULL JOIN, we must construct a coalesce() func */
extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn);
}
}
cnt++;
pMatch = pItem;
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
if( pItem->fg.isNestedFrom ){
sqlite3SrcItemColumnUsed(pItem, j);
}
}
if( 0==cnt && VisibleRowid(pTab) ){
/* pTab is a potential ROWID match. Keep track of it and match
** the ROWID later if that seems appropriate. (Search for "cntTab"
** to find related code.) Only allow a ROWID match if there is
** a single ROWID match candidate.
|
| ︙ | ︙ | |||
107653 107654 107655 107656 107657 107658 107659 |
pExpr->iTable = EXCLUDED_TABLE_NUMBER;
}
}
#endif /* SQLITE_OMIT_UPSERT */
if( pTab ){
int iCol;
| < < < | < | | | < < < | < | > > > | 107809 107810 107811 107812 107813 107814 107815 107816 107817 107818 107819 107820 107821 107822 107823 107824 107825 107826 107827 107828 107829 107830 107831 107832 107833 |
pExpr->iTable = EXCLUDED_TABLE_NUMBER;
}
}
#endif /* SQLITE_OMIT_UPSERT */
if( pTab ){
int iCol;
pSchema = pTab->pSchema;
cntTab++;
iCol = sqlite3ColumnIndex(pTab, zCol);
if( iCol>=0 ){
if( pTab->iPKey==iCol ) iCol = -1;
}else{
if( sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){
iCol = -1;
}else{
iCol = pTab->nCol;
}
}
if( iCol<pTab->nCol ){
cnt++;
pMatch = 0;
#ifndef SQLITE_OMIT_UPSERT
if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){
testcase( iCol==(-1) );
|
| ︙ | ︙ | |||
109894 109895 109896 109897 109898 109899 109900 |
p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft);
}else{
p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
}
p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
(void*)p4, P4_COLLSEQ);
| | | 110045 110046 110047 110048 110049 110050 110051 110052 110053 110054 110055 110056 110057 110058 110059 |
p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft);
}else{
p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight);
}
p5 = binaryCompareP5(pLeft, pRight, jumpIfNull);
addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
(void*)p4, P4_COLLSEQ);
sqlite3VdbeChangeP5(pParse->pVdbe, (u16)p5);
return addr;
}
/*
** Return true if expression pExpr is a vector, or false otherwise.
**
** A vector is defined as any expression that results in two or more
|
| ︙ | ︙ | |||
111264 111265 111266 111267 111268 111269 111270 |
pNewExpr->pRight = pPriorSelectColNew;
}
pNewExpr->pLeft = pPriorSelectColNew;
}
}
pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
pItem->fg = pOldItem->fg;
| < | 111415 111416 111417 111418 111419 111420 111421 111422 111423 111424 111425 111426 111427 111428 |
pNewExpr->pRight = pPriorSelectColNew;
}
pNewExpr->pLeft = pPriorSelectColNew;
}
}
pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
pItem->fg = pOldItem->fg;
pItem->u = pOldItem->u;
}
return pNew;
}
/*
** If cursors, triggers, views and subqueries are all omitted from
|
| ︙ | ︙ | |||
111347 111348 111349 111350 111351 111352 111353 |
return pNew;
}
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
IdList *pNew;
int i;
assert( db!=0 );
if( p==0 ) return 0;
| < < < | 111497 111498 111499 111500 111501 111502 111503 111504 111505 111506 111507 111508 111509 111510 111511 111512 111513 111514 111515 111516 111517 |
return pNew;
}
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
IdList *pNew;
int i;
assert( db!=0 );
if( p==0 ) return 0;
pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) );
if( pNew==0 ) return 0;
pNew->nId = p->nId;
for(i=0; i<p->nId; i++){
struct IdList_item *pNewItem = &pNew->a[i];
const struct IdList_item *pOldItem = &p->a[i];
pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
}
return pNew;
}
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
Select *pRet = 0;
Select *pNext = 0;
Select **pp = &pRet;
|
| ︙ | ︙ | |||
112384 112385 112386 112387 112388 112389 112390 |
** of the same name.
*/
SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab){
const char *azOpt[] = {"_ROWID_", "ROWID", "OID"};
int ii;
assert( VisibleRowid(pTab) );
for(ii=0; ii<ArraySize(azOpt); ii++){
| < < < < < | < | 112531 112532 112533 112534 112535 112536 112537 112538 112539 112540 112541 112542 112543 112544 112545 |
** of the same name.
*/
SQLITE_PRIVATE const char *sqlite3RowidAlias(Table *pTab){
const char *azOpt[] = {"_ROWID_", "ROWID", "OID"};
int ii;
assert( VisibleRowid(pTab) );
for(ii=0; ii<ArraySize(azOpt); ii++){
if( sqlite3ColumnIndex(pTab, azOpt[ii])<0 ) return azOpt[ii];
}
return 0;
}
/*
** pX is the RHS of an IN operator. If pX is a SELECT statement
** that can be simplified to a direct table access, then return
|
| ︙ | ︙ | |||
112700 112701 112702 112703 112704 112705 112706 112707 112708 112709 112710 112711 112712 112713 |
if( j==nExpr ) break;
mCol = MASKBIT(j);
if( mCol & colUsed ) break; /* Each column used only once */
colUsed |= mCol;
if( aiMap ) aiMap[i] = j;
}
assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) );
if( colUsed==(MASKBIT(nExpr)-1) ){
/* If we reach this point, that means the index pIdx is usable */
int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
ExplainQueryPlan((pParse, 0,
"USING INDEX %s FOR IN-OPERATOR",pIdx->zName));
sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
| > | 112841 112842 112843 112844 112845 112846 112847 112848 112849 112850 112851 112852 112853 112854 112855 |
if( j==nExpr ) break;
mCol = MASKBIT(j);
if( mCol & colUsed ) break; /* Each column used only once */
colUsed |= mCol;
if( aiMap ) aiMap[i] = j;
}
assert( nExpr>0 && nExpr<BMS );
assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) );
if( colUsed==(MASKBIT(nExpr)-1) ){
/* If we reach this point, that means the index pIdx is usable */
int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
ExplainQueryPlan((pParse, 0,
"USING INDEX %s FOR IN-OPERATOR",pIdx->zName));
sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb);
|
| ︙ | ︙ | |||
112793 112794 112795 112796 112797 112798 112799 |
static char *exprINAffinity(Parse *pParse, const Expr *pExpr){
Expr *pLeft = pExpr->pLeft;
int nVal = sqlite3ExprVectorSize(pLeft);
Select *pSelect = ExprUseXSelect(pExpr) ? pExpr->x.pSelect : 0;
char *zRet;
assert( pExpr->op==TK_IN );
| | | 112935 112936 112937 112938 112939 112940 112941 112942 112943 112944 112945 112946 112947 112948 112949 |
static char *exprINAffinity(Parse *pParse, const Expr *pExpr){
Expr *pLeft = pExpr->pLeft;
int nVal = sqlite3ExprVectorSize(pLeft);
Select *pSelect = ExprUseXSelect(pExpr) ? pExpr->x.pSelect : 0;
char *zRet;
assert( pExpr->op==TK_IN );
zRet = sqlite3DbMallocRaw(pParse->db, 1+(i64)nVal);
if( zRet ){
int i;
for(i=0; i<nVal; i++){
Expr *pA = sqlite3VectorFieldSubexpr(pLeft, i);
char a = sqlite3ExprAffinity(pA);
if( pSelect ){
zRet[i] = sqlite3CompareAffinity(pSelect->pEList->a[i].pExpr, a);
|
| ︙ | ︙ | |||
112879 112880 112881 112882 112883 112884 112885 112886 112887 112888 112889 112890 112891 112892 |
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;
| > | 113021 113022 113023 113024 113025 113026 113027 113028 113029 113030 113031 113032 113033 113034 113035 |
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;
|
| ︙ | ︙ | |||
112925 112926 112927 112928 112929 112930 112931 112932 112933 112934 112935 112936 112937 112938 112939 112940 112941 112942 112943 112944 112945 112946 112947 112948 112949 112950 112951 |
){
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.
*/
| > < | 113068 113069 113070 113071 113072 113073 113074 113075 113076 113077 113078 113079 113080 113081 113082 113083 113084 113085 113086 113087 113088 113089 113090 113091 113092 113093 113094 113095 113096 113097 113098 113099 113100 113101 113102 |
){
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);
}
|
| ︙ | ︙ | |||
112988 112989 112990 112991 112992 112993 112994 112995 112996 112997 112998 112999 113000 113001 |
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);
| > | 113131 113132 113133 113134 113135 113136 113137 113138 113139 113140 113141 113142 113143 113144 113145 |
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);
|
| ︙ | ︙ | |||
113123 113124 113125 113126 113127 113128 113129 113130 113131 113132 113133 113134 113135 113136 |
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 */
| > | 113267 113268 113269 113270 113271 113272 113273 113274 113275 113276 113277 113278 113279 113280 113281 |
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 */
|
| ︙ | ︙ | |||
117435 117436 117437 117438 117439 117440 117441 | } #endif /* Make sure the old name really is a column name in the table to be ** altered. Set iCol to be the index of the column being renamed */ zOld = sqlite3NameFromToken(db, pOld); if( !zOld ) goto exit_rename_column; | < | < | | 117580 117581 117582 117583 117584 117585 117586 117587 117588 117589 117590 117591 117592 117593 117594 117595 |
}
#endif
/* Make sure the old name really is a column name in the table to be
** altered. Set iCol to be the index of the column being renamed */
zOld = sqlite3NameFromToken(db, pOld);
if( !zOld ) goto exit_rename_column;
iCol = sqlite3ColumnIndex(pTab, zOld);
if( iCol<0 ){
sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld);
goto exit_rename_column;
}
/* Ensure the schema contains no double-quoted strings */
renameTestSchema(pParse, zDb, iSchema==1, "", 0);
renameFixQuotes(pParse, zDb, iSchema==1);
|
| ︙ | ︙ | |||
119337 119338 119339 119340 119341 119342 119343 |
/* The sqlite_statN table does not exist. Create it. Note that a
** side-effect of the CREATE TABLE statement is to leave the rootpage
** of the new table in register pParse->regRoot. This is important
** because the OpenWrite opcode below will be needing it. */
sqlite3NestedParse(pParse,
"CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols
);
| > | | 119480 119481 119482 119483 119484 119485 119486 119487 119488 119489 119490 119491 119492 119493 119494 119495 |
/* The sqlite_statN table does not exist. Create it. Note that a
** side-effect of the CREATE TABLE statement is to leave the rootpage
** of the new table in register pParse->regRoot. This is important
** because the OpenWrite opcode below will be needing it. */
sqlite3NestedParse(pParse,
"CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols
);
assert( pParse->isCreate || pParse->nErr );
aRoot[i] = (u32)pParse->u1.cr.regRoot;
aCreateTbl[i] = OPFLAG_P2ISREG;
}
}else{
/* The table already exists. If zWhere is not NULL, delete all entries
** associated with the table zWhere. If zWhere is NULL, delete the
** entire contents of the table. */
aRoot[i] = pStat->tnum;
|
| ︙ | ︙ | |||
119528 119529 119530 119531 119532 119533 119534 |
int argc,
sqlite3_value **argv
){
StatAccum *p;
int nCol; /* Number of columns in index being sampled */
int nKeyCol; /* Number of key columns */
int nColUp; /* nCol rounded up for alignment */
| | | 119672 119673 119674 119675 119676 119677 119678 119679 119680 119681 119682 119683 119684 119685 119686 |
int argc,
sqlite3_value **argv
){
StatAccum *p;
int nCol; /* Number of columns in index being sampled */
int nKeyCol; /* Number of key columns */
int nColUp; /* nCol rounded up for alignment */
i64 n; /* Bytes of space to allocate */
sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */
#ifdef SQLITE_ENABLE_STAT4
/* Maximum number of samples. 0 if STAT4 data is not collected */
int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
#endif
/* Decode the three function arguments */
|
| ︙ | ︙ | |||
121302 121303 121304 121305 121306 121307 121308 |
** hash tables.
*/
if( db->aDb==db->aDbStatic ){
aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
if( aNew==0 ) return;
memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
}else{
| | > > > > > > | 121446 121447 121448 121449 121450 121451 121452 121453 121454 121455 121456 121457 121458 121459 121460 121461 121462 121463 121464 121465 121466 121467 121468 121469 121470 121471 121472 121473 121474 121475 121476 121477 121478 121479 121480 121481 121482 121483 |
** hash tables.
*/
if( db->aDb==db->aDbStatic ){
aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 );
if( aNew==0 ) return;
memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
}else{
aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(1+(i64)db->nDb));
if( aNew==0 ) return;
}
db->aDb = aNew;
pNew = &db->aDb[db->nDb];
memset(pNew, 0, sizeof(*pNew));
/* Open the database file. If the btree is successfully opened, use
** it to obtain the database schema. At this point the schema may
** or may not be initialized.
*/
flags = db->openFlags;
rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
if( rc!=SQLITE_OK ){
if( rc==SQLITE_NOMEM ) sqlite3OomFault(db);
sqlite3_result_error(context, zErr, -1);
sqlite3_free(zErr);
return;
}
if( (db->flags & SQLITE_AttachWrite)==0 ){
flags &= ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE);
flags |= SQLITE_OPEN_READONLY;
}else if( (db->flags & SQLITE_AttachCreate)==0 ){
flags &= ~SQLITE_OPEN_CREATE;
}
assert( pVfs );
flags |= SQLITE_OPEN_MAIN_DB;
rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
db->nDb++;
pNew->zDbSName = sqlite3DbStrDup(db, zName);
}
|
| ︙ | ︙ | |||
122089 122090 122091 122092 122093 122094 122095 122096 122097 122098 122099 122100 122101 122102 |
p = &pToplevel->aTableLock[i];
if( p->iDb==iDb && p->iTab==iTab ){
p->isWriteLock = (p->isWriteLock || isWriteLock);
return;
}
}
nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1);
pToplevel->aTableLock =
sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes);
if( pToplevel->aTableLock ){
p = &pToplevel->aTableLock[pToplevel->nTableLock++];
p->iDb = iDb;
p->iTab = iTab;
| > | 122239 122240 122241 122242 122243 122244 122245 122246 122247 122248 122249 122250 122251 122252 122253 |
p = &pToplevel->aTableLock[i];
if( p->iDb==iDb && p->iTab==iTab ){
p->isWriteLock = (p->isWriteLock || isWriteLock);
return;
}
}
assert( pToplevel->nTableLock < 0x7fff0000 );
nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1);
pToplevel->aTableLock =
sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes);
if( pToplevel->aTableLock ){
p = &pToplevel->aTableLock[pToplevel->nTableLock++];
p->iDb = iDb;
p->iTab = iTab;
|
| ︙ | ︙ | |||
122189 122190 122191 122192 122193 122194 122195 |
v = sqlite3GetVdbe(pParse);
if( v==0 ) pParse->rc = SQLITE_ERROR;
}
assert( !pParse->isMultiWrite
|| sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
if( v ){
if( pParse->bReturning ){
| | > > | 122340 122341 122342 122343 122344 122345 122346 122347 122348 122349 122350 122351 122352 122353 122354 122355 122356 122357 122358 122359 |
v = sqlite3GetVdbe(pParse);
if( v==0 ) pParse->rc = SQLITE_ERROR;
}
assert( !pParse->isMultiWrite
|| sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
if( v ){
if( pParse->bReturning ){
Returning *pReturning;
int addrRewind;
int reg;
assert( !pParse->isCreate );
pReturning = pParse->u1.d.pReturning;
if( pReturning->nRetCol ){
sqlite3VdbeAddOp0(v, OP_FkCheck);
addrRewind =
sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur);
VdbeCoverage(v);
reg = pReturning->iRetReg;
for(i=0; i<pReturning->nRetCol; i++){
|
| ︙ | ︙ | |||
122268 122269 122270 122271 122272 122273 122274 |
for(i=0; i<pEL->nExpr; i++){
assert( pEL->a[i].u.iConstExprReg>0 );
sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg);
}
}
if( pParse->bReturning ){
| | > > | 122421 122422 122423 122424 122425 122426 122427 122428 122429 122430 122431 122432 122433 122434 122435 122436 122437 |
for(i=0; i<pEL->nExpr; i++){
assert( pEL->a[i].u.iConstExprReg>0 );
sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg);
}
}
if( pParse->bReturning ){
Returning *pRet;
assert( !pParse->isCreate );
pRet = pParse->u1.d.pReturning;
if( pRet->nRetCol ){
sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol);
}
}
/* Finally, jump back to the beginning of the executable code. */
sqlite3VdbeGoto(v, 1);
|
| ︙ | ︙ | |||
123340 123341 123342 123343 123344 123345 123346 |
sqlite3VdbeAddOp0(v, OP_VBegin);
}
#endif
/* If the file format and encoding in the database have not been set,
** set them now.
*/
| > | | | | | | 123495 123496 123497 123498 123499 123500 123501 123502 123503 123504 123505 123506 123507 123508 123509 123510 123511 123512 123513 123514 123515 123516 123517 123518 123519 123520 123521 123522 123523 123524 123525 123526 123527 123528 123529 123530 123531 123532 123533 123534 123535 123536 123537 123538 |
sqlite3VdbeAddOp0(v, OP_VBegin);
}
#endif
/* If the file format and encoding in the database have not been set,
** set them now.
*/
assert( pParse->isCreate );
reg1 = pParse->u1.cr.regRowid = ++pParse->nMem;
reg2 = pParse->u1.cr.regRoot = ++pParse->nMem;
reg3 = ++pParse->nMem;
sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
sqlite3VdbeUsesBtree(v, iDb);
addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
1 : SQLITE_MAX_FILE_FORMAT;
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat);
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db));
sqlite3VdbeJumpHere(v, addr1);
/* This just creates a place-holder record in the sqlite_schema table.
** The record created does not contain anything yet. It will be replaced
** by the real entry in code generated at sqlite3EndTable().
**
** The rowid for the new entry is left in register pParse->u1.cr.regRowid.
** The root page of the new table is left in reg pParse->u1.cr.regRoot.
** The rowid and root page number values are needed by the code that
** sqlite3EndTable will generate.
*/
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
if( isView || isVirtual ){
sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2);
}else
#endif
{
assert( !pParse->bReturning );
pParse->u1.cr.addrCrTab =
sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY);
}
sqlite3OpenSchemaTable(pParse, iDb);
sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1);
sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC);
sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1);
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
|
| ︙ | ︙ | |||
123446 123447 123448 123449 123450 123451 123452 |
}
pParse->bReturning = 1;
pRet = sqlite3DbMallocZero(db, sizeof(*pRet));
if( pRet==0 ){
sqlite3ExprListDelete(db, pList);
return;
}
| > | | 123602 123603 123604 123605 123606 123607 123608 123609 123610 123611 123612 123613 123614 123615 123616 123617 |
}
pParse->bReturning = 1;
pRet = sqlite3DbMallocZero(db, sizeof(*pRet));
if( pRet==0 ){
sqlite3ExprListDelete(db, pList);
return;
}
assert( !pParse->isCreate );
pParse->u1.d.pReturning = pRet;
pRet->pParse = pParse;
pRet->pReturnEL = pList;
sqlite3ParserAddCleanup(pParse, sqlite3DeleteReturning, pRet);
testcase( pParse->earlyCleanup );
if( db->mallocFailed ) return;
sqlite3_snprintf(sizeof(pRet->zName), pRet->zName,
"sqlite_returning_%p", pParse);
|
| ︙ | ︙ | |||
123488 123489 123490 123491 123492 123493 123494 |
SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){
Table *p;
int i;
char *z;
char *zType;
Column *pCol;
sqlite3 *db = pParse->db;
| < | 123645 123646 123647 123648 123649 123650 123651 123652 123653 123654 123655 123656 123657 123658 |
SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){
Table *p;
int i;
char *z;
char *zType;
Column *pCol;
sqlite3 *db = pParse->db;
Column *aNew;
u8 eType = COLTYPE_CUSTOM;
u8 szEst = 1;
char affinity = SQLITE_AFF_BLOB;
if( (p = pParse->pNewTable)==0 ) return;
if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
|
| ︙ | ︙ | |||
123542 123543 123544 123545 123546 123547 123548 | z = sqlite3DbMallocRaw(db, (i64)sName.n + 1 + (i64)sType.n + (sType.n>0) ); if( z==0 ) return; if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName); memcpy(z, sName.z, sName.n); z[sName.n] = 0; sqlite3Dequote(z); | | < < | | | < | | 123698 123699 123700 123701 123702 123703 123704 123705 123706 123707 123708 123709 123710 123711 123712 123713 123714 123715 123716 123717 123718 123719 123720 123721 123722 123723 123724 123725 123726 |
z = sqlite3DbMallocRaw(db, (i64)sName.n + 1 + (i64)sType.n + (sType.n>0) );
if( z==0 ) return;
if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName);
memcpy(z, sName.z, sName.n);
z[sName.n] = 0;
sqlite3Dequote(z);
if( p->nCol && sqlite3ColumnIndex(p, z)>=0 ){
sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
sqlite3DbFree(db, z);
return;
}
aNew = sqlite3DbRealloc(db,p->aCol,((i64)p->nCol+1)*sizeof(p->aCol[0]));
if( aNew==0 ){
sqlite3DbFree(db, z);
return;
}
p->aCol = aNew;
pCol = &p->aCol[p->nCol];
memset(pCol, 0, sizeof(p->aCol[0]));
pCol->zCnName = z;
pCol->hName = sqlite3StrIHash(z);
sqlite3ColumnPropertiesFromName(p, pCol);
if( sType.n==0 ){
/* If there is no type specified, columns have the default affinity
** 'BLOB' with a default size of 4 bytes. */
pCol->affinity = affinity;
pCol->eCType = eType;
|
| ︙ | ︙ | |||
123583 123584 123585 123586 123587 123588 123589 123590 123591 |
zType = z + sqlite3Strlen30(z) + 1;
memcpy(zType, sType.z, sType.n);
zType[sType.n] = 0;
sqlite3Dequote(zType);
pCol->affinity = sqlite3AffinityType(zType, pCol);
pCol->colFlags |= COLFLAG_HASTYPE;
}
p->nCol++;
p->nNVCol++;
| > > > > > | | 123736 123737 123738 123739 123740 123741 123742 123743 123744 123745 123746 123747 123748 123749 123750 123751 123752 123753 123754 123755 123756 123757 |
zType = z + sqlite3Strlen30(z) + 1;
memcpy(zType, sType.z, sType.n);
zType[sType.n] = 0;
sqlite3Dequote(zType);
pCol->affinity = sqlite3AffinityType(zType, pCol);
pCol->colFlags |= COLFLAG_HASTYPE;
}
if( p->nCol<=0xff ){
u8 h = pCol->hName % sizeof(p->aHx);
p->aHx[h] = p->nCol;
}
p->nCol++;
p->nNVCol++;
assert( pParse->isCreate );
pParse->u1.cr.constraintName.n = 0;
}
/*
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement. A "NOT NULL" constraint has
** been seen on a column. This routine sets the notNull flag on
** the column currently under construction.
|
| ︙ | ︙ | |||
123849 123850 123851 123852 123853 123854 123855 |
}else{
nTerm = pList->nExpr;
for(i=0; i<nTerm; i++){
Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
assert( pCExpr!=0 );
sqlite3StringToId(pCExpr);
if( pCExpr->op==TK_ID ){
| < | | < | | < < | 124007 124008 124009 124010 124011 124012 124013 124014 124015 124016 124017 124018 124019 124020 124021 124022 124023 124024 124025 |
}else{
nTerm = pList->nExpr;
for(i=0; i<nTerm; i++){
Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
assert( pCExpr!=0 );
sqlite3StringToId(pCExpr);
if( pCExpr->op==TK_ID ){
assert( !ExprHasProperty(pCExpr, EP_IntValue) );
iCol = sqlite3ColumnIndex(pTab, pCExpr->u.zToken);
if( iCol>=0 ){
pCol = &pTab->aCol[iCol];
makeColumnPartOfPrimaryKey(pParse, pCol);
}
}
}
}
if( nTerm==1
&& pCol
&& pCol->eCType==COLTYPE_INTEGER
|
| ︙ | ︙ | |||
123909 123910 123911 123912 123913 123914 123915 |
#ifndef SQLITE_OMIT_CHECK
Table *pTab = pParse->pNewTable;
sqlite3 *db = pParse->db;
if( pTab && !IN_DECLARE_VTAB
&& !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt)
){
pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr);
| > | | > | 124063 124064 124065 124066 124067 124068 124069 124070 124071 124072 124073 124074 124075 124076 124077 124078 124079 124080 |
#ifndef SQLITE_OMIT_CHECK
Table *pTab = pParse->pNewTable;
sqlite3 *db = pParse->db;
if( pTab && !IN_DECLARE_VTAB
&& !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt)
){
pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr);
assert( pParse->isCreate );
if( pParse->u1.cr.constraintName.n ){
sqlite3ExprListSetName(pParse, pTab->pCheck,
&pParse->u1.cr.constraintName, 1);
}else{
Token t;
for(zStart++; sqlite3Isspace(zStart[0]); zStart++){}
while( sqlite3Isspace(zEnd[-1]) ){ zEnd--; }
t.z = zStart;
t.n = (int)(zEnd - t.z);
sqlite3ExprListSetName(pParse, pTab->pCheck, &t, 1);
|
| ︙ | ︙ | |||
124105 124106 124107 124108 124109 124110 124111 |
/*
** Generate a CREATE TABLE statement appropriate for the given
** table. Memory to hold the text of the statement is obtained
** from sqliteMalloc() and must be freed by the calling function.
*/
static char *createTableStmt(sqlite3 *db, Table *p){
| | > | 124261 124262 124263 124264 124265 124266 124267 124268 124269 124270 124271 124272 124273 124274 124275 124276 |
/*
** Generate a CREATE TABLE statement appropriate for the given
** table. Memory to hold the text of the statement is obtained
** from sqliteMalloc() and must be freed by the calling function.
*/
static char *createTableStmt(sqlite3 *db, Table *p){
int i, k, len;
i64 n;
char *zStmt;
char *zSep, *zSep2, *zEnd;
Column *pCol;
n = 0;
for(pCol = p->aCol, i=0; i<p->nCol; i++, pCol++){
n += identLength(pCol->zCnName) + 5;
}
|
| ︙ | ︙ | |||
124129 124130 124131 124132 124133 124134 124135 |
}
n += 35 + 6*p->nCol;
zStmt = sqlite3DbMallocRaw(0, n);
if( zStmt==0 ){
sqlite3OomFault(db);
return 0;
}
| > | | < > > | | > > > > | | 124286 124287 124288 124289 124290 124291 124292 124293 124294 124295 124296 124297 124298 124299 124300 124301 124302 124303 124304 124305 124306 124307 124308 124309 124310 124311 124312 124313 124314 124315 124316 124317 124318 124319 124320 124321 124322 124323 124324 124325 124326 124327 124328 124329 124330 124331 124332 124333 124334 124335 124336 124337 124338 124339 124340 124341 124342 124343 124344 |
}
n += 35 + 6*p->nCol;
zStmt = sqlite3DbMallocRaw(0, n);
if( zStmt==0 ){
sqlite3OomFault(db);
return 0;
}
assert( n>14 && n<=0x7fffffff );
memcpy(zStmt, "CREATE TABLE ", 13);
k = 13;
identPut(zStmt, &k, p->zName);
zStmt[k++] = '(';
for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
static const char * const azType[] = {
/* SQLITE_AFF_BLOB */ "",
/* SQLITE_AFF_TEXT */ " TEXT",
/* SQLITE_AFF_NUMERIC */ " NUM",
/* SQLITE_AFF_INTEGER */ " INT",
/* SQLITE_AFF_REAL */ " REAL",
/* SQLITE_AFF_FLEXNUM */ " NUM",
};
const char *zType;
len = sqlite3Strlen30(zSep);
assert( k+len<n );
memcpy(&zStmt[k], zSep, len);
k += len;
zSep = zSep2;
identPut(zStmt, &k, pCol->zCnName);
assert( k<n );
assert( pCol->affinity-SQLITE_AFF_BLOB >= 0 );
assert( pCol->affinity-SQLITE_AFF_BLOB < ArraySize(azType) );
testcase( pCol->affinity==SQLITE_AFF_BLOB );
testcase( pCol->affinity==SQLITE_AFF_TEXT );
testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
testcase( pCol->affinity==SQLITE_AFF_INTEGER );
testcase( pCol->affinity==SQLITE_AFF_REAL );
testcase( pCol->affinity==SQLITE_AFF_FLEXNUM );
zType = azType[pCol->affinity - SQLITE_AFF_BLOB];
len = sqlite3Strlen30(zType);
assert( pCol->affinity==SQLITE_AFF_BLOB
|| pCol->affinity==SQLITE_AFF_FLEXNUM
|| pCol->affinity==sqlite3AffinityType(zType, 0) );
assert( k+len<n );
memcpy(&zStmt[k], zType, len);
k += len;
assert( k<=n );
}
len = sqlite3Strlen30(zEnd);
assert( k+len<n );
memcpy(&zStmt[k], zEnd, len+1);
return zStmt;
}
/*
** Resize an Index object to hold N columns total. Return SQLITE_OK
** on success and SQLITE_NOMEM on an OOM error.
*/
|
| ︙ | ︙ | |||
124360 124361 124362 124363 124364 124365 124366 |
pTab->tabFlags |= TF_HasNotNull;
}
/* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
** into BTREE_BLOBKEY.
*/
assert( !pParse->bReturning );
| | | | 124523 124524 124525 124526 124527 124528 124529 124530 124531 124532 124533 124534 124535 124536 124537 124538 124539 |
pTab->tabFlags |= TF_HasNotNull;
}
/* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
** into BTREE_BLOBKEY.
*/
assert( !pParse->bReturning );
if( pParse->u1.cr.addrCrTab ){
assert( v );
sqlite3VdbeChangeP3(v, pParse->u1.cr.addrCrTab, BTREE_BLOBKEY);
}
/* Locate the PRIMARY KEY index. Or, if this table was originally
** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index.
*/
if( pTab->iPKey>=0 ){
ExprList *pList;
|
| ︙ | ︙ | |||
124802 124803 124804 124805 124806 124807 124808 |
zType = "view";
zType2 = "VIEW";
#endif
}
/* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
** statement to populate the new table. The root-page number for the
| | | 124965 124966 124967 124968 124969 124970 124971 124972 124973 124974 124975 124976 124977 124978 124979 |
zType = "view";
zType2 = "VIEW";
#endif
}
/* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
** statement to populate the new table. The root-page number for the
** new table is in register pParse->u1.cr.regRoot.
**
** Once the SELECT has been coded by sqlite3Select(), it is in a
** suitable state to query for the column names and types to be used
** by the new table.
**
** A shared-cache write-lock is not required to write to the new table,
** as a schema-lock must have already been obtained to create it. Since
|
| ︙ | ︙ | |||
124833 124834 124835 124836 124837 124838 124839 |
return;
}
iCsr = pParse->nTab++;
regYield = ++pParse->nMem;
regRec = ++pParse->nMem;
regRowid = ++pParse->nMem;
sqlite3MayAbort(pParse);
| > | | 124996 124997 124998 124999 125000 125001 125002 125003 125004 125005 125006 125007 125008 125009 125010 125011 |
return;
}
iCsr = pParse->nTab++;
regYield = ++pParse->nMem;
regRec = ++pParse->nMem;
regRowid = ++pParse->nMem;
sqlite3MayAbort(pParse);
assert( pParse->isCreate );
sqlite3VdbeAddOp3(v, OP_OpenWrite, iCsr, pParse->u1.cr.regRoot, iDb);
sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
addrTop = sqlite3VdbeCurrentAddr(v) + 1;
sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
if( pParse->nErr ) return;
pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect, SQLITE_AFF_BLOB);
if( pSelTab==0 ) return;
assert( p->aCol==0 );
|
| ︙ | ︙ | |||
124878 124879 124880 124881 124882 124883 124884 124885 124886 124887 124888 124889 124890 124891 124892 |
);
}
/* A slot for the record has already been allocated in the
** schema table. We just need to update that slot with all
** the information we've collected.
*/
sqlite3NestedParse(pParse,
"UPDATE %Q." LEGACY_SCHEMA_TABLE
" SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q"
" WHERE rowid=#%d",
db->aDb[iDb].zDbSName,
zType,
p->zName,
p->zName,
| > | | | 125042 125043 125044 125045 125046 125047 125048 125049 125050 125051 125052 125053 125054 125055 125056 125057 125058 125059 125060 125061 125062 125063 125064 125065 125066 125067 |
);
}
/* A slot for the record has already been allocated in the
** schema table. We just need to update that slot with all
** the information we've collected.
*/
assert( pParse->isCreate );
sqlite3NestedParse(pParse,
"UPDATE %Q." LEGACY_SCHEMA_TABLE
" SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q"
" WHERE rowid=#%d",
db->aDb[iDb].zDbSName,
zType,
p->zName,
p->zName,
pParse->u1.cr.regRoot,
zStmt,
pParse->u1.cr.regRowid
);
sqlite3DbFree(db, zStmt);
sqlite3ChangeCookie(pParse, iDb);
#ifndef SQLITE_OMIT_AUTOINCREMENT
/* Check to see if we need to create an sqlite_sequence table for
** keeping track of autoincrement keys.
|
| ︙ | ︙ | |||
125859 125860 125861 125862 125863 125864 125865 |
SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(
sqlite3 *db, /* Database connection */
i16 nCol, /* Total number of columns in the index */
int nExtra, /* Number of bytes of extra space to alloc */
char **ppExtra /* Pointer to the "extra" space */
){
Index *p; /* Allocated index object */
| | | 126024 126025 126026 126027 126028 126029 126030 126031 126032 126033 126034 126035 126036 126037 126038 |
SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(
sqlite3 *db, /* Database connection */
i16 nCol, /* Total number of columns in the index */
int nExtra, /* Number of bytes of extra space to alloc */
char **ppExtra /* Pointer to the "extra" space */
){
Index *p; /* Allocated index object */
i64 nByte; /* Bytes of space for Index object + arrays */
nByte = ROUND8(sizeof(Index)) + /* Index structure */
ROUND8(sizeof(char*)*nCol) + /* Index.azColl */
ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */
sizeof(i16)*nCol + /* Index.aiColumn */
sizeof(u8)*nCol); /* Index.aSortOrder */
p = sqlite3DbMallocZero(db, nByte + nExtra);
|
| ︙ | ︙ | |||
126712 126713 126714 126715 126716 126717 126718 |
/*
** Delete an IdList.
*/
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
int i;
assert( db!=0 );
if( pList==0 ) return;
| < | 126877 126878 126879 126880 126881 126882 126883 126884 126885 126886 126887 126888 126889 126890 |
/*
** Delete an IdList.
*/
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
int i;
assert( db!=0 );
if( pList==0 ) return;
for(i=0; i<pList->nId; i++){
sqlite3DbFree(db, pList->a[i].zName);
}
sqlite3DbNNFreeNN(db, pList);
}
/*
|
| ︙ | ︙ | |||
128093 128094 128095 128096 128097 128098 128099 |
#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */
static int matchQuality(
FuncDef *p, /* The function we are evaluating for match quality */
int nArg, /* Desired number of arguments. (-1)==any */
u8 enc /* Desired text encoding */
){
int match;
| | > | > > > > > | 128257 128258 128259 128260 128261 128262 128263 128264 128265 128266 128267 128268 128269 128270 128271 128272 128273 128274 128275 128276 128277 128278 128279 128280 128281 128282 |
#define FUNC_PERFECT_MATCH 6 /* The score for a perfect match */
static int matchQuality(
FuncDef *p, /* The function we are evaluating for match quality */
int nArg, /* Desired number of arguments. (-1)==any */
u8 enc /* Desired text encoding */
){
int match;
assert( p->nArg>=(-4) && p->nArg!=(-2) );
assert( nArg>=(-2) );
/* Wrong number of arguments means "no match" */
if( p->nArg!=nArg ){
if( nArg==(-2) ) return p->xSFunc==0 ? 0 : FUNC_PERFECT_MATCH;
if( p->nArg>=0 ) return 0;
/* Special p->nArg values available to built-in functions only:
** -3 1 or more arguments required
** -4 2 or more arguments required
*/
if( p->nArg<(-2) && nArg<(-2-p->nArg) ) return 0;
}
/* Give a better score to a function with a specific number of arguments
** than to function that accepts any number of arguments. */
if( p->nArg==nArg ){
match = 4;
}else{
|
| ︙ | ︙ | |||
129721 129722 129723 129724 129725 129726 129727 |
sqlite3_value **argv
){
const unsigned char *z;
const unsigned char *z2;
int len;
int p0type;
i64 p1, p2;
| < < < < < < | < < < < < < < < | | < < < > > > > > > > > > > > > > > | < > | < | | > | > | > > | | | | | 129891 129892 129893 129894 129895 129896 129897 129898 129899 129900 129901 129902 129903 129904 129905 129906 129907 129908 129909 129910 129911 129912 129913 129914 129915 129916 129917 129918 129919 129920 129921 129922 129923 129924 129925 129926 129927 129928 129929 129930 129931 129932 129933 129934 129935 129936 129937 129938 129939 129940 129941 129942 129943 129944 129945 129946 129947 129948 129949 129950 129951 129952 129953 129954 129955 129956 129957 129958 129959 129960 129961 129962 129963 129964 129965 129966 129967 129968 129969 129970 129971 129972 129973 129974 129975 129976 129977 129978 129979 129980 129981 129982 129983 129984 129985 129986 129987 129988 129989 129990 129991 129992 129993 129994 129995 129996 129997 129998 129999 130000 130001 130002 130003 130004 130005 130006 130007 130008 130009 130010 130011 130012 |
sqlite3_value **argv
){
const unsigned char *z;
const unsigned char *z2;
int len;
int p0type;
i64 p1, p2;
assert( argc==3 || argc==2 );
p0type = sqlite3_value_type(argv[0]);
p1 = sqlite3_value_int64(argv[1]);
if( p0type==SQLITE_BLOB ){
len = sqlite3_value_bytes(argv[0]);
z = sqlite3_value_blob(argv[0]);
if( z==0 ) return;
assert( len==sqlite3_value_bytes(argv[0]) );
}else{
z = sqlite3_value_text(argv[0]);
if( z==0 ) return;
len = 0;
if( p1<0 ){
for(z2=z; *z2; len++){
SQLITE_SKIP_UTF8(z2);
}
}
}
if( argc==3 ){
p2 = sqlite3_value_int64(argv[2]);
if( p2==0 && sqlite3_value_type(argv[2])==SQLITE_NULL ) return;
}else{
p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH];
}
if( p1==0 ){
#ifdef SQLITE_SUBSTR_COMPATIBILITY
/* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as
** as substr(X,1,N) - it returns the first N characters of X. This
** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8]
** from 2009-02-02 for compatibility of applications that exploited the
** old buggy behavior. */
p1 = 1; /* <rdar://problem/6778339> */
#endif
if( sqlite3_value_type(argv[1])==SQLITE_NULL ) return;
}
if( p1<0 ){
p1 += len;
if( p1<0 ){
if( p2<0 ){
p2 = 0;
}else{
p2 += p1;
}
p1 = 0;
}
}else if( p1>0 ){
p1--;
}else if( p2>0 ){
p2--;
}
if( p2<0 ){
if( p2<-p1 ){
p2 = p1;
}else{
p2 = -p2;
}
p1 -= p2;
}
assert( p1>=0 && p2>=0 );
if( p0type!=SQLITE_BLOB ){
while( *z && p1 ){
SQLITE_SKIP_UTF8(z);
p1--;
}
for(z2=z; *z2 && p2; p2--){
SQLITE_SKIP_UTF8(z2);
}
sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT,
SQLITE_UTF8);
}else{
if( p1>=len ){
p1 = p2 = 0;
}else if( p2>len-p1 ){
p2 = len-p1;
assert( p2>0 );
}
sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT);
}
}
/*
** Implementation of the round() function
*/
#ifndef SQLITE_OMIT_FLOATING_POINT
static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
i64 n = 0;
double r;
char *zBuf;
assert( argc==1 || argc==2 );
if( argc==2 ){
if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
n = sqlite3_value_int64(argv[1]);
if( n>30 ) n = 30;
if( n<0 ) n = 0;
}
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
r = sqlite3_value_double(argv[0]);
/* If Y==0 and X will fit in a 64-bit int,
** handle the rounding directly,
** otherwise use printf.
*/
if( r<-4503599627370496.0 || r>+4503599627370496.0 ){
/* The value has no fractional part so there is nothing to round */
}else if( n==0 ){
r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5)));
}else{
zBuf = sqlite3_mprintf("%!.*f",(int)n,r);
if( zBuf==0 ){
sqlite3_result_error_nomem(context);
return;
}
sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8);
sqlite3_free(zBuf);
}
|
| ︙ | ︙ | |||
130787 130788 130789 130790 130791 130792 130793 | assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */ zRep = sqlite3_value_text(argv[2]); if( zRep==0 ) return; nRep = sqlite3_value_bytes(argv[2]); assert( zRep==sqlite3_value_text(argv[2]) ); nOut = nStr + 1; assert( nOut<SQLITE_MAX_LENGTH ); | | | 130957 130958 130959 130960 130961 130962 130963 130964 130965 130966 130967 130968 130969 130970 130971 |
assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */
zRep = sqlite3_value_text(argv[2]);
if( zRep==0 ) return;
nRep = sqlite3_value_bytes(argv[2]);
assert( zRep==sqlite3_value_text(argv[2]) );
nOut = nStr + 1;
assert( nOut<SQLITE_MAX_LENGTH );
zOut = contextMalloc(context, nOut);
if( zOut==0 ){
return;
}
loopLimit = nStr - nPattern;
cntExpand = 0;
for(i=j=0; i<=loopLimit; i++){
if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
|
| ︙ | ︙ | |||
130937 130938 130939 130940 130941 130942 130943 |
){
i64 j, k, n = 0;
int i;
char *z;
for(i=0; i<argc; i++){
n += sqlite3_value_bytes(argv[i]);
}
| | | 131107 131108 131109 131110 131111 131112 131113 131114 131115 131116 131117 131118 131119 131120 131121 |
){
i64 j, k, n = 0;
int i;
char *z;
for(i=0; i<argc; i++){
n += sqlite3_value_bytes(argv[i]);
}
n += (argc-1)*(i64)nSep;
z = sqlite3_malloc64(n+1);
if( z==0 ){
sqlite3_result_error_nomem(context);
return;
}
j = 0;
for(i=0; i<argc; i++){
|
| ︙ | ︙ | |||
131235 131236 131237 131238 131239 131240 131241 |
type = sqlite3_value_numeric_type(argv[0]);
/* p is always non-NULL because sumStep() will have been called first
** to initialize it */
if( ALWAYS(p) && type!=SQLITE_NULL ){
assert( p->cnt>0 );
p->cnt--;
if( !p->approx ){
| | > > > | 131405 131406 131407 131408 131409 131410 131411 131412 131413 131414 131415 131416 131417 131418 131419 131420 131421 131422 |
type = sqlite3_value_numeric_type(argv[0]);
/* p is always non-NULL because sumStep() will have been called first
** to initialize it */
if( ALWAYS(p) && type!=SQLITE_NULL ){
assert( p->cnt>0 );
p->cnt--;
if( !p->approx ){
if( sqlite3SubInt64(&p->iSum, sqlite3_value_int64(argv[0])) ){
p->ovrfl = 1;
p->approx = 1;
}
}else if( type==SQLITE_INTEGER ){
i64 iVal = sqlite3_value_int64(argv[0]);
if( iVal!=SMALLEST_INT64 ){
kahanBabuskaNeumaierStepInt64(p, -iVal);
}else{
kahanBabuskaNeumaierStepInt64(p, LARGEST_INT64);
kahanBabuskaNeumaierStepInt64(p, 1);
|
| ︙ | ︙ | |||
132061 132062 132063 132064 132065 132066 132067 |
#endif
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
FUNCTION(trim, 1, 3, 0, trimFunc ),
FUNCTION(trim, 2, 3, 0, trimFunc ),
| | < | < | 132234 132235 132236 132237 132238 132239 132240 132241 132242 132243 132244 132245 132246 132247 132248 132249 132250 132251 |
#endif
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
FUNCTION(trim, 1, 3, 0, trimFunc ),
FUNCTION(trim, 2, 3, 0, trimFunc ),
FUNCTION(min, -3, 0, 1, minmaxFunc ),
WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ),
FUNCTION(max, -3, 1, 1, minmaxFunc ),
WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ),
FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF),
FUNCTION2(subtype, 1, 0, 0, subtypeFunc,
SQLITE_FUNC_TYPEOF|SQLITE_SUBTYPE),
FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH),
FUNCTION2(octet_length, 1, 0, 0, bytelengthFunc,SQLITE_FUNC_BYTELEN),
|
| ︙ | ︙ | |||
132093 132094 132095 132096 132097 132098 132099 |
FUNCTION(round, 2, 0, 0, roundFunc ),
#endif
FUNCTION(upper, 1, 0, 0, upperFunc ),
FUNCTION(lower, 1, 0, 0, lowerFunc ),
FUNCTION(hex, 1, 0, 0, hexFunc ),
FUNCTION(unhex, 1, 0, 0, unhexFunc ),
FUNCTION(unhex, 2, 0, 0, unhexFunc ),
| | < | < < | 132264 132265 132266 132267 132268 132269 132270 132271 132272 132273 132274 132275 132276 132277 132278 132279 |
FUNCTION(round, 2, 0, 0, roundFunc ),
#endif
FUNCTION(upper, 1, 0, 0, upperFunc ),
FUNCTION(lower, 1, 0, 0, lowerFunc ),
FUNCTION(hex, 1, 0, 0, hexFunc ),
FUNCTION(unhex, 1, 0, 0, unhexFunc ),
FUNCTION(unhex, 2, 0, 0, unhexFunc ),
FUNCTION(concat, -3, 0, 0, concatFunc ),
FUNCTION(concat_ws, -4, 0, 0, concatwsFunc ),
INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ),
VFUNCTION(random, 0, 0, 0, randomFunc ),
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
DFUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
DFUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
FUNCTION(sqlite_log, 2, 0, 0, errlogFunc ),
|
| ︙ | ︙ | |||
132141 132142 132143 132144 132145 132146 132147 |
#else
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
#endif
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
FUNCTION(unknown, -1, 0, 0, unknownFunc ),
#endif
| < < | 132309 132310 132311 132312 132313 132314 132315 132316 132317 132318 132319 132320 132321 132322 |
#else
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
#endif
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
FUNCTION(unknown, -1, 0, 0, unknownFunc ),
#endif
#ifdef SQLITE_ENABLE_MATH_FUNCTIONS
MFUNCTION(ceil, 1, xCeil, ceilingFunc ),
MFUNCTION(ceiling, 1, xCeil, ceilingFunc ),
MFUNCTION(floor, 1, xFloor, ceilingFunc ),
#if SQLITE_HAVE_C99_MATH_FUNCS
MFUNCTION(trunc, 1, trunc, ceilingFunc ),
#endif
|
| ︙ | ︙ | |||
132180 132181 132182 132183 132184 132185 132186 |
#endif
MFUNCTION(sqrt, 1, sqrt, math1Func ),
MFUNCTION(radians, 1, degToRad, math1Func ),
MFUNCTION(degrees, 1, radToDeg, math1Func ),
MFUNCTION(pi, 0, 0, piFunc ),
#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */
FUNCTION(sign, 1, 0, 0, signFunc ),
| | | < | < | 132346 132347 132348 132349 132350 132351 132352 132353 132354 132355 132356 132357 132358 132359 132360 132361 132362 |
#endif
MFUNCTION(sqrt, 1, sqrt, math1Func ),
MFUNCTION(radians, 1, degToRad, math1Func ),
MFUNCTION(degrees, 1, radToDeg, math1Func ),
MFUNCTION(pi, 0, 0, piFunc ),
#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */
FUNCTION(sign, 1, 0, 0, signFunc ),
INLINE_FUNC(coalesce, -4, INLINEFUNC_coalesce, 0 ),
INLINE_FUNC(iif, -4, INLINEFUNC_iif, 0 ),
INLINE_FUNC(if, -4, INLINEFUNC_iif, 0 ),
};
#ifndef SQLITE_OMIT_ALTERTABLE
sqlite3AlterFunctions();
#endif
sqlite3WindowFunctions();
sqlite3RegisterDateTimeFunctions();
sqlite3RegisterJsonFunctions();
|
| ︙ | ︙ | |||
134630 134631 134632 134633 134634 134635 134636 134637 134638 134639 134640 134641 134642 134643 | int regFromSelect = 0;/* Base register for data coming from SELECT */ int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ int regRowCount = 0; /* Memory cell used for the row counter */ int regIns; /* Block of regs holding rowid+data being inserted */ int regRowid; /* registers holding insert rowid */ int regData; /* register holding first column to insert */ int *aRegIdx = 0; /* One register allocated to each index */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to insert into a view */ Trigger *pTrigger; /* List of triggers on pTab, if required */ int tmask; /* Mask of trigger times */ #endif | > | 134794 134795 134796 134797 134798 134799 134800 134801 134802 134803 134804 134805 134806 134807 134808 | int regFromSelect = 0;/* Base register for data coming from SELECT */ int regAutoinc = 0; /* Register holding the AUTOINCREMENT counter */ int regRowCount = 0; /* Memory cell used for the row counter */ int regIns; /* Block of regs holding rowid+data being inserted */ int regRowid; /* registers holding insert rowid */ int regData; /* register holding first column to insert */ int *aRegIdx = 0; /* One register allocated to each index */ int *aTabColMap = 0; /* Mapping from pTab columns to pCol entries */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to insert into a view */ Trigger *pTrigger; /* List of triggers on pTab, if required */ int tmask; /* Mask of trigger times */ #endif |
| ︙ | ︙ | |||
134774 134775 134776 134777 134778 134779 134780 |
** bIdListInOrder is true if the columns in IDLIST are in storage
** order. This enables an optimization that avoids shuffling the
** columns into storage order. False negatives are harmless,
** but false positives will cause database corruption.
*/
bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0;
if( pColumn ){
| | | | < < < < | > | | | | | | | | | | < | < < | 134939 134940 134941 134942 134943 134944 134945 134946 134947 134948 134949 134950 134951 134952 134953 134954 134955 134956 134957 134958 134959 134960 134961 134962 134963 134964 134965 134966 134967 134968 134969 134970 134971 |
** bIdListInOrder is true if the columns in IDLIST are in storage
** order. This enables an optimization that avoids shuffling the
** columns into storage order. False negatives are harmless,
** but false positives will cause database corruption.
*/
bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0;
if( pColumn ){
aTabColMap = sqlite3DbMallocZero(db, pTab->nCol*sizeof(int));
if( aTabColMap==0 ) goto insert_cleanup;
for(i=0; i<pColumn->nId; i++){
j = sqlite3ColumnIndex(pTab, pColumn->a[i].zName);
if( j>=0 ){
if( aTabColMap[j]==0 ) aTabColMap[j] = i+1;
if( i!=j ) bIdListInOrder = 0;
if( j==pTab->iPKey ){
ipkColumn = i; assert( !withoutRowid );
}
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){
sqlite3ErrorMsg(pParse,
"cannot INSERT into generated column \"%s\"",
pTab->aCol[j].zCnName);
goto insert_cleanup;
}
#endif
}else{
if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){
ipkColumn = i;
bIdListInOrder = 0;
}else{
sqlite3ErrorMsg(pParse, "table %S has no column named %s",
pTabList->a, pColumn->a[i].zName);
pParse->checkSchema = 1;
|
| ︙ | ︙ | |||
135096 135097 135098 135099 135100 135101 135102 |
** initialized to NULL to avoid an uninitialized register read */
if( tmask & TRIGGER_BEFORE ){
sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
}
continue;
}else if( pColumn==0 ){
/* Hidden columns that are not explicitly named in the INSERT
| | | | | | | 135255 135256 135257 135258 135259 135260 135261 135262 135263 135264 135265 135266 135267 135268 135269 135270 135271 135272 135273 135274 135275 135276 135277 135278 135279 135280 135281 135282 135283 135284 135285 135286 135287 |
** initialized to NULL to avoid an uninitialized register read */
if( tmask & TRIGGER_BEFORE ){
sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore);
}
continue;
}else if( pColumn==0 ){
/* Hidden columns that are not explicitly named in the INSERT
** get their default value */
sqlite3ExprCodeFactorable(pParse,
sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
iRegStore);
continue;
}
}
if( pColumn ){
j = aTabColMap[i];
assert( j>=0 && j<=pColumn->nId );
if( j==0 ){
/* A column not named in the insert column list gets its
** default value */
sqlite3ExprCodeFactorable(pParse,
sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
iRegStore);
continue;
}
k = j - 1;
}else if( nColumn==0 ){
/* This is INSERT INTO ... DEFAULT VALUES. Load the default value. */
sqlite3ExprCodeFactorable(pParse,
sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
iRegStore);
continue;
}else{
|
| ︙ | ︙ | |||
135359 135360 135361 135362 135363 135364 135365 | } insert_cleanup: sqlite3SrcListDelete(db, pTabList); sqlite3ExprListDelete(db, pList); sqlite3UpsertDelete(db, pUpsert); sqlite3SelectDelete(db, pSelect); | > | > > | 135518 135519 135520 135521 135522 135523 135524 135525 135526 135527 135528 135529 135530 135531 135532 135533 135534 135535 |
}
insert_cleanup:
sqlite3SrcListDelete(db, pTabList);
sqlite3ExprListDelete(db, pList);
sqlite3UpsertDelete(db, pUpsert);
sqlite3SelectDelete(db, pSelect);
if( pColumn ){
sqlite3IdListDelete(db, pColumn);
sqlite3DbFree(db, aTabColMap);
}
if( aRegIdx ) sqlite3DbNNFreeNN(db, aRegIdx);
}
/* Make sure "isView" and other macros defined above are undefined. Otherwise
** they may interfere with compilation of other functions in this file
** (or in another file, if this file becomes part of the amalgamation). */
#ifdef isView
|
| ︙ | ︙ | |||
140706 140707 140708 140709 140710 140711 140712 |
if( (mask & SQLITE_WriteSchema)==0
|| (db->flags & SQLITE_Defensive)==0
){
db->flags |= mask;
}
}else{
db->flags &= ~mask;
| | > > > | 140868 140869 140870 140871 140872 140873 140874 140875 140876 140877 140878 140879 140880 140881 140882 140883 140884 140885 |
if( (mask & SQLITE_WriteSchema)==0
|| (db->flags & SQLITE_Defensive)==0
){
db->flags |= mask;
}
}else{
db->flags &= ~mask;
if( mask==SQLITE_DeferFKs ){
db->nDeferredImmCons = 0;
db->nDeferredCons = 0;
}
if( (mask & SQLITE_WriteSchema)!=0
&& sqlite3_stricmp(zRight, "reset")==0
){
/* IMP: R-60817-01178 If the argument is "RESET" then schema
** writing is disabled (as with "PRAGMA writable_schema=OFF") and,
** in addition, the schema is reloaded. */
sqlite3ResetAllSchemasOfConnection(db);
|
| ︙ | ︙ | |||
141314 141315 141316 141317 141318 141319 141320 |
/* Make sure sufficient number of registers have been allocated */
sqlite3TouchRegister(pParse, 8+cnt);
sqlite3VdbeAddOp3(v, OP_Null, 0, 8, 8+cnt);
sqlite3ClearTempRegCache(pParse);
/* Do the b-tree integrity checks */
sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY);
| | | 141479 141480 141481 141482 141483 141484 141485 141486 141487 141488 141489 141490 141491 141492 141493 |
/* Make sure sufficient number of registers have been allocated */
sqlite3TouchRegister(pParse, 8+cnt);
sqlite3VdbeAddOp3(v, OP_Null, 0, 8, 8+cnt);
sqlite3ClearTempRegCache(pParse);
/* Do the b-tree integrity checks */
sqlite3VdbeAddOp4(v, OP_IntegrityCk, 1, cnt, 8, (char*)aRoot,P4_INTARRAY);
sqlite3VdbeChangeP5(v, (u16)i);
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName),
P4_DYNAMIC);
sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3);
integrityCheckResultRow(v);
sqlite3VdbeJumpHere(v, addr);
|
| ︙ | ︙ | |||
144040 144041 144042 144043 144044 144045 144046 |
/*
** Return the index of a column in a table. Return -1 if the column
** is not contained in the table.
*/
SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){
int i;
| > > > > | > > | > > > > > > > > | > > > > | > > > > > | 144205 144206 144207 144208 144209 144210 144211 144212 144213 144214 144215 144216 144217 144218 144219 144220 144221 144222 144223 144224 144225 144226 144227 144228 144229 144230 144231 144232 144233 144234 144235 144236 144237 144238 144239 144240 144241 144242 144243 144244 144245 |
/*
** Return the index of a column in a table. Return -1 if the column
** is not contained in the table.
*/
SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){
int i;
u8 h;
const Column *aCol;
int nCol;
h = sqlite3StrIHash(zCol);
aCol = pTab->aCol;
nCol = pTab->nCol;
/* See if the aHx gives us a lucky match */
i = pTab->aHx[h % sizeof(pTab->aHx)];
assert( i<nCol );
if( aCol[i].hName==h
&& sqlite3StrICmp(aCol[i].zCnName, zCol)==0
){
return i;
}
/* No lucky match from the hash table. Do a full search. */
i = 0;
while( 1 /*exit-by-break*/ ){
if( aCol[i].hName==h
&& sqlite3StrICmp(aCol[i].zCnName, zCol)==0
){
return i;
}
i++;
if( i>=nCol ) break;
}
return -1;
}
/*
** Mark a subquery result column as having been used.
*/
|
| ︙ | ︙ | |||
150547 150548 150549 150550 150551 150552 150553 |
sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype);
sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j);
}
sqlite3ReleaseTempReg(pParse, regSubtype);
}
sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i));
sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
| | | 150735 150736 150737 150738 150739 150740 150741 150742 150743 150744 150745 150746 150747 150748 150749 |
sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype);
sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j);
}
sqlite3ReleaseTempReg(pParse, regSubtype);
}
sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i));
sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u16)nArg);
sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v);
sqlite3VdbeJumpHere(v, iTop);
sqlite3ReleaseTempRange(pParse, regAgg, nArg);
}
sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i),
pList ? pList->nExpr : 0);
sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
|
| ︙ | ︙ | |||
150710 150711 150712 150713 150714 150715 150716 |
}
if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0,
(char *)pColl, P4_COLLSEQ);
}
sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i));
sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
| | | 150898 150899 150900 150901 150902 150903 150904 150905 150906 150907 150908 150909 150910 150911 150912 |
}
if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem;
sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0,
(char *)pColl, P4_COLLSEQ);
}
sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i));
sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u16)nArg);
sqlite3ReleaseTempRange(pParse, regAgg, nArg);
}
if( addrNext ){
sqlite3VdbeResolveLabel(v, addrNext);
}
if( pParse->nErr ) return;
}
|
| ︙ | ︙ | |||
152765 152766 152767 152768 152769 152770 152771 |
pTrig->pNext = pList;
pList = pTrig;
}else if( pTrig->op==TK_RETURNING ){
#ifndef SQLITE_OMIT_VIRTUALTABLE
assert( pParse->db->pVtabCtx==0 );
#endif
assert( pParse->bReturning );
| > | | 152953 152954 152955 152956 152957 152958 152959 152960 152961 152962 152963 152964 152965 152966 152967 152968 |
pTrig->pNext = pList;
pList = pTrig;
}else if( pTrig->op==TK_RETURNING ){
#ifndef SQLITE_OMIT_VIRTUALTABLE
assert( pParse->db->pVtabCtx==0 );
#endif
assert( pParse->bReturning );
assert( !pParse->isCreate );
assert( &(pParse->u1.d.pReturning->retTrig) == pTrig );
pTrig->table = pTab->zName;
pTrig->pTabSchema = pTab->pSchema;
pTrig->pNext = pList;
pList = pTrig;
}
p = sqliteHashNext(p);
}
|
| ︙ | ︙ | |||
153742 153743 153744 153745 153746 153747 153748 |
assert( v!=0 );
if( !pParse->bReturning ){
/* This RETURNING trigger must be for a different statement as
** this statement lacks a RETURNING clause. */
return;
}
assert( db->pParse==pParse );
| > | | 153931 153932 153933 153934 153935 153936 153937 153938 153939 153940 153941 153942 153943 153944 153945 153946 |
assert( v!=0 );
if( !pParse->bReturning ){
/* This RETURNING trigger must be for a different statement as
** this statement lacks a RETURNING clause. */
return;
}
assert( db->pParse==pParse );
assert( !pParse->isCreate );
pReturning = pParse->u1.d.pReturning;
if( pTrigger != &(pReturning->retTrig) ){
/* This RETURNING trigger is for a different statement */
return;
}
memset(&sSelect, 0, sizeof(sSelect));
memset(&sFrom, 0, sizeof(sFrom));
sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0);
|
| ︙ | ︙ | |||
153972 153973 153974 153975 153976 153977 153978 153979 153980 153981 153982 153983 153984 153985 |
sNC.pParse = &sSubParse;
sSubParse.pTriggerTab = pTab;
sSubParse.pToplevel = pTop;
sSubParse.zAuthContext = pTrigger->zName;
sSubParse.eTriggerOp = pTrigger->op;
sSubParse.nQueryLoop = pParse->nQueryLoop;
sSubParse.prepFlags = pParse->prepFlags;
v = sqlite3GetVdbe(&sSubParse);
if( v ){
VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)",
pTrigger->zName, onErrorText(orconf),
(pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
(pTrigger->op==TK_UPDATE ? "UPDATE" : ""),
| > > | 154162 154163 154164 154165 154166 154167 154168 154169 154170 154171 154172 154173 154174 154175 154176 154177 |
sNC.pParse = &sSubParse;
sSubParse.pTriggerTab = pTab;
sSubParse.pToplevel = pTop;
sSubParse.zAuthContext = pTrigger->zName;
sSubParse.eTriggerOp = pTrigger->op;
sSubParse.nQueryLoop = pParse->nQueryLoop;
sSubParse.prepFlags = pParse->prepFlags;
sSubParse.oldmask = 0;
sSubParse.newmask = 0;
v = sqlite3GetVdbe(&sSubParse);
if( v ){
VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)",
pTrigger->zName, onErrorText(orconf),
(pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
(pTrigger->op==TK_UPDATE ? "UPDATE" : ""),
|
| ︙ | ︙ | |||
154104 154105 154106 154107 154108 154109 154110 |
(v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf)));
/* Set the P5 operand of the OP_Program instruction to non-zero if
** recursive invocation of this trigger program is disallowed. Recursive
** invocation is disallowed if (a) the sub-program is really a trigger,
** not a foreign key action, and (b) the flag to enable recursive triggers
** is clear. */
| | | 154296 154297 154298 154299 154300 154301 154302 154303 154304 154305 154306 154307 154308 154309 154310 |
(v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf)));
/* Set the P5 operand of the OP_Program instruction to non-zero if
** recursive invocation of this trigger program is disallowed. Recursive
** invocation is disallowed if (a) the sub-program is really a trigger,
** not a foreign key action, and (b) the flag to enable recursive triggers
** is clear. */
sqlite3VdbeChangeP5(v, (u16)bRecursive);
}
}
/*
** This is called to code the required FOR EACH ROW triggers for an operation
** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE)
** is given by the op parameter. The tr_tm parameter determines whether the
|
| ︙ | ︙ | |||
154726 154727 154728 154729 154730 154731 154732 |
** of the UPDATE statement. Also find the column index
** for each column to be updated in the pChanges array. For each
** column to be updated, make sure we have authorization to change
** that column.
*/
chngRowid = chngPk = 0;
for(i=0; i<pChanges->nExpr; i++){
| < < < | | | | | | | | | | | | | | | | | | < | < < | 154918 154919 154920 154921 154922 154923 154924 154925 154926 154927 154928 154929 154930 154931 154932 154933 154934 154935 154936 154937 154938 154939 154940 154941 154942 154943 154944 154945 154946 154947 154948 154949 154950 154951 154952 154953 154954 154955 154956 154957 |
** of the UPDATE statement. Also find the column index
** for each column to be updated in the pChanges array. For each
** column to be updated, make sure we have authorization to change
** that column.
*/
chngRowid = chngPk = 0;
for(i=0; i<pChanges->nExpr; i++){
/* If this is an UPDATE with a FROM clause, do not resolve expressions
** here. The call to sqlite3Select() below will do that. */
if( nChangeFrom==0 && sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){
goto update_cleanup;
}
j = sqlite3ColumnIndex(pTab, pChanges->a[i].zEName);
if( j>=0 ){
if( j==pTab->iPKey ){
chngRowid = 1;
pRowidExpr = pChanges->a[i].pExpr;
iRowidExpr = i;
}else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){
chngPk = 1;
}
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){
testcase( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL );
testcase( pTab->aCol[j].colFlags & COLFLAG_STORED );
sqlite3ErrorMsg(pParse,
"cannot UPDATE generated column \"%s\"",
pTab->aCol[j].zCnName);
goto update_cleanup;
}
#endif
aXRef[j] = i;
}else{
if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zEName) ){
j = -1;
chngRowid = 1;
pRowidExpr = pChanges->a[i].pExpr;
iRowidExpr = i;
}else{
sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zEName);
|
| ︙ | ︙ | |||
156864 156865 156866 156867 156868 156869 156870 |
}
zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
/* A slot for the record has already been allocated in the
** schema table. We just need to update that slot with all
** the information we've collected.
**
| | > | | 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 |
}
zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken);
/* A slot for the record has already been allocated in the
** schema table. We just need to update that slot with all
** the information we've collected.
**
** The VM register number pParse->u1.cr.regRowid holds the rowid of an
** entry in the sqlite_schema table that was created for this vtab
** by sqlite3StartTable().
*/
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
assert( pParse->isCreate );
sqlite3NestedParse(pParse,
"UPDATE %Q." LEGACY_SCHEMA_TABLE " "
"SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
"WHERE rowid=#%d",
db->aDb[iDb].zDbSName,
pTab->zName,
pTab->zName,
zStmt,
pParse->u1.cr.regRowid
);
v = sqlite3GetVdbe(pParse);
sqlite3ChangeCookie(pParse, iDb);
sqlite3VdbeAddOp0(v, OP_Expire);
zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt);
sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere, 0);
|
| ︙ | ︙ | |||
157215 157216 157217 157218 157219 157220 157221 |
/* Verify that the first two keywords in the CREATE TABLE statement
** really are "CREATE" and "TABLE". If this is not the case, then
** sqlite3_declare_vtab() is being misused.
*/
z = (const unsigned char*)zCreateTable;
for(i=0; aKeyword[i]; i++){
int tokenType = 0;
| > | > | 157402 157403 157404 157405 157406 157407 157408 157409 157410 157411 157412 157413 157414 157415 157416 157417 157418 |
/* Verify that the first two keywords in the CREATE TABLE statement
** really are "CREATE" and "TABLE". If this is not the case, then
** sqlite3_declare_vtab() is being misused.
*/
z = (const unsigned char*)zCreateTable;
for(i=0; aKeyword[i]; i++){
int tokenType = 0;
do{
z += sqlite3GetToken(z, &tokenType);
}while( tokenType==TK_SPACE || tokenType==TK_COMMENT );
if( tokenType!=aKeyword[i] ){
sqlite3ErrorWithMsg(db, SQLITE_ERROR, "syntax error");
return SQLITE_ERROR;
}
}
sqlite3_mutex_enter(db->mutex);
|
| ︙ | ︙ | |||
157946 157947 157948 157949 157950 157951 157952 157953 | } u; u32 wsFlags; /* WHERE_* flags describing the plan */ u16 nLTerm; /* Number of entries in aLTerm[] */ u16 nSkip; /* Number of NULL aLTerm[] entries */ /**** whereLoopXfer() copies fields above ***********************/ # define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot) u16 nLSlot; /* Number of slots allocated for aLTerm[] */ LogEst rStarDelta; /* Cost delta due to star-schema heuristic. Not | > | > | 158135 158136 158137 158138 158139 158140 158141 158142 158143 158144 158145 158146 158147 158148 158149 158150 158151 158152 |
} u;
u32 wsFlags; /* WHERE_* flags describing the plan */
u16 nLTerm; /* Number of entries in aLTerm[] */
u16 nSkip; /* Number of NULL aLTerm[] entries */
/**** whereLoopXfer() copies fields above ***********************/
# define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot)
u16 nLSlot; /* Number of slots allocated for aLTerm[] */
#ifdef WHERETRACE_ENABLED
LogEst rStarDelta; /* Cost delta due to star-schema heuristic. Not
** initialized unless pWInfo->bStarUsed */
#endif
WhereTerm **aLTerm; /* WhereTerms used */
WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
WhereTerm *aLTermSpace[3]; /* Initial aLTerm[] space */
};
/* This object holds the prerequisites and the cost of running a
** subquery on one operand of an OR operator in the WHERE clause.
|
| ︙ | ︙ | |||
157996 157997 157998 157999 158000 158001 158002 |
** at the end is the chosen query plan.
*/
struct WherePath {
Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */
Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */
LogEst nRow; /* Estimated number of rows generated by this path */
LogEst rCost; /* Total cost of this path */
| | | 158187 158188 158189 158190 158191 158192 158193 158194 158195 158196 158197 158198 158199 158200 158201 |
** at the end is the chosen query plan.
*/
struct WherePath {
Bitmask maskLoop; /* Bitmask of all WhereLoop objects in this path */
Bitmask revLoop; /* aLoop[]s that should be reversed for ORDER BY */
LogEst nRow; /* Estimated number of rows generated by this path */
LogEst rCost; /* Total cost of this path */
LogEst rUnsort; /* Total cost of this path ignoring sorting costs */
i8 isOrdered; /* No. of ORDER BY terms satisfied. -1 for unknown */
WhereLoop **aLoop; /* Array of WhereLoop objects implementing this path */
};
/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause. Each WHERE
|
| ︙ | ︙ | |||
158269 158270 158271 158272 158273 158274 158275 | u8 nLevel; /* Number of nested loop */ i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ unsigned bDeferredSeek :1; /* Uses OP_DeferredSeek */ unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ | | | > > > > | 158460 158461 158462 158463 158464 158465 158466 158467 158468 158469 158470 158471 158472 158473 158474 158475 158476 158477 158478 158479 158480 | u8 nLevel; /* Number of nested loop */ i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ u8 eOnePass; /* ONEPASS_OFF, or _SINGLE, or _MULTI */ u8 eDistinct; /* One of the WHERE_DISTINCT_* values */ unsigned bDeferredSeek :1; /* Uses OP_DeferredSeek */ unsigned untestedTerms :1; /* Not all WHERE terms resolved by outer loop */ unsigned bOrderedInnerLoop:1;/* True if only the inner-most loop is ordered */ unsigned sorted :1; /* True if really sorted (not just grouped) */ unsigned bStarDone :1; /* True if check for star-query is complete */ unsigned bStarUsed :1; /* True if star-query heuristic is used */ LogEst nRowOut; /* Estimated number of output rows */ #ifdef WHERETRACE_ENABLED LogEst rTotalCost; /* Total cost of the solution */ #endif int iTop; /* The very beginning of the WHERE loop */ int iEndWhere; /* End of the WHERE clause itself */ WhereLoop *pLoops; /* List of all WhereLoop objects */ WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ WhereClause sWC; /* Decomposition of the WHERE clause */ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ |
| ︙ | ︙ | |||
160027 160028 160029 160030 160031 160032 160033 160034 160035 160036 160037 160038 160039 160040 |
sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pSelect->iOffset);
VdbeComment((v,"Zero OFFSET counter"));
}
}
}
sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
pLoop->u.vtab.idxStr,
pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC);
VdbeCoverage(v);
pLoop->u.vtab.needFree = 0;
/* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed
** the u.vtab.idxStr. NULL it out to prevent a use-after-free */
| > > > | 160222 160223 160224 160225 160226 160227 160228 160229 160230 160231 160232 160233 160234 160235 160236 160237 160238 |
sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pSelect->iOffset);
VdbeComment((v,"Zero OFFSET counter"));
}
}
}
sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
/* The instruction immediately prior to OP_VFilter must be an OP_Integer
** that sets the "argc" value for xVFilter. This is necessary for
** resolveP2() to work correctly. See tag-20250207a. */
sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
pLoop->u.vtab.idxStr,
pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC);
VdbeCoverage(v);
pLoop->u.vtab.needFree = 0;
/* An OOM inside of AddOp4(OP_VFilter) instruction above might have freed
** the u.vtab.idxStr. NULL it out to prevent a use-after-free */
|
| ︙ | ︙ | |||
161582 161583 161584 161585 161586 161587 161588 |
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 ){
| | | | | | | > | > | 161780 161781 161782 161783 161784 161785 161786 161787 161788 161789 161790 161791 161792 161793 161794 161795 161796 161797 161798 161799 161800 161801 161802 161803 161804 161805 161806 161807 161808 161809 |
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( c==0xff || sqlite3Utf8Read(&z2)==0xfffd /* bad utf-8 */
|| ENC(db)==SQLITE_UTF16LE
){
cnt--;
break;
}else{
cnt = (int)(z2-z);
}
}
}
|
| ︙ | ︙ | |||
162747 162748 162749 162750 162751 162752 162753 |
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 ){
| | < | | > > > | > > > > | 162947 162948 162949 162950 162951 162952 162953 162954 162955 162956 162957 162958 162959 162960 162961 162962 162963 162964 162965 162966 162967 162968 162969 162970 162971 162972 162973 162974 162975 162976 162977 162978 162979 162980 |
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);
|
| ︙ | ︙ | |||
164128 164129 164130 164131 164132 164133 164134 164135 164136 164137 164138 164139 164140 164141 |
** 1. If iCol is already the left-most column of some other index,
** then return false.
**
** 2. If iCol is part of an existing index that has an aiRowLogEst of
** more than 20, then return false.
**
** 3. If no disqualifying conditions above are found, return true.
*/
static SQLITE_NOINLINE int columnIsGoodIndexCandidate(
const Table *pTab,
int iCol
){
const Index *pIdx;
for(pIdx = pTab->pIndex; pIdx!=0; pIdx=pIdx->pNext){
| > > > > > | 164334 164335 164336 164337 164338 164339 164340 164341 164342 164343 164344 164345 164346 164347 164348 164349 164350 164351 164352 |
** 1. If iCol is already the left-most column of some other index,
** then return false.
**
** 2. If iCol is part of an existing index that has an aiRowLogEst of
** more than 20, then return false.
**
** 3. If no disqualifying conditions above are found, return true.
**
** 2025-01-03: I experimented with a new rule that returns false if the
** the datatype of the column is "BOOLEAN". This did not improve
** performance on any queries at hand, but it did burn CPU cycles, so the
** idea was not committed.
*/
static SQLITE_NOINLINE int columnIsGoodIndexCandidate(
const Table *pTab,
int iCol
){
const Index *pIdx;
for(pIdx = pTab->pIndex; pIdx!=0; pIdx=pIdx->pNext){
|
| ︙ | ︙ | |||
164212 164213 164214 164215 164216 164217 164218 |
Table *pTab = pIdx->pTable;
const char *zSep = "";
char *zText = 0;
int ii = 0;
sqlite3_str *pStr = sqlite3_str_new(pParse->db);
sqlite3_str_appendf(pStr,"CREATE AUTOMATIC INDEX ON %s(", pTab->zName);
assert( pIdx->nColumn>1 );
| | | 164423 164424 164425 164426 164427 164428 164429 164430 164431 164432 164433 164434 164435 164436 164437 |
Table *pTab = pIdx->pTable;
const char *zSep = "";
char *zText = 0;
int ii = 0;
sqlite3_str *pStr = sqlite3_str_new(pParse->db);
sqlite3_str_appendf(pStr,"CREATE AUTOMATIC INDEX ON %s(", pTab->zName);
assert( pIdx->nColumn>1 );
assert( pIdx->aiColumn[pIdx->nColumn-1]==XN_ROWID || !HasRowid(pTab) );
for(ii=0; ii<(pIdx->nColumn-1); ii++){
const char *zName = 0;
int iCol = pIdx->aiColumn[ii];
zName = pTab->aCol[iCol].zCnName;
sqlite3_str_appendf(pStr, "%s%s", zSep, zName);
zSep = ", ";
|
| ︙ | ︙ | |||
164342 164343 164344 164345 164346 164347 164348 164349 164350 164351 164352 164353 164354 164355 164356 164357 164358 164359 164360 |
** original table changes and the index and table cannot both be used
** if they go out of sync.
*/
if( IsView(pTable) ){
extraCols = ALLBITS & ~idxCols;
}else{
extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
}
mxBitCol = MIN(BMS-1,pTable->nCol);
testcase( pTable->nCol==BMS-1 );
testcase( pTable->nCol==BMS-2 );
for(i=0; i<mxBitCol; i++){
if( extraCols & MASKBIT(i) ) nKeyCol++;
}
if( pSrc->colUsed & MASKBIT(BMS-1) ){
nKeyCol += pTable->nCol - BMS + 1;
}
/* Construct the Index object to describe this index */
| > > > > > > > > > > > > > | > | 164553 164554 164555 164556 164557 164558 164559 164560 164561 164562 164563 164564 164565 164566 164567 164568 164569 164570 164571 164572 164573 164574 164575 164576 164577 164578 164579 164580 164581 164582 164583 164584 164585 164586 164587 164588 164589 164590 164591 164592 164593 |
** original table changes and the index and table cannot both be used
** if they go out of sync.
*/
if( IsView(pTable) ){
extraCols = ALLBITS & ~idxCols;
}else{
extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
}
if( !HasRowid(pTable) ){
/* For WITHOUT ROWID tables, ensure that all PRIMARY KEY columns are
** either in the idxCols mask or in the extraCols mask */
for(i=0; i<pTable->nCol; i++){
if( (pTable->aCol[i].colFlags & COLFLAG_PRIMKEY)==0 ) continue;
if( i>=BMS-1 ){
extraCols |= MASKBIT(BMS-1);
break;
}
if( idxCols & MASKBIT(i) ) continue;
extraCols |= MASKBIT(i);
}
}
mxBitCol = MIN(BMS-1,pTable->nCol);
testcase( pTable->nCol==BMS-1 );
testcase( pTable->nCol==BMS-2 );
for(i=0; i<mxBitCol; i++){
if( extraCols & MASKBIT(i) ) nKeyCol++;
}
if( pSrc->colUsed & MASKBIT(BMS-1) ){
nKeyCol += pTable->nCol - BMS + 1;
}
/* Construct the Index object to describe this index */
pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+HasRowid(pTable),
0, &zNotUsed);
if( pIdx==0 ) goto end_auto_index_create;
pLoop->u.btree.pIndex = pIdx;
pIdx->zName = "auto-index";
pIdx->pTable = pTable;
n = 0;
idxCols = 0;
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
|
| ︙ | ︙ | |||
164410 164411 164412 164413 164414 164415 164416 |
for(i=BMS-1; i<pTable->nCol; i++){
pIdx->aiColumn[n] = i;
pIdx->azColl[n] = sqlite3StrBINARY;
n++;
}
}
assert( n==nKeyCol );
| > | | > | 164635 164636 164637 164638 164639 164640 164641 164642 164643 164644 164645 164646 164647 164648 164649 164650 164651 164652 |
for(i=BMS-1; i<pTable->nCol; i++){
pIdx->aiColumn[n] = i;
pIdx->azColl[n] = sqlite3StrBINARY;
n++;
}
}
assert( n==nKeyCol );
if( HasRowid(pTable) ){
pIdx->aiColumn[n] = XN_ROWID;
pIdx->azColl[n] = sqlite3StrBINARY;
}
/* Create the automatic index */
explainAutomaticIndex(pParse, pIdx, pPartial!=0, &addrExp);
assert( pLevel->iIdxCur>=0 );
pLevel->iIdxCur = pParse->nTab++;
sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
|
| ︙ | ︙ | |||
165678 165679 165680 165681 165682 165683 165684 165685 |
** | | .-- prereq Idx wsFlags----. | |
** | | | Name | | |
** | | | __|__ nEq ---. ___|__ | __|__
** | / \ / \ / \ | / \ / \ / \
** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31
*/
SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){
if( pWC ){
| > | > | 165905 165906 165907 165908 165909 165910 165911 165912 165913 165914 165915 165916 165917 165918 165919 165920 165921 165922 165923 165924 165925 165926 165927 165928 165929 165930 165931 |
** | | .-- prereq Idx wsFlags----. | |
** | | | Name | | |
** | | | __|__ nEq ---. ___|__ | __|__
** | / \ / \ / \ | / \ / \ / \
** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31
*/
SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){
WhereInfo *pWInfo;
if( pWC ){
pWInfo = pWC->pWInfo;
int nb = 1+(pWInfo->pTabList->nSrc+3)/4;
SrcItem *pItem = pWInfo->pTabList->a + p->iTab;
Table *pTab = pItem->pSTab;
Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1;
sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId,
p->iTab, nb, p->maskSelf, nb, p->prereq & mAll);
sqlite3DebugPrintf(" %12s",
pItem->zAlias ? pItem->zAlias : pTab->zName);
}else{
pWInfo = 0;
sqlite3DebugPrintf("%c%2d.%03llx.%03llx %c%d",
p->cId, p->iTab, p->maskSelf, p->prereq & 0xfff, p->cId, p->iTab);
}
if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
const char *zName;
if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
|
| ︙ | ︙ | |||
165720 165721 165722 165723 165724 165725 165726 |
sqlite3_free(z);
}
if( p->wsFlags & WHERE_SKIPSCAN ){
sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
}else{
sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm);
}
| > > > > | > | 165949 165950 165951 165952 165953 165954 165955 165956 165957 165958 165959 165960 165961 165962 165963 165964 165965 165966 165967 165968 |
sqlite3_free(z);
}
if( p->wsFlags & WHERE_SKIPSCAN ){
sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
}else{
sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm);
}
if( pWInfo && pWInfo->bStarUsed && p->rStarDelta!=0 ){
sqlite3DebugPrintf(" cost %d,%d,%d delta=%d\n",
p->rSetup, p->rRun, p->nOut, p->rStarDelta);
}else{
sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
}
if( p->nLTerm && (sqlite3WhereTrace & 0x4000)!=0 ){
int i;
for(i=0; i<p->nLTerm; i++){
sqlite3WhereTermPrint(p->aLTerm[i], i);
}
}
}
|
| ︙ | ︙ | |||
167186 167187 167188 167189 167190 167191 167192 | #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* Automatic indexes */ if( !pBuilder->pOrSet /* Not part of an OR optimization */ && (pWInfo->wctrlFlags & (WHERE_RIGHT_JOIN|WHERE_OR_SUBCLAUSE))==0 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 && !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */ && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ | < | 167420 167421 167422 167423 167424 167425 167426 167427 167428 167429 167430 167431 167432 167433 |
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
/* Automatic indexes */
if( !pBuilder->pOrSet /* Not part of an OR optimization */
&& (pWInfo->wctrlFlags & (WHERE_RIGHT_JOIN|WHERE_OR_SUBCLAUSE))==0
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
&& !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */
&& !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */
&& !pSrc->fg.isCorrelated /* Not a correlated subquery */
&& !pSrc->fg.isRecursive /* Not a recursive common table expression. */
&& (pSrc->fg.jointype & JT_RIGHT)==0 /* Not the right tab of a RIGHT JOIN */
){
/* Generate auto-index WhereLoops */
LogEst rLogSize; /* Logarithm of the number of rows in the table */
WhereTerm *pTerm;
|
| ︙ | ︙ | |||
168689 168690 168691 168692 168693 168694 168695 | ** each step of the solver search algorithm to avoid exponential behavior. ** ** The value returned is a tuning parameter. Currently the value is: ** ** 18 for star queries ** 12 otherwise ** | | | > | | > > | > > | | | > | > > > > > > > > > | < > > > > > > > > > > > > > | | | | > > | > > | > > > > > | > > > > > > | > > | > | > > > > > > | > | > > > > > > > > > > > > | > > > > > > > | > > > > > | | > | > > > > | > | | < < | | > > | > > > | > | > | > | < > > | > > | > > > > > > > > > > > > | > > > > > > | | > > | > > > > > > > > > > > > > > > > > > > > > > | 168922 168923 168924 168925 168926 168927 168928 168929 168930 168931 168932 168933 168934 168935 168936 168937 168938 168939 168940 168941 168942 168943 168944 168945 168946 168947 168948 168949 168950 168951 168952 168953 168954 168955 168956 168957 168958 168959 168960 168961 168962 168963 168964 168965 168966 168967 168968 168969 168970 168971 168972 168973 168974 168975 168976 168977 168978 168979 168980 168981 168982 168983 168984 168985 168986 168987 168988 168989 168990 168991 168992 168993 168994 168995 168996 168997 168998 168999 169000 169001 169002 169003 169004 169005 169006 169007 169008 169009 169010 169011 169012 169013 169014 169015 169016 169017 169018 169019 169020 169021 169022 169023 169024 169025 169026 169027 169028 169029 169030 169031 169032 169033 169034 169035 169036 169037 169038 169039 169040 169041 169042 169043 169044 169045 169046 169047 169048 169049 169050 169051 169052 169053 169054 169055 169056 169057 169058 169059 169060 169061 169062 169063 169064 169065 169066 169067 169068 169069 169070 169071 169072 169073 169074 169075 169076 169077 169078 169079 169080 169081 169082 169083 169084 169085 169086 169087 169088 169089 169090 169091 169092 169093 169094 169095 169096 169097 169098 169099 169100 169101 169102 169103 169104 169105 169106 169107 169108 169109 169110 169111 169112 169113 169114 169115 169116 169117 169118 169119 169120 169121 169122 169123 169124 169125 169126 169127 169128 169129 169130 |
** each step of the solver search algorithm to avoid exponential behavior.
**
** The value returned is a tuning parameter. Currently the value is:
**
** 18 for star queries
** 12 otherwise
**
** For the purposes of this heuristic, a star-query is defined as a query
** with a large central table that is joined using an INNER JOIN,
** not CROSS or OUTER JOINs, against four or more smaller tables.
** The central table is called the "fact" table. The smaller tables
** that get joined are "dimension tables". Also, any table that is
** self-joined cannot be a dimension table; we assume that dimension
** tables may only be joined against fact tables.
**
** SIDE EFFECT: (and really the whole point of this subroutine)
**
** If pWInfo describes a star-query, then the cost for SCANs of dimension
** WhereLoops is increased to be slightly larger than the cost of a SCAN
** in the fact table. Only SCAN costs are increased. SEARCH costs are
** unchanged. This heuristic helps keep fact tables in outer loops. Without
** this heuristic, paths with fact tables in outer loops tend to get pruned
** by the mxChoice limit on the number of paths, resulting in poor query
** plans. See the starschema1.test test module for examples of queries
** that need this heuristic to find good query plans.
**
** This heuristic can be completely disabled, so that no query is
** considered a star-query, using SQLITE_TESTCTRL_OPTIMIZATION to
** disable the SQLITE_StarQuery optimization. In the CLI, the command
** to do that is: ".testctrl opt -starquery".
**
** HISTORICAL NOTES:
**
** This optimization was first added on 2024-05-09 by check-in 38db9b5c83d.
** The original optimization reduced the cost and output size estimate for
** fact tables to help them move to outer loops. But months later (as people
** started upgrading) performance regression reports started caming in,
** including:
**
** forum post b18ef983e68d06d1 (2024-12-21)
** forum post 0025389d0860af82 (2025-01-14)
** forum post d87570a145599033 (2025-01-17)
**
** To address these, the criteria for a star-query was tightened to exclude
** cases where the fact and dimensions are separated by an outer join, and
** the affect of star-schema detection was changed to increase the rRun cost
** on just full table scans of dimension tables, rather than reducing costs
** in the all access methods of the fact table.
*/
static int computeMxChoice(WhereInfo *pWInfo){
int nLoop = pWInfo->nLevel; /* Number of terms in the join */
WhereLoop *pWLoop; /* For looping over WhereLoops */
#ifdef SQLITE_DEBUG
/* The star-query detection code below makes use of the following
** properties of the WhereLoop list, so verify them before
** continuing:
** (1) .maskSelf is the bitmask corresponding to .iTab
** (2) The WhereLoop list is in ascending .iTab order
*/
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
assert( pWLoop->maskSelf==MASKBIT(pWLoop->iTab) );
assert( pWLoop->pNextLoop==0 || pWLoop->iTab<=pWLoop->pNextLoop->iTab );
}
#endif /* SQLITE_DEBUG */
if( nLoop>=5
&& !pWInfo->bStarDone
&& OptimizationEnabled(pWInfo->pParse->db, SQLITE_StarQuery)
){
SrcItem *aFromTabs; /* All terms of the FROM clause */
int iFromIdx; /* Term of FROM clause is the candidate fact-table */
Bitmask m; /* Bitmask for candidate fact-table */
Bitmask mSelfJoin = 0; /* Tables that cannot be dimension tables */
WhereLoop *pStart; /* Where to start searching for dimension-tables */
pWInfo->bStarDone = 1; /* Only do this computation once */
/* Look for fact tables with four or more dimensions where the
** dimension tables are not separately from the fact tables by an outer
** or cross join. Adjust cost weights if found.
*/
assert( !pWInfo->bStarUsed );
aFromTabs = pWInfo->pTabList->a;
pStart = pWInfo->pLoops;
for(iFromIdx=0, m=1; iFromIdx<nLoop; iFromIdx++, m<<=1){
int nDep = 0; /* Number of dimension tables */
LogEst mxRun; /* Maximum SCAN cost of a fact table */
Bitmask mSeen = 0; /* Mask of dimension tables */
SrcItem *pFactTab; /* The candidate fact table */
pFactTab = aFromTabs + iFromIdx;
if( (pFactTab->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
/* If the candidate fact-table is the right table of an outer join
** restrict the search for dimension-tables to be tables to the right
** of the fact-table. */
if( iFromIdx+4 > nLoop ) break; /* Impossible to reach nDep>=4 */
while( pStart && pStart->iTab<=iFromIdx ){
pStart = pStart->pNextLoop;
}
}
for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){
if( (aFromTabs[pWLoop->iTab].fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){
/* Fact-tables and dimension-tables cannot be separated by an
** outer join (at least for the definition of fact- and dimension-
** used by this heuristic). */
break;
}
if( (pWLoop->prereq & m)!=0 /* pWInfo depends on iFromIdx */
&& (pWLoop->maskSelf & mSeen)==0 /* pWInfo not already a dependency */
&& (pWLoop->maskSelf & mSelfJoin)==0 /* Not a self-join */
){
if( aFromTabs[pWLoop->iTab].pSTab==pFactTab->pSTab ){
mSelfJoin |= m;
}else{
nDep++;
mSeen |= pWLoop->maskSelf;
}
}
}
if( nDep<=3 ) continue;
/* If we reach this point, it means that pFactTab is a fact table
** with four or more dimensions connected by inner joins. Proceed
** to make cost adjustments. */
#ifdef WHERETRACE_ENABLED
/* Make sure rStarDelta values are initialized */
if( !pWInfo->bStarUsed ){
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
pWLoop->rStarDelta = 0;
}
}
#endif
pWInfo->bStarUsed = 1;
/* Compute the maximum cost of any WhereLoop for the
** fact table plus one epsilon */
mxRun = LOGEST_MIN;
for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){
if( pWLoop->iTab<iFromIdx ) continue;
if( pWLoop->iTab>iFromIdx ) break;
if( pWLoop->rRun>mxRun ) mxRun = pWLoop->rRun;
}
if( ALWAYS(mxRun<LOGEST_MAX) ) mxRun++;
/* Increase the cost of table scans for dimension tables to be
** slightly more than the maximum cost of the fact table */
for(pWLoop=pStart; pWLoop; pWLoop=pWLoop->pNextLoop){
if( (pWLoop->maskSelf & mSeen)==0 ) continue;
if( pWLoop->nLTerm ) continue;
if( pWLoop->rRun<mxRun ){
#ifdef WHERETRACE_ENABLED /* 0x80000 */
if( sqlite3WhereTrace & 0x80000 ){
SrcItem *pDim = aFromTabs + pWLoop->iTab;
sqlite3DebugPrintf(
"Increase SCAN cost of dimension %s(%d) of fact %s(%d) to %d\n",
pDim->zAlias ? pDim->zAlias: pDim->pSTab->zName, pWLoop->iTab,
pFactTab->zAlias ? pFactTab->zAlias : pFactTab->pSTab->zName,
iFromIdx, mxRun
);
}
pWLoop->rStarDelta = mxRun - pWLoop->rRun;
#endif /* WHERETRACE_ENABLED */
pWLoop->rRun = mxRun;
}
}
}
#ifdef WHERETRACE_ENABLED /* 0x80000 */
if( (sqlite3WhereTrace & 0x80000)!=0 && pWInfo->bStarUsed ){
sqlite3DebugPrintf("WhereLoops changed by star-query heuristic:\n");
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
if( pWLoop->rStarDelta ){
sqlite3WhereLoopPrint(pWLoop, &pWInfo->sWC);
}
}
}
#endif
}
return pWInfo->bStarUsed ? 18 : 12;
}
/*
** Two WhereLoop objects, pCandidate and pBaseline, are known to have the
** same cost. Look deep into each to see if pCandidate is even slightly
** better than pBaseline. Return false if it is, if pCandidate is is preferred.
** Return true if pBaseline is preferred or if we cannot tell the difference.
**
** Result Meaning
** -------- ----------------------------------------------------------
** true We cannot tell the difference in pCandidate and pBaseline
** false pCandidate seems like a better choice than pBaseline
*/
static SQLITE_NOINLINE int whereLoopIsNoBetter(
const WhereLoop *pCandidate,
const WhereLoop *pBaseline
){
if( (pCandidate->wsFlags & WHERE_INDEXED)==0 ) return 1;
if( (pBaseline->wsFlags & WHERE_INDEXED)==0 ) return 1;
if( pCandidate->u.btree.pIndex->szIdxRow <
pBaseline->u.btree.pIndex->szIdxRow ) return 0;
return 1;
}
/*
** Given the list of WhereLoop objects at pWInfo->pLoops, this routine
** attempts to find the lowest cost path that visits each WhereLoop
** once. This path is then loaded into the pWInfo->a[].pWLoop fields.
**
|
| ︙ | ︙ | |||
168774 168775 168776 168777 168778 168779 168780 | int nLoop; /* Number of terms in the join */ Parse *pParse; /* Parsing context */ int iLoop; /* Loop counter over the terms of the join */ int ii, jj; /* Loop counters */ int mxI = 0; /* Index of next entry to replace */ int nOrderBy; /* Number of ORDER BY clause terms */ LogEst mxCost = 0; /* Maximum cost of a set of paths */ | | | 169140 169141 169142 169143 169144 169145 169146 169147 169148 169149 169150 169151 169152 169153 169154 | int nLoop; /* Number of terms in the join */ Parse *pParse; /* Parsing context */ int iLoop; /* Loop counter over the terms of the join */ int ii, jj; /* Loop counters */ int mxI = 0; /* Index of next entry to replace */ int nOrderBy; /* Number of ORDER BY clause terms */ LogEst mxCost = 0; /* Maximum cost of a set of paths */ LogEst mxUnsort = 0; /* Maximum unsorted cost of a set of path */ int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */ WherePath *aFrom; /* All nFrom paths at the previous level */ WherePath *aTo; /* The nTo best paths at the current level */ WherePath *pFrom; /* An element of aFrom[] that we are working on */ WherePath *pTo; /* An element of aTo[] that we are working on */ WhereLoop *pWLoop; /* One of the WhereLoop objects */ WhereLoop **pX; /* Used to divy up the pSpace memory */ |
| ︙ | ︙ | |||
168803 168804 168805 168806 168807 168808 168809 168810 |
** 2 5
** 3+ 12 or 18 // see computeMxChoice()
*/
if( nLoop<=1 ){
mxChoice = 1;
}else if( nLoop==2 ){
mxChoice = 5;
}else{
| > > | | 169169 169170 169171 169172 169173 169174 169175 169176 169177 169178 169179 169180 169181 169182 169183 169184 169185 169186 |
** 2 5
** 3+ 12 or 18 // see computeMxChoice()
*/
if( nLoop<=1 ){
mxChoice = 1;
}else if( nLoop==2 ){
mxChoice = 5;
}else if( pParse->nErr ){
mxChoice = 1;
}else{
mxChoice = computeMxChoice(pWInfo);
}
assert( nLoop<=pWInfo->pTabList->nSrc );
/* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this
** case the purpose of this call is to estimate the number of rows returned
** by the overall query. Once this estimate has been obtained, the caller
** will invoke this function a second time, passing the estimate as the
|
| ︙ | ︙ | |||
168871 168872 168873 168874 168875 168876 168877 |
** best paths at each generation */
for(iLoop=0; iLoop<nLoop; iLoop++){
nTo = 0;
for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
LogEst nOut; /* Rows visited by (pFrom+pWLoop) */
LogEst rCost; /* Cost of path (pFrom+pWLoop) */
| | | | | | 169239 169240 169241 169242 169243 169244 169245 169246 169247 169248 169249 169250 169251 169252 169253 169254 169255 169256 169257 169258 169259 169260 169261 169262 169263 169264 169265 169266 169267 169268 169269 169270 169271 169272 169273 169274 169275 |
** best paths at each generation */
for(iLoop=0; iLoop<nLoop; iLoop++){
nTo = 0;
for(ii=0, pFrom=aFrom; ii<nFrom; ii++, pFrom++){
for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){
LogEst nOut; /* Rows visited by (pFrom+pWLoop) */
LogEst rCost; /* Cost of path (pFrom+pWLoop) */
LogEst rUnsort; /* Unsorted cost of (pFrom+pWLoop) */
i8 isOrdered; /* isOrdered for (pFrom+pWLoop) */
Bitmask maskNew; /* Mask of src visited by (..) */
Bitmask revMask; /* Mask of rev-order loops for (..) */
if( (pWLoop->prereq & ~pFrom->maskLoop)!=0 ) continue;
if( (pWLoop->maskSelf & pFrom->maskLoop)!=0 ) continue;
if( (pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 && pFrom->nRow<3 ){
/* Do not use an automatic index if the this loop is expected
** to run less than 1.25 times. It is tempting to also exclude
** automatic index usage on an outer loop, but sometimes an automatic
** index is useful in the outer loop of a correlated subquery. */
assert( 10==sqlite3LogEst(2) );
continue;
}
/* At this point, pWLoop is a candidate to be the next loop.
** Compute its cost */
rUnsort = pWLoop->rRun + pFrom->nRow;
if( pWLoop->rSetup ){
rUnsort = sqlite3LogEstAdd(pWLoop->rSetup, rUnsort);
}
rUnsort = sqlite3LogEstAdd(rUnsort, pFrom->rUnsort);
nOut = pFrom->nRow + pWLoop->nOut;
maskNew = pFrom->maskLoop | pWLoop->maskSelf;
isOrdered = pFrom->isOrdered;
if( isOrdered<0 ){
revMask = 0;
isOrdered = wherePathSatisfiesOrderBy(pWInfo,
pWInfo->pOrderBy, pFrom, pWInfo->wctrlFlags,
|
| ︙ | ︙ | |||
168915 168916 168917 168918 168919 168920 168921 |
pWInfo, nRowEst, nOrderBy, isOrdered
);
}
/* TUNING: Add a small extra penalty (3) to sorting as an
** extra encouragement to the query planner to select a plan
** where the rows emerge in the correct order without any sorting
** required. */
| | | | | | 169283 169284 169285 169286 169287 169288 169289 169290 169291 169292 169293 169294 169295 169296 169297 169298 169299 169300 169301 169302 169303 169304 169305 |
pWInfo, nRowEst, nOrderBy, isOrdered
);
}
/* TUNING: Add a small extra penalty (3) to sorting as an
** extra encouragement to the query planner to select a plan
** where the rows emerge in the correct order without any sorting
** required. */
rCost = sqlite3LogEstAdd(rUnsort, aSortCost[isOrdered]) + 3;
WHERETRACE(0x002,
("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",
aSortCost[isOrdered], (nOrderBy-isOrdered), nOrderBy,
rUnsort, rCost));
}else{
rCost = rUnsort;
rUnsort -= 2; /* TUNING: Slight bias in favor of no-sort plans */
}
/* Check to see if pWLoop should be added to the set of
** mxChoice best-so-far paths.
**
** First look for an existing path among best-so-far paths
** that covers the same set of loops and has the same isOrdered
|
| ︙ | ︙ | |||
168949 168950 168951 168952 168953 168954 168955 |
testcase( jj==nTo-1 );
break;
}
}
if( jj>=nTo ){
/* None of the existing best-so-far paths match the candidate. */
if( nTo>=mxChoice
| | | | | | | | | | < | | | | | | | | > < > > > | | 169317 169318 169319 169320 169321 169322 169323 169324 169325 169326 169327 169328 169329 169330 169331 169332 169333 169334 169335 169336 169337 169338 169339 169340 169341 169342 169343 169344 169345 169346 169347 169348 169349 169350 169351 169352 169353 169354 169355 169356 169357 169358 169359 169360 169361 169362 169363 169364 169365 169366 169367 169368 169369 169370 169371 169372 169373 169374 169375 169376 169377 169378 169379 169380 169381 169382 169383 169384 169385 169386 169387 169388 169389 169390 169391 169392 169393 169394 169395 169396 169397 169398 169399 169400 169401 169402 169403 169404 169405 169406 169407 169408 169409 169410 169411 169412 169413 169414 169415 169416 169417 169418 169419 169420 169421 169422 169423 169424 169425 169426 169427 169428 169429 169430 169431 169432 169433 169434 169435 169436 169437 169438 169439 169440 169441 169442 169443 169444 169445 169446 169447 169448 169449 169450 169451 169452 169453 169454 169455 169456 169457 169458 169459 169460 |
testcase( jj==nTo-1 );
break;
}
}
if( jj>=nTo ){
/* None of the existing best-so-far paths match the candidate. */
if( nTo>=mxChoice
&& (rCost>mxCost || (rCost==mxCost && rUnsort>=mxUnsort))
){
/* The current candidate is no better than any of the mxChoice
** paths currently in the best-so-far buffer. So discard
** this candidate as not viable. */
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf("Skip %s cost=%-3d,%3d,%3d order=%c\n",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsort,
isOrdered>=0 ? isOrdered+'0' : '?');
}
#endif
continue;
}
/* If we reach this points it means that the new candidate path
** needs to be added to the set of best-so-far paths. */
if( nTo<mxChoice ){
/* Increase the size of the aTo set by one */
jj = nTo++;
}else{
/* New path replaces the prior worst to keep count below mxChoice */
jj = mxI;
}
pTo = &aTo[jj];
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf("New %s cost=%-3d,%3d,%3d order=%c\n",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsort,
isOrdered>=0 ? isOrdered+'0' : '?');
}
#endif
}else{
/* Control reaches here if best-so-far path pTo=aTo[jj] covers the
** same set of loops and has the same isOrdered setting as the
** candidate path. Check to see if the candidate should replace
** pTo or if the candidate should be skipped.
**
** The conditional is an expanded vector comparison equivalent to:
** (pTo->rCost,pTo->nRow,pTo->rUnsort) <= (rCost,nOut,rUnsort)
*/
if( (pTo->rCost<rCost)
|| (pTo->rCost==rCost && pTo->nRow<nOut)
|| (pTo->rCost==rCost && pTo->nRow==nOut && pTo->rUnsort<rUnsort)
|| (pTo->rCost==rCost && pTo->nRow==nOut && pTo->rUnsort==rUnsort
&& whereLoopIsNoBetter(pWLoop, pTo->aLoop[iLoop]) )
){
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf(
"Skip %s cost=%-3d,%3d,%3d order=%c",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsort,
isOrdered>=0 ? isOrdered+'0' : '?');
sqlite3DebugPrintf(" vs %s cost=%-3d,%3d,%3d order=%c\n",
wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
pTo->rUnsort, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
}
#endif
/* Discard the candidate path from further consideration */
testcase( pTo->rCost==rCost );
continue;
}
testcase( pTo->rCost==rCost+1 );
/* Control reaches here if the candidate path is better than the
** pTo path. Replace pTo with the candidate. */
#ifdef WHERETRACE_ENABLED /* 0x4 */
if( sqlite3WhereTrace&0x4 ){
sqlite3DebugPrintf(
"Update %s cost=%-3d,%3d,%3d order=%c",
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsort,
isOrdered>=0 ? isOrdered+'0' : '?');
sqlite3DebugPrintf(" was %s cost=%-3d,%3d,%3d order=%c\n",
wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
pTo->rUnsort, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?');
}
#endif
}
/* pWLoop is a winner. Add it to the set of best so far */
pTo->maskLoop = pFrom->maskLoop | pWLoop->maskSelf;
pTo->revLoop = revMask;
pTo->nRow = nOut;
pTo->rCost = rCost;
pTo->rUnsort = rUnsort;
pTo->isOrdered = isOrdered;
memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop);
pTo->aLoop[iLoop] = pWLoop;
if( nTo>=mxChoice ){
mxI = 0;
mxCost = aTo[0].rCost;
mxUnsort = aTo[0].nRow;
for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
if( pTo->rCost>mxCost
|| (pTo->rCost==mxCost && pTo->rUnsort>mxUnsort)
){
mxCost = pTo->rCost;
mxUnsort = pTo->rUnsort;
mxI = jj;
}
}
}
}
}
#ifdef WHERETRACE_ENABLED /* >=2 */
if( sqlite3WhereTrace & 0x02 ){
LogEst rMin, rFloor = 0;
int nDone = 0;
int nProgress;
sqlite3DebugPrintf("---- after round %d ----\n", iLoop);
do{
nProgress = 0;
rMin = 0x7fff;
for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){
if( pTo->rCost>rFloor && pTo->rCost<rMin ) rMin = pTo->rCost;
}
for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){
if( pTo->rCost==rMin ){
sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c",
wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?');
if( pTo->isOrdered>0 ){
sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop);
}else{
sqlite3DebugPrintf("\n");
}
nDone++;
nProgress++;
}
}
rFloor = rMin;
}while( nDone<nTo && nProgress>0 );
}
#endif
/* Swap the roles of aFrom and aTo for the next generation */
pFrom = aTo;
aTo = aFrom;
aFrom = pFrom;
|
| ︙ | ︙ | |||
169170 169171 169172 169173 169174 169175 169176 |
if( nOrder==pWInfo->pOrderBy->nExpr ){
pWInfo->sorted = 1;
pWInfo->revMask = revMask;
}
}
}
| | > > > | 169540 169541 169542 169543 169544 169545 169546 169547 169548 169549 169550 169551 169552 169553 169554 169555 169556 169557 |
if( nOrder==pWInfo->pOrderBy->nExpr ){
pWInfo->sorted = 1;
pWInfo->revMask = revMask;
}
}
}
pWInfo->nRowOut = pFrom->nRow;
#ifdef WHERETRACE_ENABLED
pWInfo->rTotalCost = pFrom->rCost;
#endif
/* Free temporary memory and return success */
sqlite3StackFreeNN(pParse->db, pSpace);
return SQLITE_OK;
}
/*
|
| ︙ | ︙ | |||
169568 169569 169570 169571 169572 169573 169574 |
"-> use Bloom-filter on loop %c because there are ~%.1e "
"lookups into %s which has only ~%.1e rows\n",
pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName,
(double)sqlite3LogEstToInt(pTab->nRowLogEst)));
}
}
nSearch += pLoop->nOut;
| < | 169941 169942 169943 169944 169945 169946 169947 169948 169949 169950 169951 169952 169953 169954 |
"-> use Bloom-filter on loop %c because there are ~%.1e "
"lookups into %s which has only ~%.1e rows\n",
pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName,
(double)sqlite3LogEstToInt(pTab->nRowLogEst)));
}
}
nSearch += pLoop->nOut;
}
}
/*
** The index pIdx is used by a query and contains one or more expressions.
** In other words pIdx is an index on an expression. iIdxCur is the cursor
** number for the index and iDataCur is the cursor number for the corresponding
|
| ︙ | ︙ | |||
170051 170052 170053 170054 170055 170056 170057 |
}
if( pParse->nErr ){
goto whereBeginError;
}
assert( db->mallocFailed==0 );
#ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace ){
| | > | 170423 170424 170425 170426 170427 170428 170429 170430 170431 170432 170433 170434 170435 170436 170437 170438 |
}
if( pParse->nErr ){
goto whereBeginError;
}
assert( db->mallocFailed==0 );
#ifdef WHERETRACE_ENABLED
if( sqlite3WhereTrace ){
sqlite3DebugPrintf("---- Solution cost=%d, nRow=%d",
pWInfo->rTotalCost, pWInfo->nRowOut);
if( pWInfo->nOBSat>0 ){
sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
}
switch( pWInfo->eDistinct ){
case WHERE_DISTINCT_UNIQUE: {
sqlite3DebugPrintf(" DISTINCT=unique");
break;
|
| ︙ | ︙ | |||
170412 170413 170414 170415 170416 170417 170418 170419 170420 170421 170422 170423 170424 170425 |
static void sqlite3WhereOpcodeRewriteTrace(
sqlite3 *db,
int pc,
VdbeOp *pOp
){
if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return;
sqlite3VdbePrintOp(0, pc, pOp);
}
#endif
/*
** Generate the end of the WHERE loop. See comments on
** sqlite3WhereBegin() for additional information.
*/
| > | 170785 170786 170787 170788 170789 170790 170791 170792 170793 170794 170795 170796 170797 170798 170799 |
static void sqlite3WhereOpcodeRewriteTrace(
sqlite3 *db,
int pc,
VdbeOp *pOp
){
if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return;
sqlite3VdbePrintOp(0, pc, pOp);
sqlite3ShowWhereTerm(0); /* So compiler won't complain about unused func */
}
#endif
/*
** Generate the end of the WHERE loop. See comments on
** sqlite3WhereBegin() for additional information.
*/
|
| ︙ | ︙ | |||
172521 172522 172523 172524 172525 172526 172527 |
assert( ExprUseXList(pWin->pOwner) );
pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
}
sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
bInverse, regArg, pWin->regAccum);
sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
| | | 172895 172896 172897 172898 172899 172900 172901 172902 172903 172904 172905 172906 172907 172908 172909 |
assert( ExprUseXList(pWin->pOwner) );
pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
}
sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
bInverse, regArg, pWin->regAccum);
sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
sqlite3VdbeChangeP5(v, (u16)nArg);
if( pWin->bExprArgs ){
sqlite3ReleaseTempRange(pParse, regArg, nArg);
}
}
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
}
|
| ︙ | ︙ | |||
173905 173906 173907 173908 173909 173910 173911 173912 173913 173914 173915 173916 173917 173918 | ** implementation of a parser for the given grammar. You might be reading ** this comment as part of the translated C-code. Edits should be made ** to the original parse.y sources. */ /* #include "sqliteInt.h" */ /* ** Disable all error recovery processing in the parser push-down ** automaton. */ #define YYNOERRORRECOVERY 1 /* | > > > > > | 174279 174280 174281 174282 174283 174284 174285 174286 174287 174288 174289 174290 174291 174292 174293 174294 174295 174296 174297 | ** implementation of a parser for the given grammar. You might be reading ** this comment as part of the translated C-code. Edits should be made ** to the original parse.y sources. */ /* #include "sqliteInt.h" */ /* ** Verify that the pParse->isCreate field is set */ #define ASSERT_IS_CREATE assert(pParse->isCreate) /* ** Disable all error recovery processing in the parser push-down ** automaton. */ #define YYNOERRORRECOVERY 1 /* |
| ︙ | ︙ | |||
173968 173969 173970 173971 173972 173973 173974 173975 173976 173977 173978 173979 173980 173981 |
/*
** Disable lookaside memory allocation for objects that might be
** shared across database connections.
*/
static void disableLookaside(Parse *pParse){
sqlite3 *db = pParse->db;
pParse->disableLookaside++;
DisableLookaside;
}
#if !defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) \
&& defined(SQLITE_UDL_CAPABLE_PARSER)
/*
** Issue an error message if an ORDER BY or LIMIT clause occurs on an
| > > > > | 174347 174348 174349 174350 174351 174352 174353 174354 174355 174356 174357 174358 174359 174360 174361 174362 174363 174364 |
/*
** Disable lookaside memory allocation for objects that might be
** shared across database connections.
*/
static void disableLookaside(Parse *pParse){
sqlite3 *db = pParse->db;
pParse->disableLookaside++;
#ifdef SQLITE_DEBUG
pParse->isCreate = 1;
#endif
memset(&pParse->u1.cr, 0, sizeof(pParse->u1.cr));
DisableLookaside;
}
#if !defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) \
&& defined(SQLITE_UDL_CAPABLE_PARSER)
/*
** Issue an error message if an ORDER BY or LIMIT clause occurs on an
|
| ︙ | ︙ | |||
174308 174309 174310 174311 174312 174313 174314 | #define TK_SELECT_COLUMN 178 #define TK_IF_NULL_ROW 179 #define TK_ASTERISK 180 #define TK_SPAN 181 #define TK_ERROR 182 #define TK_QNUMBER 183 #define TK_SPACE 184 | > | | 174691 174692 174693 174694 174695 174696 174697 174698 174699 174700 174701 174702 174703 174704 174705 174706 | #define TK_SELECT_COLUMN 178 #define TK_IF_NULL_ROW 179 #define TK_ASTERISK 180 #define TK_SPAN 181 #define TK_ERROR 182 #define TK_QNUMBER 183 #define TK_SPACE 184 #define TK_COMMENT 185 #define TK_ILLEGAL 186 #endif /**************** End token definitions ***************************************/ /* The next sections is a series of control #defines. ** various aspects of the generated parser. ** YYCODETYPE is the data type used to store the integer codes ** that represent terminal and non-terminal symbols. |
| ︙ | ︙ | |||
174373 174374 174375 174376 174377 174378 174379 | ** YY_MAX_DSTRCTR Maximum symbol value that has a destructor */ #ifndef INTERFACE # define INTERFACE 1 #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int | | | > | < < | > | | > | | | | | > | | | < < | | 174757 174758 174759 174760 174761 174762 174763 174764 174765 174766 174767 174768 174769 174770 174771 174772 174773 174774 174775 174776 174777 174778 174779 174780 174781 174782 174783 174784 174785 174786 174787 174788 174789 174790 174791 174792 174793 174794 174795 |
** YY_MAX_DSTRCTR Maximum symbol value that has a destructor
*/
#ifndef INTERFACE
# define INTERFACE 1
#endif
/************* Begin control #defines *****************************************/
#define YYCODETYPE unsigned short int
#define YYNOCODE 323
#define YYACTIONTYPE unsigned short int
#define YYWILDCARD 102
#define sqlite3ParserTOKENTYPE Token
typedef union {
int yyinit;
sqlite3ParserTOKENTYPE yy0;
u32 yy9;
struct TrigEvent yy28;
With* yy125;
IdList* yy204;
struct FrameBound yy205;
TriggerStep* yy319;
const char* yy342;
Cte* yy361;
ExprList* yy402;
Upsert* yy403;
OnOrUsing yy421;
u8 yy444;
struct {int value; int mask;} yy481;
Window* yy483;
int yy502;
SrcList* yy563;
Expr* yy590;
Select* yy637;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
#endif
#define sqlite3ParserARG_SDECL
#define sqlite3ParserARG_PDECL
#define sqlite3ParserARG_PARAM
|
| ︙ | ︙ | |||
174419 174420 174421 174422 174423 174424 174425 | #define sqlite3ParserCTX_PARAM ,pParse #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 #define YYNSTATE 583 #define YYNRULE 409 #define YYNRULE_WITH_ACTION 344 | | | | | 174803 174804 174805 174806 174807 174808 174809 174810 174811 174812 174813 174814 174815 174816 174817 174818 174819 174820 174821 174822 174823 174824 174825 174826 174827 | #define sqlite3ParserCTX_PARAM ,pParse #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 #define YYNSTATE 583 #define YYNRULE 409 #define YYNRULE_WITH_ACTION 344 #define YYNTOKEN 187 #define YY_MAX_SHIFT 582 #define YY_MIN_SHIFTREDUCE 845 #define YY_MAX_SHIFTREDUCE 1253 #define YY_ERROR_ACTION 1254 #define YY_ACCEPT_ACTION 1255 #define YY_NO_ACTION 1256 #define YY_MIN_REDUCE 1257 #define YY_MAX_REDUCE 1665 #define YY_MIN_DSTRCTR 206 #define YY_MAX_DSTRCTR 320 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) /* Define the yytestcase() macro to be a no-op if is not already defined ** otherwise. ** ** Applications can choose to define yytestcase() in the %include section |
| ︙ | ︙ | |||
174525 174526 174527 174528 174529 174530 174531 | /* 40 */ 82, 82, 1577, 137, 138, 91, 7, 1228, 1228, 1063, /* 50 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 413, /* 60 */ 288, 288, 182, 288, 288, 481, 536, 288, 288, 130, /* 70 */ 127, 234, 432, 573, 525, 562, 573, 557, 562, 1290, /* 80 */ 573, 421, 562, 137, 138, 91, 559, 1228, 1228, 1063, /* 90 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 296, /* 100 */ 460, 398, 1249, 134, 134, 134, 134, 133, 133, 132, | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 174909 174910 174911 174912 174913 174914 174915 174916 174917 174918 174919 174920 174921 174922 174923 174924 174925 174926 174927 174928 174929 174930 174931 174932 174933 174934 174935 174936 174937 174938 174939 174940 174941 174942 174943 174944 174945 174946 174947 174948 174949 174950 174951 174952 174953 174954 174955 174956 174957 174958 174959 174960 174961 174962 174963 174964 174965 174966 174967 174968 174969 174970 174971 174972 174973 174974 174975 174976 174977 174978 174979 174980 174981 174982 174983 174984 174985 174986 174987 174988 174989 174990 174991 174992 174993 174994 174995 174996 174997 174998 174999 175000 175001 175002 175003 175004 175005 175006 175007 175008 175009 175010 175011 175012 175013 175014 175015 175016 175017 175018 175019 175020 175021 175022 175023 175024 175025 175026 175027 175028 175029 175030 175031 175032 175033 175034 175035 175036 175037 175038 175039 175040 175041 175042 175043 175044 175045 175046 175047 175048 175049 175050 175051 175052 175053 175054 175055 175056 175057 175058 175059 175060 175061 175062 175063 175064 175065 175066 175067 175068 175069 175070 175071 175072 175073 175074 175075 175076 175077 175078 175079 175080 175081 175082 175083 175084 175085 175086 175087 175088 175089 175090 175091 175092 175093 175094 175095 175096 175097 175098 175099 175100 175101 175102 175103 175104 175105 175106 175107 175108 175109 175110 175111 175112 175113 175114 175115 175116 175117 175118 175119 175120 175121 175122 175123 175124 175125 175126 175127 175128 175129 175130 175131 175132 175133 175134 175135 175136 175137 175138 175139 175140 175141 175142 175143 175144 175145 175146 175147 175148 175149 175150 175151 175152 175153 175154 175155 175156 175157 175158 175159 175160 175161 175162 175163 175164 175165 175166 175167 175168 175169 175170 175171 175172 175173 175174 175175 175176 175177 175178 175179 175180 175181 175182 175183 175184 175185 175186 175187 175188 175189 175190 175191 175192 175193 175194 175195 175196 175197 175198 175199 175200 175201 175202 175203 175204 175205 175206 175207 175208 175209 175210 175211 175212 175213 175214 175215 175216 175217 175218 175219 175220 175221 175222 175223 175224 175225 175226 175227 175228 175229 175230 175231 175232 175233 175234 175235 175236 175237 175238 175239 175240 175241 175242 175243 175244 175245 175246 175247 175248 175249 175250 175251 175252 175253 175254 175255 175256 175257 175258 175259 175260 175261 175262 175263 175264 175265 175266 175267 175268 175269 175270 175271 175272 175273 175274 175275 175276 175277 175278 175279 175280 175281 175282 175283 175284 175285 175286 175287 175288 175289 175290 175291 175292 175293 175294 175295 175296 175297 175298 175299 175300 175301 175302 175303 175304 175305 175306 175307 175308 175309 175310 175311 175312 175313 175314 175315 175316 175317 175318 175319 175320 175321 175322 175323 175324 175325 175326 175327 175328 175329 175330 175331 175332 175333 175334 175335 175336 175337 175338 175339 175340 175341 175342 175343 175344 175345 175346 175347 175348 175349 175350 175351 175352 175353 175354 175355 175356 175357 175358 175359 175360 175361 175362 175363 175364 175365 175366 175367 175368 175369 175370 175371 175372 175373 175374 175375 175376 175377 175378 175379 175380 175381 175382 175383 175384 175385 175386 175387 175388 175389 175390 175391 175392 175393 175394 175395 175396 175397 175398 175399 175400 175401 175402 175403 175404 175405 175406 175407 175408 175409 175410 175411 175412 175413 175414 175415 175416 175417 175418 175419 175420 175421 175422 175423 175424 175425 175426 175427 175428 175429 175430 175431 175432 175433 175434 175435 175436 175437 175438 175439 175440 175441 175442 175443 175444 175445 175446 175447 175448 175449 175450 175451 175452 175453 175454 175455 175456 175457 175458 175459 175460 175461 175462 175463 175464 175465 175466 175467 175468 175469 175470 175471 175472 175473 175474 175475 175476 175477 175478 175479 175480 175481 175482 175483 175484 175485 |
/* 40 */ 82, 82, 1577, 137, 138, 91, 7, 1228, 1228, 1063,
/* 50 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 413,
/* 60 */ 288, 288, 182, 288, 288, 481, 536, 288, 288, 130,
/* 70 */ 127, 234, 432, 573, 525, 562, 573, 557, 562, 1290,
/* 80 */ 573, 421, 562, 137, 138, 91, 559, 1228, 1228, 1063,
/* 90 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 296,
/* 100 */ 460, 398, 1249, 134, 134, 134, 134, 133, 133, 132,
/* 110 */ 132, 132, 131, 128, 451, 451, 1050, 1050, 1064, 1067,
/* 120 */ 1255, 1, 1, 582, 2, 1259, 581, 1174, 1259, 1174,
/* 130 */ 321, 413, 155, 321, 1584, 155, 379, 112, 481, 1341,
/* 140 */ 456, 299, 1341, 134, 134, 134, 134, 133, 133, 132,
/* 150 */ 132, 132, 131, 128, 451, 137, 138, 91, 498, 1228,
/* 160 */ 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136,
/* 170 */ 136, 1204, 862, 1281, 288, 288, 283, 288, 288, 523,
/* 180 */ 523, 1250, 139, 578, 7, 578, 1345, 573, 1169, 562,
/* 190 */ 573, 1054, 562, 136, 136, 136, 136, 129, 573, 547,
/* 200 */ 562, 1169, 245, 1541, 1169, 245, 133, 133, 132, 132,
/* 210 */ 132, 131, 128, 451, 302, 134, 134, 134, 134, 133,
/* 220 */ 133, 132, 132, 132, 131, 128, 451, 1575, 1204, 1205,
/* 230 */ 1204, 7, 470, 550, 455, 413, 550, 455, 130, 127,
/* 240 */ 234, 134, 134, 134, 134, 133, 133, 132, 132, 132,
/* 250 */ 131, 128, 451, 136, 136, 136, 136, 538, 483, 137,
/* 260 */ 138, 91, 1019, 1228, 1228, 1063, 1066, 1053, 1053, 135,
/* 270 */ 135, 136, 136, 136, 136, 1085, 576, 1204, 132, 132,
/* 280 */ 132, 131, 128, 451, 93, 214, 134, 134, 134, 134,
/* 290 */ 133, 133, 132, 132, 132, 131, 128, 451, 401, 19,
/* 300 */ 19, 134, 134, 134, 134, 133, 133, 132, 132, 132,
/* 310 */ 131, 128, 451, 1498, 426, 267, 344, 467, 332, 134,
/* 320 */ 134, 134, 134, 133, 133, 132, 132, 132, 131, 128,
/* 330 */ 451, 1281, 576, 6, 1204, 1205, 1204, 257, 576, 413,
/* 340 */ 511, 508, 507, 1279, 94, 1019, 464, 1204, 551, 551,
/* 350 */ 506, 1224, 1571, 44, 38, 51, 51, 411, 576, 413,
/* 360 */ 45, 51, 51, 137, 138, 91, 530, 1228, 1228, 1063,
/* 370 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 398,
/* 380 */ 1148, 82, 82, 137, 138, 91, 39, 1228, 1228, 1063,
/* 390 */ 1066, 1053, 1053, 135, 135, 136, 136, 136, 136, 344,
/* 400 */ 44, 288, 288, 375, 1204, 1205, 1204, 209, 1204, 1224,
/* 410 */ 320, 567, 471, 576, 573, 576, 562, 576, 316, 264,
/* 420 */ 231, 46, 160, 134, 134, 134, 134, 133, 133, 132,
/* 430 */ 132, 132, 131, 128, 451, 303, 82, 82, 82, 82,
/* 440 */ 82, 82, 442, 134, 134, 134, 134, 133, 133, 132,
/* 450 */ 132, 132, 131, 128, 451, 1582, 544, 320, 567, 1250,
/* 460 */ 874, 1582, 380, 382, 413, 1204, 1205, 1204, 360, 182,
/* 470 */ 288, 288, 1576, 557, 1339, 557, 7, 557, 1277, 472,
/* 480 */ 346, 526, 531, 573, 556, 562, 439, 1511, 137, 138,
/* 490 */ 91, 219, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135,
/* 500 */ 136, 136, 136, 136, 465, 1511, 1513, 532, 413, 288,
/* 510 */ 288, 423, 512, 288, 288, 411, 288, 288, 874, 130,
/* 520 */ 127, 234, 573, 1107, 562, 1204, 573, 1107, 562, 573,
/* 530 */ 560, 562, 137, 138, 91, 1293, 1228, 1228, 1063, 1066,
/* 540 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 134, 134,
/* 550 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451,
/* 560 */ 493, 503, 1292, 1204, 257, 288, 288, 511, 508, 507,
/* 570 */ 1204, 1628, 1169, 123, 568, 275, 4, 506, 573, 1511,
/* 580 */ 562, 331, 1204, 1205, 1204, 1169, 548, 548, 1169, 261,
/* 590 */ 571, 7, 134, 134, 134, 134, 133, 133, 132, 132,
/* 600 */ 132, 131, 128, 451, 108, 533, 130, 127, 234, 1204,
/* 610 */ 448, 447, 413, 1451, 452, 983, 886, 96, 1598, 1233,
/* 620 */ 1204, 1205, 1204, 984, 1235, 1450, 565, 1204, 1205, 1204,
/* 630 */ 229, 522, 1234, 534, 1333, 1333, 137, 138, 91, 1449,
/* 640 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136,
/* 650 */ 136, 136, 373, 1595, 971, 1040, 413, 1236, 418, 1236,
/* 660 */ 879, 121, 121, 948, 373, 1595, 1204, 1205, 1204, 122,
/* 670 */ 1204, 452, 577, 452, 363, 417, 1028, 882, 373, 1595,
/* 680 */ 137, 138, 91, 462, 1228, 1228, 1063, 1066, 1053, 1053,
/* 690 */ 135, 135, 136, 136, 136, 136, 134, 134, 134, 134,
/* 700 */ 133, 133, 132, 132, 132, 131, 128, 451, 1028, 1028,
/* 710 */ 1030, 1031, 35, 570, 570, 570, 197, 423, 1040, 198,
/* 720 */ 1204, 123, 568, 1204, 4, 320, 567, 1204, 1205, 1204,
/* 730 */ 40, 388, 576, 384, 882, 1029, 423, 1188, 571, 1028,
/* 740 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131,
/* 750 */ 128, 451, 529, 1568, 1204, 19, 19, 1204, 575, 492,
/* 760 */ 413, 157, 452, 489, 1187, 1331, 1331, 5, 1204, 949,
/* 770 */ 431, 1028, 1028, 1030, 565, 22, 22, 1204, 1205, 1204,
/* 780 */ 1204, 1205, 1204, 477, 137, 138, 91, 212, 1228, 1228,
/* 790 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136,
/* 800 */ 1188, 48, 111, 1040, 413, 1204, 213, 970, 1041, 121,
/* 810 */ 121, 1204, 1205, 1204, 1204, 1205, 1204, 122, 221, 452,
/* 820 */ 577, 452, 44, 487, 1028, 1204, 1205, 1204, 137, 138,
/* 830 */ 91, 378, 1228, 1228, 1063, 1066, 1053, 1053, 135, 135,
/* 840 */ 136, 136, 136, 136, 134, 134, 134, 134, 133, 133,
/* 850 */ 132, 132, 132, 131, 128, 451, 1028, 1028, 1030, 1031,
/* 860 */ 35, 461, 1204, 1205, 1204, 1569, 1040, 377, 214, 1149,
/* 870 */ 1657, 535, 1657, 437, 902, 320, 567, 1568, 364, 320,
/* 880 */ 567, 412, 329, 1029, 519, 1188, 3, 1028, 134, 134,
/* 890 */ 134, 134, 133, 133, 132, 132, 132, 131, 128, 451,
/* 900 */ 1659, 399, 1169, 307, 893, 307, 515, 576, 413, 214,
/* 910 */ 498, 944, 1024, 540, 903, 1169, 943, 392, 1169, 1028,
/* 920 */ 1028, 1030, 406, 298, 1204, 50, 1149, 1658, 413, 1658,
/* 930 */ 145, 145, 137, 138, 91, 293, 1228, 1228, 1063, 1066,
/* 940 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 1188, 1147,
/* 950 */ 514, 1568, 137, 138, 91, 1505, 1228, 1228, 1063, 1066,
/* 960 */ 1053, 1053, 135, 135, 136, 136, 136, 136, 434, 323,
/* 970 */ 435, 539, 111, 1506, 274, 291, 372, 517, 367, 516,
/* 980 */ 262, 1204, 1205, 1204, 1574, 481, 363, 576, 7, 1569,
/* 990 */ 1568, 377, 134, 134, 134, 134, 133, 133, 132, 132,
/* 1000 */ 132, 131, 128, 451, 1568, 576, 1147, 576, 232, 576,
/* 1010 */ 19, 19, 134, 134, 134, 134, 133, 133, 132, 132,
/* 1020 */ 132, 131, 128, 451, 1169, 433, 576, 1207, 19, 19,
/* 1030 */ 19, 19, 19, 19, 1627, 576, 911, 1169, 47, 120,
/* 1040 */ 1169, 117, 413, 306, 498, 438, 1125, 206, 336, 19,
/* 1050 */ 19, 1435, 49, 449, 449, 449, 1368, 315, 81, 81,
/* 1060 */ 576, 304, 413, 1570, 207, 377, 137, 138, 91, 115,
/* 1070 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136,
/* 1080 */ 136, 136, 576, 82, 82, 1207, 137, 138, 91, 1340,
/* 1090 */ 1228, 1228, 1063, 1066, 1053, 1053, 135, 135, 136, 136,
/* 1100 */ 136, 136, 1569, 386, 377, 82, 82, 463, 1126, 1552,
/* 1110 */ 333, 463, 335, 131, 128, 451, 1569, 161, 377, 16,
/* 1120 */ 317, 387, 428, 1127, 448, 447, 134, 134, 134, 134,
/* 1130 */ 133, 133, 132, 132, 132, 131, 128, 451, 1128, 576,
/* 1140 */ 1105, 10, 445, 267, 576, 1554, 134, 134, 134, 134,
/* 1150 */ 133, 133, 132, 132, 132, 131, 128, 451, 532, 576,
/* 1160 */ 922, 576, 19, 19, 576, 1573, 576, 147, 147, 7,
/* 1170 */ 923, 1236, 498, 1236, 576, 487, 413, 552, 285, 1224,
/* 1180 */ 969, 215, 82, 82, 66, 66, 1435, 67, 67, 21,
/* 1190 */ 21, 1110, 1110, 495, 334, 297, 413, 53, 53, 297,
/* 1200 */ 137, 138, 91, 119, 1228, 1228, 1063, 1066, 1053, 1053,
/* 1210 */ 135, 135, 136, 136, 136, 136, 413, 1336, 1311, 446,
/* 1220 */ 137, 138, 91, 227, 1228, 1228, 1063, 1066, 1053, 1053,
/* 1230 */ 135, 135, 136, 136, 136, 136, 574, 1224, 936, 936,
/* 1240 */ 137, 126, 91, 141, 1228, 1228, 1063, 1066, 1053, 1053,
/* 1250 */ 135, 135, 136, 136, 136, 136, 533, 429, 472, 346,
/* 1260 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131,
/* 1270 */ 128, 451, 576, 457, 233, 343, 1435, 403, 498, 1550,
/* 1280 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131,
/* 1290 */ 128, 451, 576, 324, 576, 82, 82, 487, 576, 969,
/* 1300 */ 134, 134, 134, 134, 133, 133, 132, 132, 132, 131,
/* 1310 */ 128, 451, 288, 288, 546, 68, 68, 54, 54, 553,
/* 1320 */ 413, 69, 69, 351, 6, 573, 944, 562, 410, 409,
/* 1330 */ 1435, 943, 450, 545, 260, 259, 258, 576, 158, 576,
/* 1340 */ 413, 222, 1180, 479, 969, 138, 91, 430, 1228, 1228,
/* 1350 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136,
/* 1360 */ 70, 70, 71, 71, 576, 1126, 91, 576, 1228, 1228,
/* 1370 */ 1063, 1066, 1053, 1053, 135, 135, 136, 136, 136, 136,
/* 1380 */ 1127, 166, 850, 851, 852, 1282, 419, 72, 72, 108,
/* 1390 */ 73, 73, 1310, 358, 1180, 1128, 576, 305, 576, 123,
/* 1400 */ 568, 494, 4, 488, 134, 134, 134, 134, 133, 133,
/* 1410 */ 132, 132, 132, 131, 128, 451, 571, 564, 534, 55,
/* 1420 */ 55, 56, 56, 576, 134, 134, 134, 134, 133, 133,
/* 1430 */ 132, 132, 132, 131, 128, 451, 576, 1104, 233, 1104,
/* 1440 */ 452, 1602, 582, 2, 1259, 576, 57, 57, 576, 321,
/* 1450 */ 576, 155, 565, 1435, 485, 353, 576, 356, 1341, 59,
/* 1460 */ 59, 576, 44, 969, 569, 419, 576, 238, 60, 60,
/* 1470 */ 261, 74, 74, 75, 75, 287, 231, 576, 1366, 76,
/* 1480 */ 76, 1040, 420, 184, 20, 20, 576, 121, 121, 77,
/* 1490 */ 77, 97, 218, 288, 288, 122, 125, 452, 577, 452,
/* 1500 */ 143, 143, 1028, 576, 520, 576, 573, 576, 562, 144,
/* 1510 */ 144, 474, 227, 1244, 478, 123, 568, 576, 4, 320,
/* 1520 */ 567, 245, 411, 576, 443, 411, 78, 78, 62, 62,
/* 1530 */ 79, 79, 571, 319, 1028, 1028, 1030, 1031, 35, 418,
/* 1540 */ 63, 63, 576, 290, 411, 9, 80, 80, 1144, 576,
/* 1550 */ 400, 576, 486, 455, 576, 1223, 452, 576, 325, 342,
/* 1560 */ 576, 111, 576, 1188, 242, 64, 64, 473, 565, 576,
/* 1570 */ 23, 576, 170, 170, 171, 171, 576, 87, 87, 328,
/* 1580 */ 65, 65, 542, 83, 83, 146, 146, 541, 123, 568,
/* 1590 */ 341, 4, 84, 84, 168, 168, 576, 1040, 576, 148,
/* 1600 */ 148, 576, 1380, 121, 121, 571, 1021, 576, 266, 576,
/* 1610 */ 424, 122, 576, 452, 577, 452, 576, 553, 1028, 142,
/* 1620 */ 142, 169, 169, 576, 162, 162, 528, 889, 371, 452,
/* 1630 */ 152, 152, 151, 151, 1379, 149, 149, 109, 370, 150,
/* 1640 */ 150, 565, 576, 480, 576, 266, 86, 86, 576, 1092,
/* 1650 */ 1028, 1028, 1030, 1031, 35, 542, 482, 576, 266, 466,
/* 1660 */ 543, 123, 568, 1616, 4, 88, 88, 85, 85, 475,
/* 1670 */ 1040, 52, 52, 222, 901, 900, 121, 121, 571, 1188,
/* 1680 */ 58, 58, 244, 1032, 122, 889, 452, 577, 452, 908,
/* 1690 */ 909, 1028, 300, 347, 504, 111, 263, 361, 165, 111,
/* 1700 */ 111, 1088, 452, 263, 974, 1153, 266, 1092, 986, 987,
/* 1710 */ 942, 939, 125, 125, 565, 1103, 872, 1103, 159, 941,
/* 1720 */ 1309, 125, 1557, 1028, 1028, 1030, 1031, 35, 542, 337,
/* 1730 */ 1530, 205, 1529, 541, 499, 1589, 490, 348, 1376, 352,
/* 1740 */ 355, 1032, 357, 1040, 359, 1324, 1308, 366, 563, 121,
/* 1750 */ 121, 376, 1188, 1389, 1434, 1362, 280, 122, 1374, 452,
/* 1760 */ 577, 452, 167, 1439, 1028, 1289, 1280, 1268, 1267, 1269,
/* 1770 */ 1609, 1359, 312, 313, 314, 397, 12, 237, 224, 1421,
/* 1780 */ 295, 1416, 1409, 1426, 339, 484, 340, 509, 1371, 1612,
/* 1790 */ 1372, 1425, 1244, 404, 301, 228, 1028, 1028, 1030, 1031,
/* 1800 */ 35, 1601, 1192, 454, 345, 1307, 292, 369, 1502, 1501,
/* 1810 */ 270, 396, 396, 395, 277, 393, 1370, 1369, 859, 1549,
/* 1820 */ 186, 123, 568, 235, 4, 1188, 391, 210, 211, 223,
/* 1830 */ 1547, 239, 1241, 327, 422, 96, 220, 195, 571, 180,
/* 1840 */ 188, 326, 468, 469, 190, 191, 502, 192, 193, 566,
/* 1850 */ 247, 109, 1430, 491, 199, 251, 102, 281, 402, 476,
/* 1860 */ 405, 1496, 452, 497, 253, 1422, 13, 1428, 14, 1427,
/* 1870 */ 203, 1507, 241, 500, 565, 354, 407, 92, 95, 1270,
/* 1880 */ 175, 254, 518, 43, 1327, 255, 1326, 1325, 436, 1518,
/* 1890 */ 350, 1318, 104, 229, 893, 1626, 440, 441, 1625, 408,
/* 1900 */ 240, 1296, 268, 1040, 310, 269, 1297, 527, 444, 121,
/* 1910 */ 121, 368, 1295, 1594, 1624, 311, 1394, 122, 1317, 452,
/* 1920 */ 577, 452, 374, 1580, 1028, 1393, 140, 553, 11, 90,
/* 1930 */ 568, 385, 4, 116, 318, 414, 1579, 110, 1483, 537,
/* 1940 */ 320, 567, 1350, 555, 42, 579, 571, 1349, 1198, 383,
/* 1950 */ 276, 390, 216, 389, 278, 279, 1028, 1028, 1030, 1031,
/* 1960 */ 35, 172, 580, 1265, 458, 1260, 415, 416, 185, 156,
/* 1970 */ 452, 1534, 1535, 173, 1533, 1532, 89, 308, 225, 226,
/* 1980 */ 846, 174, 565, 453, 217, 1188, 322, 236, 1102, 154,
/* 1990 */ 1100, 330, 187, 176, 1223, 243, 189, 925, 338, 246,
/* 2000 */ 1116, 194, 177, 425, 178, 427, 98, 196, 99, 100,
/* 2010 */ 101, 1040, 179, 1119, 1115, 248, 249, 121, 121, 163,
/* 2020 */ 24, 250, 349, 1238, 496, 122, 1108, 452, 577, 452,
/* 2030 */ 1192, 454, 1028, 266, 292, 200, 252, 201, 861, 396,
/* 2040 */ 396, 395, 277, 393, 15, 501, 859, 370, 292, 256,
/* 2050 */ 202, 554, 505, 396, 396, 395, 277, 393, 103, 239,
/* 2060 */ 859, 327, 25, 26, 1028, 1028, 1030, 1031, 35, 326,
/* 2070 */ 362, 510, 891, 239, 365, 327, 513, 904, 105, 309,
/* 2080 */ 164, 181, 27, 326, 106, 521, 107, 1185, 1069, 1155,
/* 2090 */ 17, 1154, 230, 1188, 284, 286, 265, 204, 125, 1171,
/* 2100 */ 241, 28, 978, 972, 29, 41, 1175, 1179, 175, 1173,
/* 2110 */ 30, 43, 31, 8, 241, 1178, 32, 1160, 208, 549,
/* 2120 */ 33, 111, 175, 1083, 1070, 43, 1068, 1072, 240, 113,
/* 2130 */ 114, 34, 561, 118, 1124, 271, 1073, 36, 18, 572,
/* 2140 */ 1033, 873, 240, 124, 37, 935, 272, 273, 1617, 183,
/* 2150 */ 153, 394, 1194, 1193, 1256, 1256, 1256, 1256, 1256, 1256,
/* 2160 */ 1256, 1256, 1256, 414, 1256, 1256, 1256, 1256, 320, 567,
/* 2170 */ 1256, 1256, 1256, 1256, 1256, 1256, 1256, 414, 1256, 1256,
/* 2180 */ 1256, 1256, 320, 567, 1256, 1256, 1256, 1256, 1256, 1256,
/* 2190 */ 1256, 1256, 458, 1256, 1256, 1256, 1256, 1256, 1256, 1256,
/* 2200 */ 1256, 1256, 1256, 1256, 1256, 1256, 458,
};
static const YYCODETYPE yy_lookahead[] = {
/* 0 */ 277, 278, 279, 241, 242, 225, 195, 227, 195, 241,
/* 10 */ 242, 195, 217, 221, 195, 235, 254, 195, 256, 19,
/* 20 */ 225, 298, 254, 195, 256, 206, 213, 214, 206, 218,
/* 30 */ 219, 31, 206, 195, 218, 219, 195, 218, 219, 39,
/* 40 */ 218, 219, 313, 43, 44, 45, 317, 47, 48, 49,
/* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 19,
/* 60 */ 241, 242, 195, 241, 242, 195, 255, 241, 242, 277,
/* 70 */ 278, 279, 234, 254, 255, 256, 254, 255, 256, 218,
/* 80 */ 254, 240, 256, 43, 44, 45, 264, 47, 48, 49,
/* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 271,
/* 100 */ 287, 22, 23, 103, 104, 105, 106, 107, 108, 109,
/* 110 */ 110, 111, 112, 113, 114, 114, 47, 48, 49, 50,
/* 120 */ 187, 188, 189, 190, 191, 192, 190, 87, 192, 89,
/* 130 */ 197, 19, 199, 197, 318, 199, 320, 25, 195, 206,
/* 140 */ 299, 271, 206, 103, 104, 105, 106, 107, 108, 109,
/* 150 */ 110, 111, 112, 113, 114, 43, 44, 45, 195, 47,
/* 160 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
/* 170 */ 58, 60, 21, 195, 241, 242, 215, 241, 242, 312,
/* 180 */ 313, 102, 70, 205, 317, 207, 242, 254, 77, 256,
/* 190 */ 254, 122, 256, 55, 56, 57, 58, 59, 254, 88,
/* 200 */ 256, 90, 269, 240, 93, 269, 107, 108, 109, 110,
/* 210 */ 111, 112, 113, 114, 271, 103, 104, 105, 106, 107,
/* 220 */ 108, 109, 110, 111, 112, 113, 114, 313, 117, 118,
/* 230 */ 119, 317, 81, 195, 301, 19, 195, 301, 277, 278,
/* 240 */ 279, 103, 104, 105, 106, 107, 108, 109, 110, 111,
/* 250 */ 112, 113, 114, 55, 56, 57, 58, 146, 195, 43,
/* 260 */ 44, 45, 74, 47, 48, 49, 50, 51, 52, 53,
/* 270 */ 54, 55, 56, 57, 58, 124, 195, 60, 109, 110,
/* 280 */ 111, 112, 113, 114, 68, 195, 103, 104, 105, 106,
/* 290 */ 107, 108, 109, 110, 111, 112, 113, 114, 208, 218,
/* 300 */ 219, 103, 104, 105, 106, 107, 108, 109, 110, 111,
/* 310 */ 112, 113, 114, 162, 233, 24, 128, 129, 130, 103,
/* 320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
/* 330 */ 114, 195, 195, 215, 117, 118, 119, 120, 195, 19,
/* 340 */ 123, 124, 125, 207, 24, 74, 246, 60, 310, 311,
/* 350 */ 133, 60, 311, 82, 22, 218, 219, 257, 195, 19,
/* 360 */ 73, 218, 219, 43, 44, 45, 206, 47, 48, 49,
/* 370 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 22,
/* 380 */ 23, 218, 219, 43, 44, 45, 54, 47, 48, 49,
/* 390 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 128,
/* 400 */ 82, 241, 242, 195, 117, 118, 119, 289, 60, 118,
/* 410 */ 139, 140, 294, 195, 254, 195, 256, 195, 255, 259,
/* 420 */ 260, 73, 22, 103, 104, 105, 106, 107, 108, 109,
/* 430 */ 110, 111, 112, 113, 114, 206, 218, 219, 218, 219,
/* 440 */ 218, 219, 234, 103, 104, 105, 106, 107, 108, 109,
/* 450 */ 110, 111, 112, 113, 114, 318, 319, 139, 140, 102,
/* 460 */ 60, 318, 319, 221, 19, 117, 118, 119, 23, 195,
/* 470 */ 241, 242, 313, 255, 206, 255, 317, 255, 206, 129,
/* 480 */ 130, 206, 264, 254, 264, 256, 264, 195, 43, 44,
/* 490 */ 45, 151, 47, 48, 49, 50, 51, 52, 53, 54,
/* 500 */ 55, 56, 57, 58, 246, 213, 214, 19, 19, 241,
/* 510 */ 242, 195, 23, 241, 242, 257, 241, 242, 118, 277,
/* 520 */ 278, 279, 254, 29, 256, 60, 254, 33, 256, 254,
/* 530 */ 206, 256, 43, 44, 45, 218, 47, 48, 49, 50,
/* 540 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104,
/* 550 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
/* 560 */ 66, 19, 218, 60, 120, 241, 242, 123, 124, 125,
/* 570 */ 60, 232, 77, 19, 20, 26, 22, 133, 254, 287,
/* 580 */ 256, 265, 117, 118, 119, 90, 312, 313, 93, 47,
/* 590 */ 36, 317, 103, 104, 105, 106, 107, 108, 109, 110,
/* 600 */ 111, 112, 113, 114, 116, 117, 277, 278, 279, 60,
/* 610 */ 107, 108, 19, 276, 60, 31, 23, 152, 195, 116,
/* 620 */ 117, 118, 119, 39, 121, 276, 72, 117, 118, 119,
/* 630 */ 166, 167, 129, 145, 237, 238, 43, 44, 45, 276,
/* 640 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
/* 650 */ 57, 58, 315, 316, 144, 101, 19, 154, 116, 156,
/* 660 */ 23, 107, 108, 109, 315, 316, 117, 118, 119, 115,
/* 670 */ 60, 117, 118, 119, 132, 200, 122, 60, 315, 316,
/* 680 */ 43, 44, 45, 272, 47, 48, 49, 50, 51, 52,
/* 690 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106,
/* 700 */ 107, 108, 109, 110, 111, 112, 113, 114, 154, 155,
/* 710 */ 156, 157, 158, 212, 213, 214, 22, 195, 101, 22,
/* 720 */ 60, 19, 20, 60, 22, 139, 140, 117, 118, 119,
/* 730 */ 22, 251, 195, 253, 117, 118, 195, 183, 36, 122,
/* 740 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
/* 750 */ 113, 114, 195, 195, 60, 218, 219, 60, 195, 284,
/* 760 */ 19, 25, 60, 288, 23, 237, 238, 22, 60, 109,
/* 770 */ 233, 154, 155, 156, 72, 218, 219, 117, 118, 119,
/* 780 */ 117, 118, 119, 116, 43, 44, 45, 265, 47, 48,
/* 790 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
/* 800 */ 183, 243, 25, 101, 19, 60, 265, 144, 23, 107,
/* 810 */ 108, 117, 118, 119, 117, 118, 119, 115, 151, 117,
/* 820 */ 118, 119, 82, 195, 122, 117, 118, 119, 43, 44,
/* 830 */ 45, 195, 47, 48, 49, 50, 51, 52, 53, 54,
/* 840 */ 55, 56, 57, 58, 103, 104, 105, 106, 107, 108,
/* 850 */ 109, 110, 111, 112, 113, 114, 154, 155, 156, 157,
/* 860 */ 158, 121, 117, 118, 119, 307, 101, 309, 195, 22,
/* 870 */ 23, 195, 25, 19, 35, 139, 140, 195, 24, 139,
/* 880 */ 140, 208, 195, 118, 109, 183, 22, 122, 103, 104,
/* 890 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
/* 900 */ 304, 305, 77, 230, 127, 232, 67, 195, 19, 195,
/* 910 */ 195, 136, 23, 88, 75, 90, 141, 203, 93, 154,
/* 920 */ 155, 156, 208, 295, 60, 243, 22, 23, 19, 25,
/* 930 */ 218, 219, 43, 44, 45, 100, 47, 48, 49, 50,
/* 940 */ 51, 52, 53, 54, 55, 56, 57, 58, 183, 102,
/* 950 */ 96, 195, 43, 44, 45, 240, 47, 48, 49, 50,
/* 960 */ 51, 52, 53, 54, 55, 56, 57, 58, 114, 134,
/* 970 */ 131, 146, 25, 286, 120, 121, 122, 123, 124, 125,
/* 980 */ 126, 117, 118, 119, 313, 195, 132, 195, 317, 307,
/* 990 */ 195, 309, 103, 104, 105, 106, 107, 108, 109, 110,
/* 1000 */ 111, 112, 113, 114, 195, 195, 102, 195, 195, 195,
/* 1010 */ 218, 219, 103, 104, 105, 106, 107, 108, 109, 110,
/* 1020 */ 111, 112, 113, 114, 77, 233, 195, 60, 218, 219,
/* 1030 */ 218, 219, 218, 219, 23, 195, 25, 90, 243, 159,
/* 1040 */ 93, 161, 19, 233, 195, 233, 23, 233, 16, 218,
/* 1050 */ 219, 195, 243, 212, 213, 214, 262, 263, 218, 219,
/* 1060 */ 195, 271, 19, 307, 233, 309, 43, 44, 45, 160,
/* 1070 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
/* 1080 */ 57, 58, 195, 218, 219, 118, 43, 44, 45, 240,
/* 1090 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
/* 1100 */ 57, 58, 307, 195, 309, 218, 219, 263, 12, 195,
/* 1110 */ 78, 267, 80, 112, 113, 114, 307, 22, 309, 24,
/* 1120 */ 255, 281, 266, 27, 107, 108, 103, 104, 105, 106,
/* 1130 */ 107, 108, 109, 110, 111, 112, 113, 114, 42, 195,
/* 1140 */ 11, 22, 255, 24, 195, 195, 103, 104, 105, 106,
/* 1150 */ 107, 108, 109, 110, 111, 112, 113, 114, 19, 195,
/* 1160 */ 64, 195, 218, 219, 195, 313, 195, 218, 219, 317,
/* 1170 */ 74, 154, 195, 156, 195, 195, 19, 233, 23, 60,
/* 1180 */ 25, 24, 218, 219, 218, 219, 195, 218, 219, 218,
/* 1190 */ 219, 128, 129, 130, 162, 263, 19, 218, 219, 267,
/* 1200 */ 43, 44, 45, 160, 47, 48, 49, 50, 51, 52,
/* 1210 */ 53, 54, 55, 56, 57, 58, 19, 240, 228, 255,
/* 1220 */ 43, 44, 45, 25, 47, 48, 49, 50, 51, 52,
/* 1230 */ 53, 54, 55, 56, 57, 58, 135, 118, 137, 138,
/* 1240 */ 43, 44, 45, 22, 47, 48, 49, 50, 51, 52,
/* 1250 */ 53, 54, 55, 56, 57, 58, 117, 266, 129, 130,
/* 1260 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
/* 1270 */ 113, 114, 195, 195, 119, 295, 195, 206, 195, 195,
/* 1280 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
/* 1290 */ 113, 114, 195, 195, 195, 218, 219, 195, 195, 144,
/* 1300 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
/* 1310 */ 113, 114, 241, 242, 67, 218, 219, 218, 219, 146,
/* 1320 */ 19, 218, 219, 240, 215, 254, 136, 256, 107, 108,
/* 1330 */ 195, 141, 255, 86, 128, 129, 130, 195, 165, 195,
/* 1340 */ 19, 143, 95, 272, 25, 44, 45, 266, 47, 48,
/* 1350 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
/* 1360 */ 218, 219, 218, 219, 195, 12, 45, 195, 47, 48,
/* 1370 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
/* 1380 */ 27, 23, 7, 8, 9, 210, 211, 218, 219, 116,
/* 1390 */ 218, 219, 228, 16, 147, 42, 195, 295, 195, 19,
/* 1400 */ 20, 266, 22, 294, 103, 104, 105, 106, 107, 108,
/* 1410 */ 109, 110, 111, 112, 113, 114, 36, 64, 145, 218,
/* 1420 */ 219, 218, 219, 195, 103, 104, 105, 106, 107, 108,
/* 1430 */ 109, 110, 111, 112, 113, 114, 195, 154, 119, 156,
/* 1440 */ 60, 189, 190, 191, 192, 195, 218, 219, 195, 197,
/* 1450 */ 195, 199, 72, 195, 19, 78, 195, 80, 206, 218,
/* 1460 */ 219, 195, 82, 144, 210, 211, 195, 15, 218, 219,
/* 1470 */ 47, 218, 219, 218, 219, 259, 260, 195, 261, 218,
/* 1480 */ 219, 101, 302, 303, 218, 219, 195, 107, 108, 218,
/* 1490 */ 219, 150, 151, 241, 242, 115, 25, 117, 118, 119,
/* 1500 */ 218, 219, 122, 195, 146, 195, 254, 195, 256, 218,
/* 1510 */ 219, 246, 25, 61, 246, 19, 20, 195, 22, 139,
/* 1520 */ 140, 269, 257, 195, 266, 257, 218, 219, 218, 219,
/* 1530 */ 218, 219, 36, 246, 154, 155, 156, 157, 158, 116,
/* 1540 */ 218, 219, 195, 22, 257, 49, 218, 219, 23, 195,
/* 1550 */ 25, 195, 117, 301, 195, 25, 60, 195, 195, 23,
/* 1560 */ 195, 25, 195, 183, 24, 218, 219, 130, 72, 195,
/* 1570 */ 22, 195, 218, 219, 218, 219, 195, 218, 219, 195,
/* 1580 */ 218, 219, 86, 218, 219, 218, 219, 91, 19, 20,
/* 1590 */ 153, 22, 218, 219, 218, 219, 195, 101, 195, 218,
/* 1600 */ 219, 195, 195, 107, 108, 36, 23, 195, 25, 195,
/* 1610 */ 62, 115, 195, 117, 118, 119, 195, 146, 122, 218,
/* 1620 */ 219, 218, 219, 195, 218, 219, 19, 60, 122, 60,
/* 1630 */ 218, 219, 218, 219, 195, 218, 219, 150, 132, 218,
/* 1640 */ 219, 72, 195, 23, 195, 25, 218, 219, 195, 60,
/* 1650 */ 154, 155, 156, 157, 158, 86, 23, 195, 25, 195,
/* 1660 */ 91, 19, 20, 142, 22, 218, 219, 218, 219, 130,
/* 1670 */ 101, 218, 219, 143, 121, 122, 107, 108, 36, 183,
/* 1680 */ 218, 219, 142, 60, 115, 118, 117, 118, 119, 7,
/* 1690 */ 8, 122, 153, 23, 23, 25, 25, 23, 23, 25,
/* 1700 */ 25, 23, 60, 25, 23, 98, 25, 118, 84, 85,
/* 1710 */ 23, 23, 25, 25, 72, 154, 23, 156, 25, 23,
/* 1720 */ 228, 25, 195, 154, 155, 156, 157, 158, 86, 195,
/* 1730 */ 195, 258, 195, 91, 291, 322, 195, 195, 195, 195,
/* 1740 */ 195, 118, 195, 101, 195, 195, 195, 195, 238, 107,
/* 1750 */ 108, 195, 183, 195, 195, 195, 290, 115, 195, 117,
/* 1760 */ 118, 119, 244, 195, 122, 195, 195, 195, 195, 195,
/* 1770 */ 195, 258, 258, 258, 258, 193, 245, 300, 216, 274,
/* 1780 */ 247, 270, 270, 274, 296, 296, 248, 222, 262, 198,
/* 1790 */ 262, 274, 61, 274, 248, 231, 154, 155, 156, 157,
/* 1800 */ 158, 0, 1, 2, 247, 227, 5, 221, 221, 221,
/* 1810 */ 142, 10, 11, 12, 13, 14, 262, 262, 17, 202,
/* 1820 */ 300, 19, 20, 300, 22, 183, 247, 251, 251, 245,
/* 1830 */ 202, 30, 38, 32, 202, 152, 151, 22, 36, 43,
/* 1840 */ 236, 40, 18, 202, 239, 239, 18, 239, 239, 283,
/* 1850 */ 201, 150, 236, 202, 236, 201, 159, 202, 248, 248,
/* 1860 */ 248, 248, 60, 63, 201, 275, 273, 275, 273, 275,
/* 1870 */ 22, 286, 71, 223, 72, 202, 223, 297, 297, 202,
/* 1880 */ 79, 201, 116, 82, 220, 201, 220, 220, 65, 293,
/* 1890 */ 292, 229, 22, 166, 127, 226, 24, 114, 226, 223,
/* 1900 */ 99, 222, 202, 101, 285, 92, 220, 308, 83, 107,
/* 1910 */ 108, 220, 220, 316, 220, 285, 268, 115, 229, 117,
/* 1920 */ 118, 119, 223, 321, 122, 268, 149, 146, 22, 19,
/* 1930 */ 20, 202, 22, 159, 282, 134, 321, 148, 280, 147,
/* 1940 */ 139, 140, 252, 141, 25, 204, 36, 252, 13, 251,
/* 1950 */ 196, 248, 250, 249, 196, 6, 154, 155, 156, 157,
/* 1960 */ 158, 209, 194, 194, 163, 194, 306, 306, 303, 224,
/* 1970 */ 60, 215, 215, 209, 215, 215, 215, 224, 216, 216,
/* 1980 */ 4, 209, 72, 3, 22, 183, 164, 15, 23, 16,
/* 1990 */ 23, 140, 152, 131, 25, 24, 143, 20, 16, 145,
/* 2000 */ 1, 143, 131, 62, 131, 37, 54, 152, 54, 54,
/* 2010 */ 54, 101, 131, 117, 1, 34, 142, 107, 108, 5,
/* 2020 */ 22, 116, 162, 76, 41, 115, 69, 117, 118, 119,
/* 2030 */ 1, 2, 122, 25, 5, 69, 142, 116, 20, 10,
/* 2040 */ 11, 12, 13, 14, 24, 19, 17, 132, 5, 126,
/* 2050 */ 22, 141, 68, 10, 11, 12, 13, 14, 22, 30,
/* 2060 */ 17, 32, 22, 22, 154, 155, 156, 157, 158, 40,
/* 2070 */ 23, 68, 60, 30, 24, 32, 97, 28, 22, 68,
/* 2080 */ 23, 37, 34, 40, 150, 22, 25, 23, 23, 23,
/* 2090 */ 22, 98, 142, 183, 23, 23, 34, 22, 25, 89,
/* 2100 */ 71, 34, 117, 144, 34, 22, 76, 76, 79, 87,
/* 2110 */ 34, 82, 34, 44, 71, 94, 34, 23, 25, 24,
/* 2120 */ 34, 25, 79, 23, 23, 82, 23, 23, 99, 143,
/* 2130 */ 143, 22, 25, 25, 23, 22, 11, 22, 22, 25,
/* 2140 */ 23, 23, 99, 22, 22, 136, 142, 142, 142, 25,
/* 2150 */ 23, 15, 1, 1, 323, 323, 323, 323, 323, 323,
/* 2160 */ 323, 323, 323, 134, 323, 323, 323, 323, 139, 140,
/* 2170 */ 323, 323, 323, 323, 323, 323, 323, 134, 323, 323,
/* 2180 */ 323, 323, 139, 140, 323, 323, 323, 323, 323, 323,
/* 2190 */ 323, 323, 163, 323, 323, 323, 323, 323, 323, 323,
/* 2200 */ 323, 323, 323, 323, 323, 323, 163, 323, 323, 323,
/* 2210 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2220 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2230 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2240 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2250 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2260 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2270 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2280 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2290 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2300 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2310 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2320 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2330 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2340 */ 323, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2350 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2360 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2370 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2380 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2390 */ 187, 187, 187, 187,
};
#define YY_SHIFT_COUNT (582)
#define YY_SHIFT_MIN (0)
#define YY_SHIFT_MAX (2152)
static const unsigned short int yy_shift_ofst[] = {
/* 0 */ 2029, 1801, 2043, 1380, 1380, 318, 271, 1496, 1569, 1642,
/* 10 */ 702, 702, 702, 740, 318, 318, 318, 318, 318, 0,
/* 20 */ 0, 216, 1177, 702, 702, 702, 702, 702, 702, 702,
/* 30 */ 702, 702, 702, 702, 702, 702, 702, 702, 503, 503,
/* 40 */ 111, 111, 217, 287, 348, 610, 610, 736, 736, 736,
/* 50 */ 736, 40, 112, 320, 340, 445, 489, 593, 637, 741,
/* 60 */ 785, 889, 909, 1023, 1043, 1157, 1177, 1177, 1177, 1177,
/* 70 */ 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
/* 80 */ 1177, 1177, 1177, 1177, 1197, 1177, 1301, 1321, 1321, 554,
/* 90 */ 1802, 1910, 702, 702, 702, 702, 702, 702, 702, 702,
/* 100 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702,
/* 110 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702,
/* 120 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702,
/* 130 */ 702, 702, 702, 702, 702, 702, 702, 702, 702, 702,
/* 140 */ 702, 702, 138, 198, 198, 198, 198, 198, 198, 198,
/* 150 */ 183, 99, 169, 549, 610, 151, 542, 610, 610, 1017,
/* 160 */ 1017, 610, 1001, 350, 464, 464, 464, 586, 1, 1,
/* 170 */ 2207, 2207, 854, 854, 854, 465, 694, 694, 694, 694,
/* 180 */ 1096, 1096, 825, 549, 847, 904, 610, 610, 610, 610,
/* 190 */ 610, 610, 610, 610, 610, 610, 610, 610, 610, 610,
/* 200 */ 610, 610, 610, 610, 610, 488, 947, 947, 610, 1129,
/* 210 */ 495, 495, 1139, 1139, 967, 967, 1173, 2207, 2207, 2207,
/* 220 */ 2207, 2207, 2207, 2207, 617, 765, 765, 697, 444, 708,
/* 230 */ 660, 745, 510, 663, 864, 610, 610, 610, 610, 610,
/* 240 */ 610, 610, 610, 610, 610, 188, 610, 610, 610, 610,
/* 250 */ 610, 610, 610, 610, 610, 610, 610, 610, 839, 839,
/* 260 */ 839, 610, 610, 610, 1155, 610, 610, 610, 1119, 1247,
/* 270 */ 610, 1353, 610, 610, 610, 610, 610, 610, 610, 610,
/* 280 */ 1063, 494, 1101, 291, 291, 291, 291, 1319, 1101, 1101,
/* 290 */ 775, 1221, 1375, 1452, 667, 1341, 1198, 1341, 1435, 1487,
/* 300 */ 667, 667, 1487, 667, 1198, 1435, 777, 1011, 1423, 584,
/* 310 */ 584, 584, 1273, 1273, 1273, 1273, 1471, 1471, 880, 1530,
/* 320 */ 1190, 1095, 1731, 1731, 1668, 1668, 1794, 1794, 1668, 1683,
/* 330 */ 1685, 1815, 1796, 1824, 1824, 1824, 1824, 1668, 1828, 1701,
/* 340 */ 1685, 1685, 1701, 1815, 1796, 1701, 1796, 1701, 1668, 1828,
/* 350 */ 1697, 1800, 1668, 1828, 1848, 1668, 1828, 1668, 1828, 1848,
/* 360 */ 1766, 1766, 1766, 1823, 1870, 1870, 1848, 1766, 1767, 1766,
/* 370 */ 1823, 1766, 1766, 1727, 1872, 1783, 1783, 1848, 1668, 1813,
/* 380 */ 1813, 1825, 1825, 1777, 1781, 1906, 1668, 1774, 1777, 1789,
/* 390 */ 1792, 1701, 1919, 1935, 1935, 1949, 1949, 1949, 2207, 2207,
/* 400 */ 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207,
/* 410 */ 2207, 2207, 2207, 69, 1032, 79, 357, 1377, 1206, 400,
/* 420 */ 1525, 835, 332, 1540, 1437, 1539, 1536, 1548, 1583, 1620,
/* 430 */ 1633, 1670, 1671, 1674, 1567, 1553, 1682, 1506, 1675, 1358,
/* 440 */ 1607, 1589, 1678, 1681, 1624, 1687, 1688, 1283, 1561, 1693,
/* 450 */ 1696, 1623, 1521, 1976, 1980, 1962, 1822, 1972, 1973, 1965,
/* 460 */ 1967, 1851, 1840, 1862, 1969, 1969, 1971, 1853, 1977, 1854,
/* 470 */ 1982, 1999, 1858, 1871, 1969, 1873, 1941, 1968, 1969, 1855,
/* 480 */ 1952, 1954, 1955, 1956, 1881, 1896, 1981, 1874, 2013, 2014,
/* 490 */ 1998, 1905, 1860, 1957, 2008, 1966, 1947, 1983, 1894, 1921,
/* 500 */ 2020, 2018, 2026, 1915, 1923, 2028, 1984, 2036, 2040, 2047,
/* 510 */ 2041, 2003, 2012, 2050, 1979, 2049, 2056, 2011, 2044, 2057,
/* 520 */ 2048, 1934, 2063, 2064, 2065, 2061, 2066, 2068, 1993, 1950,
/* 530 */ 2071, 2072, 1985, 2062, 2075, 1959, 2073, 2067, 2070, 2076,
/* 540 */ 2078, 2010, 2030, 2022, 2069, 2031, 2021, 2082, 2094, 2083,
/* 550 */ 2095, 2093, 2096, 2086, 1986, 1987, 2100, 2073, 2101, 2103,
/* 560 */ 2104, 2109, 2107, 2108, 2111, 2113, 2125, 2115, 2116, 2117,
/* 570 */ 2118, 2121, 2122, 2114, 2009, 2004, 2005, 2006, 2124, 2127,
/* 580 */ 2136, 2151, 2152,
};
#define YY_REDUCE_COUNT (412)
#define YY_REDUCE_MIN (-277)
#define YY_REDUCE_MAX (1772)
static const short yy_reduce_ofst[] = {
/* 0 */ -67, 1252, -64, -178, -181, 160, 1071, 143, -184, 137,
/* 10 */ 218, 220, 222, -174, 229, 268, 272, 275, 324, -208,
/* 20 */ 242, -277, -39, 81, 537, 792, 810, 812, -189, 814,
/* 30 */ 831, 163, 865, 944, 887, 840, 964, 1077, -187, 292,
/* 40 */ -133, 274, 673, 558, 682, 795, 809, -238, -232, -238,
/* 50 */ -232, 329, 329, 329, 329, 329, 329, 329, 329, 329,
/* 60 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 329,
/* 70 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 329,
/* 80 */ 329, 329, 329, 329, 329, 329, 329, 329, 329, 557,
/* 90 */ 712, 949, 966, 969, 971, 979, 1097, 1099, 1103, 1142,
/* 100 */ 1144, 1169, 1172, 1201, 1203, 1228, 1241, 1250, 1253, 1255,
/* 110 */ 1261, 1266, 1271, 1282, 1291, 1308, 1310, 1312, 1322, 1328,
/* 120 */ 1347, 1354, 1356, 1359, 1362, 1365, 1367, 1374, 1376, 1381,
/* 130 */ 1401, 1403, 1406, 1412, 1414, 1417, 1421, 1428, 1447, 1449,
/* 140 */ 1453, 1462, 329, 329, 329, 329, 329, 329, 329, 329,
/* 150 */ 329, 329, 329, -22, -159, 475, -220, 756, 38, 501,
/* 160 */ 841, 714, 329, 118, 337, 349, 363, -56, 329, 329,
/* 170 */ 329, 329, -205, -205, -205, 687, -172, -130, -57, 790,
/* 180 */ 397, 528, -271, 136, 596, 596, 90, 316, 522, 541,
/* 190 */ -37, 715, 849, 977, 628, 856, 980, 991, 1081, 1102,
/* 200 */ 1135, 1083, -162, 208, 1258, 794, -86, 159, 41, 1109,
/* 210 */ 671, 852, 844, 932, 1175, 1254, 480, 1180, 100, 258,
/* 220 */ 1265, 1268, 1216, 1287, -139, 317, 344, 63, 339, 423,
/* 230 */ 563, 636, 676, 813, 908, 914, 950, 1078, 1084, 1098,
/* 240 */ 1363, 1384, 1407, 1439, 1464, 411, 1527, 1534, 1535, 1537,
/* 250 */ 1541, 1542, 1543, 1544, 1545, 1547, 1549, 1550, 990, 1164,
/* 260 */ 1492, 1551, 1552, 1556, 1217, 1558, 1559, 1560, 1473, 1413,
/* 270 */ 1563, 1510, 1568, 563, 1570, 1571, 1572, 1573, 1574, 1575,
/* 280 */ 1443, 1466, 1518, 1513, 1514, 1515, 1516, 1217, 1518, 1518,
/* 290 */ 1531, 1562, 1582, 1477, 1505, 1511, 1533, 1512, 1488, 1538,
/* 300 */ 1509, 1517, 1546, 1519, 1557, 1489, 1565, 1564, 1578, 1586,
/* 310 */ 1587, 1588, 1526, 1528, 1554, 1555, 1576, 1577, 1566, 1579,
/* 320 */ 1584, 1591, 1520, 1523, 1617, 1628, 1580, 1581, 1632, 1585,
/* 330 */ 1590, 1593, 1604, 1605, 1606, 1608, 1609, 1641, 1649, 1610,
/* 340 */ 1592, 1594, 1611, 1595, 1616, 1612, 1618, 1613, 1651, 1654,
/* 350 */ 1596, 1598, 1655, 1663, 1650, 1673, 1680, 1677, 1684, 1653,
/* 360 */ 1664, 1666, 1667, 1662, 1669, 1672, 1676, 1686, 1679, 1691,
/* 370 */ 1689, 1692, 1694, 1597, 1599, 1619, 1630, 1699, 1700, 1602,
/* 380 */ 1615, 1648, 1657, 1690, 1698, 1658, 1729, 1652, 1695, 1702,
/* 390 */ 1704, 1703, 1741, 1754, 1758, 1768, 1769, 1771, 1660, 1661,
/* 400 */ 1665, 1752, 1756, 1757, 1759, 1760, 1764, 1745, 1753, 1762,
/* 410 */ 1763, 1761, 1772,
};
static const YYACTIONTYPE yy_default[] = {
/* 0 */ 1663, 1663, 1663, 1491, 1254, 1367, 1254, 1254, 1254, 1254,
/* 10 */ 1491, 1491, 1491, 1254, 1254, 1254, 1254, 1254, 1254, 1397,
/* 20 */ 1397, 1544, 1287, 1254, 1254, 1254, 1254, 1254, 1254, 1254,
/* 30 */ 1254, 1254, 1254, 1254, 1254, 1490, 1254, 1254, 1254, 1254,
/* 40 */ 1578, 1578, 1254, 1254, 1254, 1254, 1254, 1563, 1562, 1254,
|
| ︙ | ︙ | |||
175353 175354 175355 175356 175357 175358 175359 175360 175361 175362 175363 175364 175365 175366 |
0, /* SELECT_COLUMN => nothing */
0, /* IF_NULL_ROW => nothing */
0, /* ASTERISK => nothing */
0, /* SPAN => nothing */
0, /* ERROR => nothing */
0, /* QNUMBER => nothing */
0, /* SPACE => nothing */
0, /* ILLEGAL => nothing */
};
#endif /* YYFALLBACK */
/* The following structure represents a single element of the
** parser's stack. Information stored includes:
**
| > | 175737 175738 175739 175740 175741 175742 175743 175744 175745 175746 175747 175748 175749 175750 175751 |
0, /* SELECT_COLUMN => nothing */
0, /* IF_NULL_ROW => nothing */
0, /* ASTERISK => nothing */
0, /* SPAN => nothing */
0, /* ERROR => nothing */
0, /* QNUMBER => nothing */
0, /* SPACE => nothing */
0, /* COMMENT => nothing */
0, /* ILLEGAL => nothing */
};
#endif /* YYFALLBACK */
/* The following structure represents a single element of the
** parser's stack. Information stored includes:
**
|
| ︙ | ︙ | |||
175622 175623 175624 175625 175626 175627 175628 | /* 178 */ "SELECT_COLUMN", /* 179 */ "IF_NULL_ROW", /* 180 */ "ASTERISK", /* 181 */ "SPAN", /* 182 */ "ERROR", /* 183 */ "QNUMBER", /* 184 */ "SPACE", | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | 176007 176008 176009 176010 176011 176012 176013 176014 176015 176016 176017 176018 176019 176020 176021 176022 176023 176024 176025 176026 176027 176028 176029 176030 176031 176032 176033 176034 176035 176036 176037 176038 176039 176040 176041 176042 176043 176044 176045 176046 176047 176048 176049 176050 176051 176052 176053 176054 176055 176056 176057 176058 176059 176060 176061 176062 176063 176064 176065 176066 176067 176068 176069 176070 176071 176072 176073 176074 176075 176076 176077 176078 176079 176080 176081 176082 176083 176084 176085 176086 176087 176088 176089 176090 176091 176092 176093 176094 176095 176096 176097 176098 176099 176100 176101 176102 176103 176104 176105 176106 176107 176108 176109 176110 176111 176112 176113 176114 176115 176116 176117 176118 176119 176120 176121 176122 176123 176124 176125 176126 176127 176128 176129 176130 176131 176132 176133 176134 176135 176136 176137 176138 176139 176140 176141 176142 176143 176144 176145 176146 176147 176148 176149 176150 176151 176152 176153 176154 176155 176156 176157 176158 |
/* 178 */ "SELECT_COLUMN",
/* 179 */ "IF_NULL_ROW",
/* 180 */ "ASTERISK",
/* 181 */ "SPAN",
/* 182 */ "ERROR",
/* 183 */ "QNUMBER",
/* 184 */ "SPACE",
/* 185 */ "COMMENT",
/* 186 */ "ILLEGAL",
/* 187 */ "input",
/* 188 */ "cmdlist",
/* 189 */ "ecmd",
/* 190 */ "cmdx",
/* 191 */ "explain",
/* 192 */ "cmd",
/* 193 */ "transtype",
/* 194 */ "trans_opt",
/* 195 */ "nm",
/* 196 */ "savepoint_opt",
/* 197 */ "create_table",
/* 198 */ "create_table_args",
/* 199 */ "createkw",
/* 200 */ "temp",
/* 201 */ "ifnotexists",
/* 202 */ "dbnm",
/* 203 */ "columnlist",
/* 204 */ "conslist_opt",
/* 205 */ "table_option_set",
/* 206 */ "select",
/* 207 */ "table_option",
/* 208 */ "columnname",
/* 209 */ "carglist",
/* 210 */ "typetoken",
/* 211 */ "typename",
/* 212 */ "signed",
/* 213 */ "plus_num",
/* 214 */ "minus_num",
/* 215 */ "scanpt",
/* 216 */ "scantok",
/* 217 */ "ccons",
/* 218 */ "term",
/* 219 */ "expr",
/* 220 */ "onconf",
/* 221 */ "sortorder",
/* 222 */ "autoinc",
/* 223 */ "eidlist_opt",
/* 224 */ "refargs",
/* 225 */ "defer_subclause",
/* 226 */ "generated",
/* 227 */ "refarg",
/* 228 */ "refact",
/* 229 */ "init_deferred_pred_opt",
/* 230 */ "conslist",
/* 231 */ "tconscomma",
/* 232 */ "tcons",
/* 233 */ "sortlist",
/* 234 */ "eidlist",
/* 235 */ "defer_subclause_opt",
/* 236 */ "orconf",
/* 237 */ "resolvetype",
/* 238 */ "raisetype",
/* 239 */ "ifexists",
/* 240 */ "fullname",
/* 241 */ "selectnowith",
/* 242 */ "oneselect",
/* 243 */ "wqlist",
/* 244 */ "multiselect_op",
/* 245 */ "distinct",
/* 246 */ "selcollist",
/* 247 */ "from",
/* 248 */ "where_opt",
/* 249 */ "groupby_opt",
/* 250 */ "having_opt",
/* 251 */ "orderby_opt",
/* 252 */ "limit_opt",
/* 253 */ "window_clause",
/* 254 */ "values",
/* 255 */ "nexprlist",
/* 256 */ "mvalues",
/* 257 */ "sclp",
/* 258 */ "as",
/* 259 */ "seltablist",
/* 260 */ "stl_prefix",
/* 261 */ "joinop",
/* 262 */ "on_using",
/* 263 */ "indexed_by",
/* 264 */ "exprlist",
/* 265 */ "xfullname",
/* 266 */ "idlist",
/* 267 */ "indexed_opt",
/* 268 */ "nulls",
/* 269 */ "with",
/* 270 */ "where_opt_ret",
/* 271 */ "setlist",
/* 272 */ "insert_cmd",
/* 273 */ "idlist_opt",
/* 274 */ "upsert",
/* 275 */ "returning",
/* 276 */ "filter_over",
/* 277 */ "likeop",
/* 278 */ "between_op",
/* 279 */ "in_op",
/* 280 */ "paren_exprlist",
/* 281 */ "case_operand",
/* 282 */ "case_exprlist",
/* 283 */ "case_else",
/* 284 */ "uniqueflag",
/* 285 */ "collate",
/* 286 */ "vinto",
/* 287 */ "nmnum",
/* 288 */ "trigger_decl",
/* 289 */ "trigger_cmd_list",
/* 290 */ "trigger_time",
/* 291 */ "trigger_event",
/* 292 */ "foreach_clause",
/* 293 */ "when_clause",
/* 294 */ "trigger_cmd",
/* 295 */ "trnm",
/* 296 */ "tridxby",
/* 297 */ "database_kw_opt",
/* 298 */ "key_opt",
/* 299 */ "add_column_fullname",
/* 300 */ "kwcolumn_opt",
/* 301 */ "create_vtab",
/* 302 */ "vtabarglist",
/* 303 */ "vtabarg",
/* 304 */ "vtabargtoken",
/* 305 */ "lp",
/* 306 */ "anylist",
/* 307 */ "wqitem",
/* 308 */ "wqas",
/* 309 */ "withnm",
/* 310 */ "windowdefn_list",
/* 311 */ "windowdefn",
/* 312 */ "window",
/* 313 */ "frame_opt",
/* 314 */ "part_opt",
/* 315 */ "filter_clause",
/* 316 */ "over_clause",
/* 317 */ "range_or_rows",
/* 318 */ "frame_bound",
/* 319 */ "frame_bound_s",
/* 320 */ "frame_bound_e",
/* 321 */ "frame_exclude_opt",
/* 322 */ "frame_exclude",
};
#endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */
#ifndef NDEBUG
/* For tracing reduce actions, the names of all rules are required.
*/
static const char *const yyRuleName[] = {
|
| ︙ | ︙ | |||
176298 176299 176300 176301 176302 176303 176304 |
** being destroyed before it is finished parsing.
**
** Note: during a reduce, the only symbols destroyed are those
** which appear on the RHS of the rule, but which are *not* used
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < | | > | | | | | | | | | | | | 176684 176685 176686 176687 176688 176689 176690 176691 176692 176693 176694 176695 176696 176697 176698 176699 176700 176701 176702 176703 176704 176705 176706 176707 176708 176709 176710 176711 176712 176713 176714 176715 176716 176717 176718 176719 176720 176721 176722 176723 176724 176725 176726 176727 176728 176729 176730 176731 176732 176733 176734 176735 176736 176737 176738 176739 176740 176741 176742 176743 176744 176745 176746 176747 176748 176749 176750 176751 176752 176753 176754 176755 176756 176757 176758 176759 176760 176761 176762 176763 176764 176765 176766 176767 176768 176769 176770 176771 176772 176773 176774 176775 176776 176777 176778 176779 176780 176781 176782 176783 176784 176785 176786 176787 176788 176789 |
** being destroyed before it is finished parsing.
**
** Note: during a reduce, the only symbols destroyed are those
** which appear on the RHS of the rule, but which are *not* used
** inside the C code.
*/
/********* Begin destructor definitions ***************************************/
case 206: /* select */
case 241: /* selectnowith */
case 242: /* oneselect */
case 254: /* values */
case 256: /* mvalues */
{
sqlite3SelectDelete(pParse->db, (yypminor->yy637));
}
break;
case 218: /* term */
case 219: /* expr */
case 248: /* where_opt */
case 250: /* having_opt */
case 270: /* where_opt_ret */
case 281: /* case_operand */
case 283: /* case_else */
case 286: /* vinto */
case 293: /* when_clause */
case 298: /* key_opt */
case 315: /* filter_clause */
{
sqlite3ExprDelete(pParse->db, (yypminor->yy590));
}
break;
case 223: /* eidlist_opt */
case 233: /* sortlist */
case 234: /* eidlist */
case 246: /* selcollist */
case 249: /* groupby_opt */
case 251: /* orderby_opt */
case 255: /* nexprlist */
case 257: /* sclp */
case 264: /* exprlist */
case 271: /* setlist */
case 280: /* paren_exprlist */
case 282: /* case_exprlist */
case 314: /* part_opt */
{
sqlite3ExprListDelete(pParse->db, (yypminor->yy402));
}
break;
case 240: /* fullname */
case 247: /* from */
case 259: /* seltablist */
case 260: /* stl_prefix */
case 265: /* xfullname */
{
sqlite3SrcListDelete(pParse->db, (yypminor->yy563));
}
break;
case 243: /* wqlist */
{
sqlite3WithDelete(pParse->db, (yypminor->yy125));
}
break;
case 253: /* window_clause */
case 310: /* windowdefn_list */
{
sqlite3WindowListDelete(pParse->db, (yypminor->yy483));
}
break;
case 266: /* idlist */
case 273: /* idlist_opt */
{
sqlite3IdListDelete(pParse->db, (yypminor->yy204));
}
break;
case 276: /* filter_over */
case 311: /* windowdefn */
case 312: /* window */
case 313: /* frame_opt */
case 316: /* over_clause */
{
sqlite3WindowDelete(pParse->db, (yypminor->yy483));
}
break;
case 289: /* trigger_cmd_list */
case 294: /* trigger_cmd */
{
sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy319));
}
break;
case 291: /* trigger_event */
{
sqlite3IdListDelete(pParse->db, (yypminor->yy28).b);
}
break;
case 318: /* frame_bound */
case 319: /* frame_bound_s */
case 320: /* frame_bound_e */
{
sqlite3ExprDelete(pParse->db, (yypminor->yy205).pExpr);
}
break;
/********* End destructor definitions *****************************************/
default: break; /* If no destructor action specified: do nothing */
}
}
|
| ︙ | ︙ | |||
176691 176692 176693 176694 176695 176696 176697 |
yytos->minor.yy0 = yyMinor;
yyTraceShift(yypParser, yyNewState, "Shift");
}
/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side
** of that rule */
static const YYCODETYPE yyRuleInfoLhs[] = {
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 177077 177078 177079 177080 177081 177082 177083 177084 177085 177086 177087 177088 177089 177090 177091 177092 177093 177094 177095 177096 177097 177098 177099 177100 177101 177102 177103 177104 177105 177106 177107 177108 177109 177110 177111 177112 177113 177114 177115 177116 177117 177118 177119 177120 177121 177122 177123 177124 177125 177126 177127 177128 177129 177130 177131 177132 177133 177134 177135 177136 177137 177138 177139 177140 177141 177142 177143 177144 177145 177146 177147 177148 177149 177150 177151 177152 177153 177154 177155 177156 177157 177158 177159 177160 177161 177162 177163 177164 177165 177166 177167 177168 177169 177170 177171 177172 177173 177174 177175 177176 177177 177178 177179 177180 177181 177182 177183 177184 177185 177186 177187 177188 177189 177190 177191 177192 177193 177194 177195 177196 177197 177198 177199 177200 177201 177202 177203 177204 177205 177206 177207 177208 177209 177210 177211 177212 177213 177214 177215 177216 177217 177218 177219 177220 177221 177222 177223 177224 177225 177226 177227 177228 177229 177230 177231 177232 177233 177234 177235 177236 177237 177238 177239 177240 177241 177242 177243 177244 177245 177246 177247 177248 177249 177250 177251 177252 177253 177254 177255 177256 177257 177258 177259 177260 177261 177262 177263 177264 177265 177266 177267 177268 177269 177270 177271 177272 177273 177274 177275 177276 177277 177278 177279 177280 177281 177282 177283 177284 177285 177286 177287 177288 177289 177290 177291 177292 177293 177294 177295 177296 177297 177298 177299 177300 177301 177302 177303 177304 177305 177306 177307 177308 177309 177310 177311 177312 177313 177314 177315 177316 177317 177318 177319 177320 177321 177322 177323 177324 177325 177326 177327 177328 177329 177330 177331 177332 177333 177334 177335 177336 177337 177338 177339 177340 177341 177342 177343 177344 177345 177346 177347 177348 177349 177350 177351 177352 177353 177354 177355 177356 177357 177358 177359 177360 177361 177362 177363 177364 177365 177366 177367 177368 177369 177370 177371 177372 177373 177374 177375 177376 177377 177378 177379 177380 177381 177382 177383 177384 177385 177386 177387 177388 177389 177390 177391 177392 177393 177394 177395 177396 177397 177398 177399 177400 177401 177402 177403 177404 177405 177406 177407 177408 177409 177410 177411 177412 177413 177414 177415 177416 177417 177418 177419 177420 177421 177422 177423 177424 177425 177426 177427 177428 177429 177430 177431 177432 177433 177434 177435 177436 177437 177438 177439 177440 177441 177442 177443 177444 177445 177446 177447 177448 177449 177450 177451 177452 177453 177454 177455 177456 177457 177458 177459 177460 177461 177462 177463 177464 177465 177466 177467 177468 177469 177470 177471 177472 177473 177474 177475 177476 177477 177478 177479 177480 177481 177482 177483 177484 177485 177486 177487 177488 177489 177490 177491 177492 177493 177494 177495 177496 177497 177498 177499 |
yytos->minor.yy0 = yyMinor;
yyTraceShift(yypParser, yyNewState, "Shift");
}
/* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side
** of that rule */
static const YYCODETYPE yyRuleInfoLhs[] = {
191, /* (0) explain ::= EXPLAIN */
191, /* (1) explain ::= EXPLAIN QUERY PLAN */
190, /* (2) cmdx ::= cmd */
192, /* (3) cmd ::= BEGIN transtype trans_opt */
193, /* (4) transtype ::= */
193, /* (5) transtype ::= DEFERRED */
193, /* (6) transtype ::= IMMEDIATE */
193, /* (7) transtype ::= EXCLUSIVE */
192, /* (8) cmd ::= COMMIT|END trans_opt */
192, /* (9) cmd ::= ROLLBACK trans_opt */
192, /* (10) cmd ::= SAVEPOINT nm */
192, /* (11) cmd ::= RELEASE savepoint_opt nm */
192, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
197, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
199, /* (14) createkw ::= CREATE */
201, /* (15) ifnotexists ::= */
201, /* (16) ifnotexists ::= IF NOT EXISTS */
200, /* (17) temp ::= TEMP */
200, /* (18) temp ::= */
198, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */
198, /* (20) create_table_args ::= AS select */
205, /* (21) table_option_set ::= */
205, /* (22) table_option_set ::= table_option_set COMMA table_option */
207, /* (23) table_option ::= WITHOUT nm */
207, /* (24) table_option ::= nm */
208, /* (25) columnname ::= nm typetoken */
210, /* (26) typetoken ::= */
210, /* (27) typetoken ::= typename LP signed RP */
210, /* (28) typetoken ::= typename LP signed COMMA signed RP */
211, /* (29) typename ::= typename ID|STRING */
215, /* (30) scanpt ::= */
216, /* (31) scantok ::= */
217, /* (32) ccons ::= CONSTRAINT nm */
217, /* (33) ccons ::= DEFAULT scantok term */
217, /* (34) ccons ::= DEFAULT LP expr RP */
217, /* (35) ccons ::= DEFAULT PLUS scantok term */
217, /* (36) ccons ::= DEFAULT MINUS scantok term */
217, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */
217, /* (38) ccons ::= NOT NULL onconf */
217, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */
217, /* (40) ccons ::= UNIQUE onconf */
217, /* (41) ccons ::= CHECK LP expr RP */
217, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */
217, /* (43) ccons ::= defer_subclause */
217, /* (44) ccons ::= COLLATE ID|STRING */
226, /* (45) generated ::= LP expr RP */
226, /* (46) generated ::= LP expr RP ID */
222, /* (47) autoinc ::= */
222, /* (48) autoinc ::= AUTOINCR */
224, /* (49) refargs ::= */
224, /* (50) refargs ::= refargs refarg */
227, /* (51) refarg ::= MATCH nm */
227, /* (52) refarg ::= ON INSERT refact */
227, /* (53) refarg ::= ON DELETE refact */
227, /* (54) refarg ::= ON UPDATE refact */
228, /* (55) refact ::= SET NULL */
228, /* (56) refact ::= SET DEFAULT */
228, /* (57) refact ::= CASCADE */
228, /* (58) refact ::= RESTRICT */
228, /* (59) refact ::= NO ACTION */
225, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
225, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
229, /* (62) init_deferred_pred_opt ::= */
229, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */
229, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
204, /* (65) conslist_opt ::= */
231, /* (66) tconscomma ::= COMMA */
232, /* (67) tcons ::= CONSTRAINT nm */
232, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
232, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */
232, /* (70) tcons ::= CHECK LP expr RP onconf */
232, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
235, /* (72) defer_subclause_opt ::= */
220, /* (73) onconf ::= */
220, /* (74) onconf ::= ON CONFLICT resolvetype */
236, /* (75) orconf ::= */
236, /* (76) orconf ::= OR resolvetype */
237, /* (77) resolvetype ::= IGNORE */
237, /* (78) resolvetype ::= REPLACE */
192, /* (79) cmd ::= DROP TABLE ifexists fullname */
239, /* (80) ifexists ::= IF EXISTS */
239, /* (81) ifexists ::= */
192, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
192, /* (83) cmd ::= DROP VIEW ifexists fullname */
192, /* (84) cmd ::= select */
206, /* (85) select ::= WITH wqlist selectnowith */
206, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */
206, /* (87) select ::= selectnowith */
241, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */
244, /* (89) multiselect_op ::= UNION */
244, /* (90) multiselect_op ::= UNION ALL */
244, /* (91) multiselect_op ::= EXCEPT|INTERSECT */
242, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
242, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
254, /* (94) values ::= VALUES LP nexprlist RP */
242, /* (95) oneselect ::= mvalues */
256, /* (96) mvalues ::= values COMMA LP nexprlist RP */
256, /* (97) mvalues ::= mvalues COMMA LP nexprlist RP */
245, /* (98) distinct ::= DISTINCT */
245, /* (99) distinct ::= ALL */
245, /* (100) distinct ::= */
257, /* (101) sclp ::= */
246, /* (102) selcollist ::= sclp scanpt expr scanpt as */
246, /* (103) selcollist ::= sclp scanpt STAR */
246, /* (104) selcollist ::= sclp scanpt nm DOT STAR */
258, /* (105) as ::= AS nm */
258, /* (106) as ::= */
247, /* (107) from ::= */
247, /* (108) from ::= FROM seltablist */
260, /* (109) stl_prefix ::= seltablist joinop */
260, /* (110) stl_prefix ::= */
259, /* (111) seltablist ::= stl_prefix nm dbnm as on_using */
259, /* (112) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
259, /* (113) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
259, /* (114) seltablist ::= stl_prefix LP select RP as on_using */
259, /* (115) seltablist ::= stl_prefix LP seltablist RP as on_using */
202, /* (116) dbnm ::= */
202, /* (117) dbnm ::= DOT nm */
240, /* (118) fullname ::= nm */
240, /* (119) fullname ::= nm DOT nm */
265, /* (120) xfullname ::= nm */
265, /* (121) xfullname ::= nm DOT nm */
265, /* (122) xfullname ::= nm DOT nm AS nm */
265, /* (123) xfullname ::= nm AS nm */
261, /* (124) joinop ::= COMMA|JOIN */
261, /* (125) joinop ::= JOIN_KW JOIN */
261, /* (126) joinop ::= JOIN_KW nm JOIN */
261, /* (127) joinop ::= JOIN_KW nm nm JOIN */
262, /* (128) on_using ::= ON expr */
262, /* (129) on_using ::= USING LP idlist RP */
262, /* (130) on_using ::= */
267, /* (131) indexed_opt ::= */
263, /* (132) indexed_by ::= INDEXED BY nm */
263, /* (133) indexed_by ::= NOT INDEXED */
251, /* (134) orderby_opt ::= */
251, /* (135) orderby_opt ::= ORDER BY sortlist */
233, /* (136) sortlist ::= sortlist COMMA expr sortorder nulls */
233, /* (137) sortlist ::= expr sortorder nulls */
221, /* (138) sortorder ::= ASC */
221, /* (139) sortorder ::= DESC */
221, /* (140) sortorder ::= */
268, /* (141) nulls ::= NULLS FIRST */
268, /* (142) nulls ::= NULLS LAST */
268, /* (143) nulls ::= */
249, /* (144) groupby_opt ::= */
249, /* (145) groupby_opt ::= GROUP BY nexprlist */
250, /* (146) having_opt ::= */
250, /* (147) having_opt ::= HAVING expr */
252, /* (148) limit_opt ::= */
252, /* (149) limit_opt ::= LIMIT expr */
252, /* (150) limit_opt ::= LIMIT expr OFFSET expr */
252, /* (151) limit_opt ::= LIMIT expr COMMA expr */
192, /* (152) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
248, /* (153) where_opt ::= */
248, /* (154) where_opt ::= WHERE expr */
270, /* (155) where_opt_ret ::= */
270, /* (156) where_opt_ret ::= WHERE expr */
270, /* (157) where_opt_ret ::= RETURNING selcollist */
270, /* (158) where_opt_ret ::= WHERE expr RETURNING selcollist */
192, /* (159) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
271, /* (160) setlist ::= setlist COMMA nm EQ expr */
271, /* (161) setlist ::= setlist COMMA LP idlist RP EQ expr */
271, /* (162) setlist ::= nm EQ expr */
271, /* (163) setlist ::= LP idlist RP EQ expr */
192, /* (164) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
192, /* (165) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
274, /* (166) upsert ::= */
274, /* (167) upsert ::= RETURNING selcollist */
274, /* (168) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
274, /* (169) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
274, /* (170) upsert ::= ON CONFLICT DO NOTHING returning */
274, /* (171) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
275, /* (172) returning ::= RETURNING selcollist */
272, /* (173) insert_cmd ::= INSERT orconf */
272, /* (174) insert_cmd ::= REPLACE */
273, /* (175) idlist_opt ::= */
273, /* (176) idlist_opt ::= LP idlist RP */
266, /* (177) idlist ::= idlist COMMA nm */
266, /* (178) idlist ::= nm */
219, /* (179) expr ::= LP expr RP */
219, /* (180) expr ::= ID|INDEXED|JOIN_KW */
219, /* (181) expr ::= nm DOT nm */
219, /* (182) expr ::= nm DOT nm DOT nm */
218, /* (183) term ::= NULL|FLOAT|BLOB */
218, /* (184) term ::= STRING */
218, /* (185) term ::= INTEGER */
219, /* (186) expr ::= VARIABLE */
219, /* (187) expr ::= expr COLLATE ID|STRING */
219, /* (188) expr ::= CAST LP expr AS typetoken RP */
219, /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
219, /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
219, /* (191) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
219, /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
219, /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
219, /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
218, /* (195) term ::= CTIME_KW */
219, /* (196) expr ::= LP nexprlist COMMA expr RP */
219, /* (197) expr ::= expr AND expr */
219, /* (198) expr ::= expr OR expr */
219, /* (199) expr ::= expr LT|GT|GE|LE expr */
219, /* (200) expr ::= expr EQ|NE expr */
219, /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
219, /* (202) expr ::= expr PLUS|MINUS expr */
219, /* (203) expr ::= expr STAR|SLASH|REM expr */
219, /* (204) expr ::= expr CONCAT expr */
277, /* (205) likeop ::= NOT LIKE_KW|MATCH */
219, /* (206) expr ::= expr likeop expr */
219, /* (207) expr ::= expr likeop expr ESCAPE expr */
219, /* (208) expr ::= expr ISNULL|NOTNULL */
219, /* (209) expr ::= expr NOT NULL */
219, /* (210) expr ::= expr IS expr */
219, /* (211) expr ::= expr IS NOT expr */
219, /* (212) expr ::= expr IS NOT DISTINCT FROM expr */
219, /* (213) expr ::= expr IS DISTINCT FROM expr */
219, /* (214) expr ::= NOT expr */
219, /* (215) expr ::= BITNOT expr */
219, /* (216) expr ::= PLUS|MINUS expr */
219, /* (217) expr ::= expr PTR expr */
278, /* (218) between_op ::= BETWEEN */
278, /* (219) between_op ::= NOT BETWEEN */
219, /* (220) expr ::= expr between_op expr AND expr */
279, /* (221) in_op ::= IN */
279, /* (222) in_op ::= NOT IN */
219, /* (223) expr ::= expr in_op LP exprlist RP */
219, /* (224) expr ::= LP select RP */
219, /* (225) expr ::= expr in_op LP select RP */
219, /* (226) expr ::= expr in_op nm dbnm paren_exprlist */
219, /* (227) expr ::= EXISTS LP select RP */
219, /* (228) expr ::= CASE case_operand case_exprlist case_else END */
282, /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */
282, /* (230) case_exprlist ::= WHEN expr THEN expr */
283, /* (231) case_else ::= ELSE expr */
283, /* (232) case_else ::= */
281, /* (233) case_operand ::= */
264, /* (234) exprlist ::= */
255, /* (235) nexprlist ::= nexprlist COMMA expr */
255, /* (236) nexprlist ::= expr */
280, /* (237) paren_exprlist ::= */
280, /* (238) paren_exprlist ::= LP exprlist RP */
192, /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
284, /* (240) uniqueflag ::= UNIQUE */
284, /* (241) uniqueflag ::= */
223, /* (242) eidlist_opt ::= */
223, /* (243) eidlist_opt ::= LP eidlist RP */
234, /* (244) eidlist ::= eidlist COMMA nm collate sortorder */
234, /* (245) eidlist ::= nm collate sortorder */
285, /* (246) collate ::= */
285, /* (247) collate ::= COLLATE ID|STRING */
192, /* (248) cmd ::= DROP INDEX ifexists fullname */
192, /* (249) cmd ::= VACUUM vinto */
192, /* (250) cmd ::= VACUUM nm vinto */
286, /* (251) vinto ::= INTO expr */
286, /* (252) vinto ::= */
192, /* (253) cmd ::= PRAGMA nm dbnm */
192, /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */
192, /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */
192, /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */
192, /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */
213, /* (258) plus_num ::= PLUS INTEGER|FLOAT */
214, /* (259) minus_num ::= MINUS INTEGER|FLOAT */
192, /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
288, /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
290, /* (262) trigger_time ::= BEFORE|AFTER */
290, /* (263) trigger_time ::= INSTEAD OF */
290, /* (264) trigger_time ::= */
291, /* (265) trigger_event ::= DELETE|INSERT */
291, /* (266) trigger_event ::= UPDATE */
291, /* (267) trigger_event ::= UPDATE OF idlist */
293, /* (268) when_clause ::= */
293, /* (269) when_clause ::= WHEN expr */
289, /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
289, /* (271) trigger_cmd_list ::= trigger_cmd SEMI */
295, /* (272) trnm ::= nm DOT nm */
296, /* (273) tridxby ::= INDEXED BY nm */
296, /* (274) tridxby ::= NOT INDEXED */
294, /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
294, /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
294, /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
294, /* (278) trigger_cmd ::= scanpt select scanpt */
219, /* (279) expr ::= RAISE LP IGNORE RP */
219, /* (280) expr ::= RAISE LP raisetype COMMA expr RP */
238, /* (281) raisetype ::= ROLLBACK */
238, /* (282) raisetype ::= ABORT */
238, /* (283) raisetype ::= FAIL */
192, /* (284) cmd ::= DROP TRIGGER ifexists fullname */
192, /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
192, /* (286) cmd ::= DETACH database_kw_opt expr */
298, /* (287) key_opt ::= */
298, /* (288) key_opt ::= KEY expr */
192, /* (289) cmd ::= REINDEX */
192, /* (290) cmd ::= REINDEX nm dbnm */
192, /* (291) cmd ::= ANALYZE */
192, /* (292) cmd ::= ANALYZE nm dbnm */
192, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */
192, /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
192, /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
299, /* (296) add_column_fullname ::= fullname */
192, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
192, /* (298) cmd ::= create_vtab */
192, /* (299) cmd ::= create_vtab LP vtabarglist RP */
301, /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
303, /* (301) vtabarg ::= */
304, /* (302) vtabargtoken ::= ANY */
304, /* (303) vtabargtoken ::= lp anylist RP */
305, /* (304) lp ::= LP */
269, /* (305) with ::= WITH wqlist */
269, /* (306) with ::= WITH RECURSIVE wqlist */
308, /* (307) wqas ::= AS */
308, /* (308) wqas ::= AS MATERIALIZED */
308, /* (309) wqas ::= AS NOT MATERIALIZED */
307, /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */
309, /* (311) withnm ::= nm */
243, /* (312) wqlist ::= wqitem */
243, /* (313) wqlist ::= wqlist COMMA wqitem */
310, /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */
311, /* (315) windowdefn ::= nm AS LP window RP */
312, /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
312, /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
312, /* (318) window ::= ORDER BY sortlist frame_opt */
312, /* (319) window ::= nm ORDER BY sortlist frame_opt */
312, /* (320) window ::= nm frame_opt */
313, /* (321) frame_opt ::= */
313, /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
313, /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
317, /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */
319, /* (325) frame_bound_s ::= frame_bound */
319, /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */
320, /* (327) frame_bound_e ::= frame_bound */
320, /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */
318, /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */
318, /* (330) frame_bound ::= CURRENT ROW */
321, /* (331) frame_exclude_opt ::= */
321, /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */
322, /* (333) frame_exclude ::= NO OTHERS */
322, /* (334) frame_exclude ::= CURRENT ROW */
322, /* (335) frame_exclude ::= GROUP|TIES */
253, /* (336) window_clause ::= WINDOW windowdefn_list */
276, /* (337) filter_over ::= filter_clause over_clause */
276, /* (338) filter_over ::= over_clause */
276, /* (339) filter_over ::= filter_clause */
316, /* (340) over_clause ::= OVER LP window RP */
316, /* (341) over_clause ::= OVER nm */
315, /* (342) filter_clause ::= FILTER LP WHERE expr RP */
218, /* (343) term ::= QNUMBER */
187, /* (344) input ::= cmdlist */
188, /* (345) cmdlist ::= cmdlist ecmd */
188, /* (346) cmdlist ::= ecmd */
189, /* (347) ecmd ::= SEMI */
189, /* (348) ecmd ::= cmdx SEMI */
189, /* (349) ecmd ::= explain cmdx SEMI */
194, /* (350) trans_opt ::= */
194, /* (351) trans_opt ::= TRANSACTION */
194, /* (352) trans_opt ::= TRANSACTION nm */
196, /* (353) savepoint_opt ::= SAVEPOINT */
196, /* (354) savepoint_opt ::= */
192, /* (355) cmd ::= create_table create_table_args */
205, /* (356) table_option_set ::= table_option */
203, /* (357) columnlist ::= columnlist COMMA columnname carglist */
203, /* (358) columnlist ::= columnname carglist */
195, /* (359) nm ::= ID|INDEXED|JOIN_KW */
195, /* (360) nm ::= STRING */
210, /* (361) typetoken ::= typename */
211, /* (362) typename ::= ID|STRING */
212, /* (363) signed ::= plus_num */
212, /* (364) signed ::= minus_num */
209, /* (365) carglist ::= carglist ccons */
209, /* (366) carglist ::= */
217, /* (367) ccons ::= NULL onconf */
217, /* (368) ccons ::= GENERATED ALWAYS AS generated */
217, /* (369) ccons ::= AS generated */
204, /* (370) conslist_opt ::= COMMA conslist */
230, /* (371) conslist ::= conslist tconscomma tcons */
230, /* (372) conslist ::= tcons */
231, /* (373) tconscomma ::= */
235, /* (374) defer_subclause_opt ::= defer_subclause */
237, /* (375) resolvetype ::= raisetype */
241, /* (376) selectnowith ::= oneselect */
242, /* (377) oneselect ::= values */
257, /* (378) sclp ::= selcollist COMMA */
258, /* (379) as ::= ID|STRING */
267, /* (380) indexed_opt ::= indexed_by */
275, /* (381) returning ::= */
219, /* (382) expr ::= term */
277, /* (383) likeop ::= LIKE_KW|MATCH */
281, /* (384) case_operand ::= expr */
264, /* (385) exprlist ::= nexprlist */
287, /* (386) nmnum ::= plus_num */
287, /* (387) nmnum ::= nm */
287, /* (388) nmnum ::= ON */
287, /* (389) nmnum ::= DELETE */
287, /* (390) nmnum ::= DEFAULT */
213, /* (391) plus_num ::= INTEGER|FLOAT */
292, /* (392) foreach_clause ::= */
292, /* (393) foreach_clause ::= FOR EACH ROW */
295, /* (394) trnm ::= nm */
296, /* (395) tridxby ::= */
297, /* (396) database_kw_opt ::= DATABASE */
297, /* (397) database_kw_opt ::= */
300, /* (398) kwcolumn_opt ::= */
300, /* (399) kwcolumn_opt ::= COLUMNKW */
302, /* (400) vtabarglist ::= vtabarg */
302, /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */
303, /* (402) vtabarg ::= vtabarg vtabargtoken */
306, /* (403) anylist ::= */
306, /* (404) anylist ::= anylist LP anylist RP */
306, /* (405) anylist ::= anylist ANY */
269, /* (406) with ::= */
310, /* (407) windowdefn_list ::= windowdefn */
312, /* (408) window ::= frame_opt */
};
/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
** of symbols on the right-hand side of that rule. */
static const signed char yyRuleInfoNRhs[] = {
-1, /* (0) explain ::= EXPLAIN */
-3, /* (1) explain ::= EXPLAIN QUERY PLAN */
|
| ︙ | ︙ | |||
177565 177566 177567 177568 177569 177570 177571 |
case 1: /* explain ::= EXPLAIN QUERY PLAN */
{ if( pParse->pReprepare==0 ) pParse->explain = 2; }
break;
case 2: /* cmdx ::= cmd */
{ sqlite3FinishCoding(pParse); }
break;
case 3: /* cmd ::= BEGIN transtype trans_opt */
| | | | | 177951 177952 177953 177954 177955 177956 177957 177958 177959 177960 177961 177962 177963 177964 177965 177966 177967 177968 177969 177970 177971 177972 177973 177974 |
case 1: /* explain ::= EXPLAIN QUERY PLAN */
{ if( pParse->pReprepare==0 ) pParse->explain = 2; }
break;
case 2: /* cmdx ::= cmd */
{ sqlite3FinishCoding(pParse); }
break;
case 3: /* cmd ::= BEGIN transtype trans_opt */
{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy502);}
break;
case 4: /* transtype ::= */
{yymsp[1].minor.yy502 = TK_DEFERRED;}
break;
case 5: /* transtype ::= DEFERRED */
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
case 324: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==324);
{yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-X*/}
break;
case 8: /* cmd ::= COMMIT|END trans_opt */
case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
{sqlite3EndTransaction(pParse,yymsp[-1].major);}
break;
case 10: /* cmd ::= SAVEPOINT nm */
{
|
| ︙ | ︙ | |||
177597 177598 177599 177600 177601 177602 177603 |
case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
{
sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
}
break;
case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
| | > | > | | | | | | | | | | | | | | | 177983 177984 177985 177986 177987 177988 177989 177990 177991 177992 177993 177994 177995 177996 177997 177998 177999 178000 178001 178002 178003 178004 178005 178006 178007 178008 178009 178010 178011 178012 178013 178014 178015 178016 178017 178018 178019 178020 178021 178022 178023 178024 178025 178026 178027 178028 178029 178030 178031 178032 178033 178034 178035 178036 178037 178038 178039 178040 178041 178042 178043 178044 178045 178046 178047 178048 178049 178050 178051 178052 178053 178054 178055 178056 178057 178058 |
case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
{
sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0);
}
break;
case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */
{
sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy502,0,0,yymsp[-2].minor.yy502);
}
break;
case 14: /* createkw ::= CREATE */
{
disableLookaside(pParse);
}
break;
case 15: /* ifnotexists ::= */
case 18: /* temp ::= */ yytestcase(yyruleno==18);
case 47: /* autoinc ::= */ yytestcase(yyruleno==47);
case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62);
case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72);
case 81: /* ifexists ::= */ yytestcase(yyruleno==81);
case 100: /* distinct ::= */ yytestcase(yyruleno==100);
case 246: /* collate ::= */ yytestcase(yyruleno==246);
{yymsp[1].minor.yy502 = 0;}
break;
case 16: /* ifnotexists ::= IF NOT EXISTS */
{yymsp[-2].minor.yy502 = 1;}
break;
case 17: /* temp ::= TEMP */
{yymsp[0].minor.yy502 = pParse->db->init.busy==0;}
break;
case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */
{
sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy9,0);
}
break;
case 20: /* create_table_args ::= AS select */
{
sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy637);
sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy637);
}
break;
case 21: /* table_option_set ::= */
{yymsp[1].minor.yy9 = 0;}
break;
case 22: /* table_option_set ::= table_option_set COMMA table_option */
{yylhsminor.yy9 = yymsp[-2].minor.yy9|yymsp[0].minor.yy9;}
yymsp[-2].minor.yy9 = yylhsminor.yy9;
break;
case 23: /* table_option ::= WITHOUT nm */
{
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
yymsp[-1].minor.yy9 = TF_WithoutRowid | TF_NoVisibleRowid;
}else{
yymsp[-1].minor.yy9 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
break;
case 24: /* table_option ::= nm */
{
if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){
yylhsminor.yy9 = TF_Strict;
}else{
yylhsminor.yy9 = 0;
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
}
}
yymsp[0].minor.yy9 = yylhsminor.yy9;
break;
case 25: /* columnname ::= nm typetoken */
{sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);}
break;
case 26: /* typetoken ::= */
case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65);
case 106: /* as ::= */ yytestcase(yyruleno==106);
|
| ︙ | ︙ | |||
177682 177683 177684 177685 177686 177687 177688 |
break;
case 29: /* typename ::= typename ID|STRING */
{yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
case 30: /* scanpt ::= */
{
assert( yyLookahead!=YYNOCODE );
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 178070 178071 178072 178073 178074 178075 178076 178077 178078 178079 178080 178081 178082 178083 178084 178085 178086 178087 178088 178089 178090 178091 178092 178093 178094 178095 178096 178097 178098 178099 178100 178101 178102 178103 178104 178105 178106 178107 178108 178109 178110 178111 178112 178113 178114 178115 178116 178117 178118 178119 178120 178121 178122 178123 178124 178125 178126 178127 178128 178129 178130 178131 178132 178133 178134 178135 178136 178137 178138 178139 178140 178141 178142 178143 178144 178145 178146 178147 178148 178149 178150 178151 178152 178153 178154 178155 178156 178157 178158 178159 178160 178161 178162 178163 178164 178165 178166 178167 178168 178169 178170 178171 178172 178173 178174 178175 178176 178177 178178 178179 178180 178181 178182 178183 178184 178185 178186 178187 178188 178189 178190 178191 178192 178193 178194 178195 178196 178197 178198 178199 178200 178201 178202 178203 178204 178205 178206 178207 178208 178209 178210 178211 178212 178213 178214 178215 178216 178217 178218 178219 178220 178221 178222 178223 178224 178225 178226 178227 178228 178229 178230 178231 178232 178233 178234 178235 178236 178237 178238 178239 178240 178241 178242 178243 178244 178245 178246 178247 178248 178249 178250 178251 178252 178253 178254 178255 178256 178257 178258 178259 178260 178261 178262 178263 178264 178265 178266 178267 178268 178269 178270 178271 178272 178273 178274 178275 178276 178277 178278 178279 178280 178281 178282 178283 178284 178285 178286 178287 178288 178289 178290 178291 178292 178293 178294 178295 178296 178297 178298 178299 178300 178301 178302 178303 178304 178305 178306 178307 178308 178309 178310 178311 178312 178313 178314 178315 178316 178317 178318 178319 178320 178321 178322 178323 178324 178325 178326 178327 178328 178329 178330 178331 178332 178333 178334 178335 178336 178337 178338 178339 178340 178341 178342 178343 178344 178345 178346 178347 178348 178349 178350 178351 178352 178353 178354 178355 178356 178357 178358 178359 178360 178361 178362 178363 178364 178365 178366 178367 178368 178369 178370 178371 178372 178373 178374 178375 178376 178377 178378 178379 178380 178381 178382 178383 178384 178385 178386 178387 178388 178389 178390 178391 178392 178393 178394 178395 178396 178397 178398 178399 178400 178401 178402 178403 178404 178405 178406 178407 178408 178409 178410 178411 178412 178413 178414 178415 178416 178417 178418 178419 178420 178421 178422 178423 178424 178425 178426 178427 178428 |
break;
case 29: /* typename ::= typename ID|STRING */
{yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
break;
case 30: /* scanpt ::= */
{
assert( yyLookahead!=YYNOCODE );
yymsp[1].minor.yy342 = yyLookaheadToken.z;
}
break;
case 31: /* scantok ::= */
{
assert( yyLookahead!=YYNOCODE );
yymsp[1].minor.yy0 = yyLookaheadToken;
}
break;
case 32: /* ccons ::= CONSTRAINT nm */
case 67: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==67);
{ASSERT_IS_CREATE; pParse->u1.cr.constraintName = yymsp[0].minor.yy0;}
break;
case 33: /* ccons ::= DEFAULT scantok term */
{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy590,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
break;
case 34: /* ccons ::= DEFAULT LP expr RP */
{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy590,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
break;
case 35: /* ccons ::= DEFAULT PLUS scantok term */
{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy590,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);}
break;
case 36: /* ccons ::= DEFAULT MINUS scantok term */
{
Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy590, 0);
sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);
}
break;
case 37: /* ccons ::= DEFAULT scantok ID|INDEXED */
{
Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0);
if( p ){
sqlite3ExprIdToTrueFalse(p);
testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) );
}
sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n);
}
break;
case 38: /* ccons ::= NOT NULL onconf */
{sqlite3AddNotNull(pParse, yymsp[0].minor.yy502);}
break;
case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy502,yymsp[0].minor.yy502,yymsp[-2].minor.yy502);}
break;
case 40: /* ccons ::= UNIQUE onconf */
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy502,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
case 41: /* ccons ::= CHECK LP expr RP */
{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy590,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);}
break;
case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */
{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy402,yymsp[0].minor.yy502);}
break;
case 43: /* ccons ::= defer_subclause */
{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy502);}
break;
case 44: /* ccons ::= COLLATE ID|STRING */
{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
break;
case 45: /* generated ::= LP expr RP */
{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy590,0);}
break;
case 46: /* generated ::= LP expr RP ID */
{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy590,&yymsp[0].minor.yy0);}
break;
case 48: /* autoinc ::= AUTOINCR */
{yymsp[0].minor.yy502 = 1;}
break;
case 49: /* refargs ::= */
{ yymsp[1].minor.yy502 = OE_None*0x0101; /* EV: R-19803-45884 */}
break;
case 50: /* refargs ::= refargs refarg */
{ yymsp[-1].minor.yy502 = (yymsp[-1].minor.yy502 & ~yymsp[0].minor.yy481.mask) | yymsp[0].minor.yy481.value; }
break;
case 51: /* refarg ::= MATCH nm */
{ yymsp[-1].minor.yy481.value = 0; yymsp[-1].minor.yy481.mask = 0x000000; }
break;
case 52: /* refarg ::= ON INSERT refact */
{ yymsp[-2].minor.yy481.value = 0; yymsp[-2].minor.yy481.mask = 0x000000; }
break;
case 53: /* refarg ::= ON DELETE refact */
{ yymsp[-2].minor.yy481.value = yymsp[0].minor.yy502; yymsp[-2].minor.yy481.mask = 0x0000ff; }
break;
case 54: /* refarg ::= ON UPDATE refact */
{ yymsp[-2].minor.yy481.value = yymsp[0].minor.yy502<<8; yymsp[-2].minor.yy481.mask = 0x00ff00; }
break;
case 55: /* refact ::= SET NULL */
{ yymsp[-1].minor.yy502 = OE_SetNull; /* EV: R-33326-45252 */}
break;
case 56: /* refact ::= SET DEFAULT */
{ yymsp[-1].minor.yy502 = OE_SetDflt; /* EV: R-33326-45252 */}
break;
case 57: /* refact ::= CASCADE */
{ yymsp[0].minor.yy502 = OE_Cascade; /* EV: R-33326-45252 */}
break;
case 58: /* refact ::= RESTRICT */
{ yymsp[0].minor.yy502 = OE_Restrict; /* EV: R-33326-45252 */}
break;
case 59: /* refact ::= NO ACTION */
{ yymsp[-1].minor.yy502 = OE_None; /* EV: R-33326-45252 */}
break;
case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
{yymsp[-2].minor.yy502 = 0;}
break;
case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76);
case 173: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==173);
{yymsp[-1].minor.yy502 = yymsp[0].minor.yy502;}
break;
case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */
case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80);
case 219: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==219);
case 222: /* in_op ::= NOT IN */ yytestcase(yyruleno==222);
case 247: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==247);
{yymsp[-1].minor.yy502 = 1;}
break;
case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
{yymsp[-1].minor.yy502 = 0;}
break;
case 66: /* tconscomma ::= COMMA */
{ASSERT_IS_CREATE; pParse->u1.cr.constraintName.n = 0;}
break;
case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy402,yymsp[0].minor.yy502,yymsp[-2].minor.yy502,0);}
break;
case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy402,yymsp[0].minor.yy502,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
break;
case 70: /* tcons ::= CHECK LP expr RP onconf */
{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy590,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);}
break;
case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
{
sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy402, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy402, yymsp[-1].minor.yy502);
sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy502);
}
break;
case 73: /* onconf ::= */
case 75: /* orconf ::= */ yytestcase(yyruleno==75);
{yymsp[1].minor.yy502 = OE_Default;}
break;
case 74: /* onconf ::= ON CONFLICT resolvetype */
{yymsp[-2].minor.yy502 = yymsp[0].minor.yy502;}
break;
case 77: /* resolvetype ::= IGNORE */
{yymsp[0].minor.yy502 = OE_Ignore;}
break;
case 78: /* resolvetype ::= REPLACE */
case 174: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==174);
{yymsp[0].minor.yy502 = OE_Replace;}
break;
case 79: /* cmd ::= DROP TABLE ifexists fullname */
{
sqlite3DropTable(pParse, yymsp[0].minor.yy563, 0, yymsp[-1].minor.yy502);
}
break;
case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
{
sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy402, yymsp[0].minor.yy637, yymsp[-7].minor.yy502, yymsp[-5].minor.yy502);
}
break;
case 83: /* cmd ::= DROP VIEW ifexists fullname */
{
sqlite3DropTable(pParse, yymsp[0].minor.yy563, 1, yymsp[-1].minor.yy502);
}
break;
case 84: /* cmd ::= select */
{
SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0};
if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0
|| sqlite3ReadSchema(pParse)==SQLITE_OK
){
sqlite3Select(pParse, yymsp[0].minor.yy637, &dest);
}
sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy637);
}
break;
case 85: /* select ::= WITH wqlist selectnowith */
{yymsp[-2].minor.yy637 = attachWithToSelect(pParse,yymsp[0].minor.yy637,yymsp[-1].minor.yy125);}
break;
case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */
{yymsp[-3].minor.yy637 = attachWithToSelect(pParse,yymsp[0].minor.yy637,yymsp[-1].minor.yy125);}
break;
case 87: /* select ::= selectnowith */
{
Select *p = yymsp[0].minor.yy637;
if( p ){
parserDoubleLinkSelect(pParse, p);
}
}
break;
case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */
{
Select *pRhs = yymsp[0].minor.yy637;
Select *pLhs = yymsp[-2].minor.yy637;
if( pRhs && pRhs->pPrior ){
SrcList *pFrom;
Token x;
x.n = 0;
parserDoubleLinkSelect(pParse, pRhs);
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0);
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0);
}
if( pRhs ){
pRhs->op = (u8)yymsp[-1].minor.yy502;
pRhs->pPrior = pLhs;
if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
pRhs->selFlags &= ~SF_MultiValue;
if( yymsp[-1].minor.yy502!=TK_ALL ) pParse->hasCompound = 1;
}else{
sqlite3SelectDelete(pParse->db, pLhs);
}
yymsp[-2].minor.yy637 = pRhs;
}
break;
case 89: /* multiselect_op ::= UNION */
case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91);
{yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-OP*/}
break;
case 90: /* multiselect_op ::= UNION ALL */
{yymsp[-1].minor.yy502 = TK_ALL;}
break;
case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
yymsp[-8].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy402,yymsp[-5].minor.yy563,yymsp[-4].minor.yy590,yymsp[-3].minor.yy402,yymsp[-2].minor.yy590,yymsp[-1].minor.yy402,yymsp[-7].minor.yy502,yymsp[0].minor.yy590);
}
break;
case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
{
yymsp[-9].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy402,yymsp[-6].minor.yy563,yymsp[-5].minor.yy590,yymsp[-4].minor.yy402,yymsp[-3].minor.yy590,yymsp[-1].minor.yy402,yymsp[-8].minor.yy502,yymsp[0].minor.yy590);
if( yymsp[-9].minor.yy637 ){
yymsp[-9].minor.yy637->pWinDefn = yymsp[-2].minor.yy483;
}else{
sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy483);
}
}
break;
case 94: /* values ::= VALUES LP nexprlist RP */
{
yymsp[-3].minor.yy637 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy402,0,0,0,0,0,SF_Values,0);
}
break;
case 95: /* oneselect ::= mvalues */
{
sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy637);
}
break;
case 96: /* mvalues ::= values COMMA LP nexprlist RP */
case 97: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==97);
{
yymsp[-4].minor.yy637 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy637, yymsp[-1].minor.yy402);
}
break;
case 98: /* distinct ::= DISTINCT */
{yymsp[0].minor.yy502 = SF_Distinct;}
break;
case 99: /* distinct ::= ALL */
{yymsp[0].minor.yy502 = SF_All;}
break;
case 101: /* sclp ::= */
case 134: /* orderby_opt ::= */ yytestcase(yyruleno==134);
case 144: /* groupby_opt ::= */ yytestcase(yyruleno==144);
case 234: /* exprlist ::= */ yytestcase(yyruleno==234);
case 237: /* paren_exprlist ::= */ yytestcase(yyruleno==237);
case 242: /* eidlist_opt ::= */ yytestcase(yyruleno==242);
{yymsp[1].minor.yy402 = 0;}
break;
case 102: /* selcollist ::= sclp scanpt expr scanpt as */
{
yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy402, yymsp[-2].minor.yy590);
if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy402, &yymsp[0].minor.yy0, 1);
sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy402,yymsp[-3].minor.yy342,yymsp[-1].minor.yy342);
}
break;
case 103: /* selcollist ::= sclp scanpt STAR */
{
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
sqlite3ExprSetErrorOffset(p, (int)(yymsp[0].minor.yy0.z - pParse->zTail));
yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy402, p);
}
break;
case 104: /* selcollist ::= sclp scanpt nm DOT STAR */
{
Expr *pRight, *pLeft, *pDot;
pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
sqlite3ExprSetErrorOffset(pRight, (int)(yymsp[0].minor.yy0.z - pParse->zTail));
pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0);
pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, pDot);
}
break;
case 105: /* as ::= AS nm */
case 117: /* dbnm ::= DOT nm */ yytestcase(yyruleno==117);
case 258: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==258);
case 259: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==259);
{yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;}
break;
case 107: /* from ::= */
case 110: /* stl_prefix ::= */ yytestcase(yyruleno==110);
{yymsp[1].minor.yy563 = 0;}
break;
case 108: /* from ::= FROM seltablist */
{
yymsp[-1].minor.yy563 = yymsp[0].minor.yy563;
sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy563);
}
break;
case 109: /* stl_prefix ::= seltablist joinop */
{
if( ALWAYS(yymsp[-1].minor.yy563 && yymsp[-1].minor.yy563->nSrc>0) ) yymsp[-1].minor.yy563->a[yymsp[-1].minor.yy563->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy502;
}
break;
case 111: /* seltablist ::= stl_prefix nm dbnm as on_using */
{
yymsp[-4].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy563,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421);
}
break;
case 112: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
{
yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy421);
sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy563, &yymsp[-1].minor.yy0);
}
break;
case 113: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
{
yymsp[-7].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy563,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421);
sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy563, yymsp[-3].minor.yy402);
}
break;
case 114: /* seltablist ::= stl_prefix LP select RP as on_using */
{
yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy637,&yymsp[0].minor.yy421);
}
break;
case 115: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
{
if( yymsp[-5].minor.yy563==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy421.pOn==0 && yymsp[0].minor.yy421.pUsing==0 ){
yymsp[-5].minor.yy563 = yymsp[-3].minor.yy563;
}else if( ALWAYS(yymsp[-3].minor.yy563!=0) && yymsp[-3].minor.yy563->nSrc==1 ){
yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy421);
if( yymsp[-5].minor.yy563 ){
SrcItem *pNew = &yymsp[-5].minor.yy563->a[yymsp[-5].minor.yy563->nSrc-1];
SrcItem *pOld = yymsp[-3].minor.yy563->a;
assert( pOld->fg.fixedSchema==0 );
pNew->zName = pOld->zName;
assert( pOld->fg.fixedSchema==0 );
if( pOld->fg.isSubquery ){
pNew->fg.isSubquery = 1;
pNew->u4.pSubq = pOld->u4.pSubq;
pOld->u4.pSubq = 0;
|
| ︙ | ︙ | |||
178051 178052 178053 178054 178055 178056 178057 |
pNew->u1.pFuncArg = pOld->u1.pFuncArg;
pOld->u1.pFuncArg = 0;
pOld->fg.isTabFunc = 0;
pNew->fg.isTabFunc = 1;
}
pOld->zName = 0;
}
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 178439 178440 178441 178442 178443 178444 178445 178446 178447 178448 178449 178450 178451 178452 178453 178454 178455 178456 178457 178458 178459 178460 178461 178462 178463 178464 178465 178466 178467 178468 178469 178470 178471 178472 178473 178474 178475 178476 178477 178478 178479 178480 178481 178482 178483 178484 178485 178486 178487 178488 178489 178490 178491 178492 178493 178494 178495 178496 178497 178498 178499 178500 178501 178502 178503 178504 178505 178506 178507 178508 178509 178510 178511 178512 178513 178514 178515 178516 178517 178518 178519 178520 178521 178522 178523 178524 178525 178526 178527 178528 178529 178530 178531 178532 178533 178534 178535 178536 178537 178538 178539 178540 178541 178542 178543 178544 178545 178546 178547 178548 178549 178550 178551 178552 178553 178554 178555 178556 178557 178558 178559 178560 178561 178562 178563 178564 178565 178566 178567 178568 178569 178570 178571 178572 178573 178574 178575 178576 178577 178578 178579 178580 178581 178582 178583 178584 178585 178586 178587 178588 178589 178590 178591 178592 178593 178594 178595 178596 178597 178598 178599 178600 178601 178602 178603 178604 178605 178606 178607 178608 178609 178610 178611 178612 178613 178614 178615 178616 178617 178618 178619 178620 178621 178622 178623 178624 178625 178626 178627 178628 178629 178630 178631 178632 178633 178634 178635 178636 178637 178638 178639 178640 178641 178642 178643 178644 178645 178646 178647 178648 178649 178650 178651 178652 178653 178654 178655 178656 178657 178658 178659 178660 178661 178662 178663 178664 178665 178666 178667 178668 178669 178670 178671 178672 178673 178674 178675 178676 178677 178678 178679 178680 178681 178682 178683 178684 178685 178686 178687 178688 178689 178690 178691 178692 178693 178694 178695 178696 178697 178698 178699 178700 178701 178702 178703 178704 178705 178706 178707 178708 178709 178710 178711 178712 178713 178714 178715 178716 178717 178718 178719 178720 178721 178722 178723 178724 178725 178726 178727 178728 178729 178730 178731 178732 178733 178734 178735 178736 178737 178738 178739 178740 178741 178742 178743 178744 178745 178746 178747 178748 178749 178750 178751 178752 178753 178754 178755 178756 178757 178758 178759 178760 178761 178762 178763 178764 178765 178766 178767 178768 178769 178770 178771 178772 178773 178774 178775 178776 178777 178778 178779 178780 178781 178782 178783 178784 178785 178786 178787 178788 178789 178790 178791 178792 178793 178794 178795 178796 178797 178798 178799 178800 178801 178802 178803 178804 178805 178806 178807 178808 178809 178810 178811 178812 178813 178814 178815 178816 178817 178818 178819 178820 178821 178822 178823 178824 178825 178826 178827 178828 178829 178830 178831 178832 178833 178834 178835 178836 178837 178838 178839 178840 178841 178842 178843 178844 178845 178846 178847 178848 178849 178850 178851 178852 178853 178854 178855 178856 178857 178858 178859 178860 178861 178862 178863 178864 178865 178866 178867 178868 178869 178870 178871 178872 178873 178874 178875 178876 178877 178878 178879 178880 178881 178882 178883 178884 178885 178886 178887 178888 178889 178890 178891 178892 178893 178894 178895 178896 178897 178898 178899 178900 178901 178902 178903 178904 178905 178906 178907 178908 178909 178910 178911 178912 178913 178914 178915 178916 178917 178918 178919 178920 178921 178922 178923 178924 178925 178926 178927 178928 178929 178930 178931 178932 178933 178934 178935 178936 178937 178938 178939 178940 178941 178942 178943 178944 178945 178946 178947 178948 178949 178950 178951 178952 178953 178954 178955 178956 178957 178958 178959 178960 178961 178962 178963 178964 178965 178966 178967 178968 178969 178970 178971 178972 178973 178974 178975 178976 178977 178978 178979 178980 178981 178982 178983 178984 178985 178986 178987 178988 178989 178990 178991 178992 178993 178994 178995 178996 178997 178998 178999 179000 179001 179002 179003 179004 179005 179006 179007 179008 179009 179010 179011 179012 179013 179014 179015 179016 179017 179018 179019 179020 179021 179022 179023 179024 179025 179026 179027 179028 179029 179030 179031 179032 179033 179034 179035 179036 179037 179038 179039 179040 179041 179042 179043 179044 179045 179046 179047 179048 179049 179050 179051 179052 179053 179054 179055 179056 179057 179058 179059 179060 179061 179062 179063 179064 179065 179066 179067 179068 179069 |
pNew->u1.pFuncArg = pOld->u1.pFuncArg;
pOld->u1.pFuncArg = 0;
pOld->fg.isTabFunc = 0;
pNew->fg.isTabFunc = 1;
}
pOld->zName = 0;
}
sqlite3SrcListDelete(pParse->db, yymsp[-3].minor.yy563);
}else{
Select *pSubquery;
sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy563);
pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy563,0,0,0,0,SF_NestedFrom,0);
yymsp[-5].minor.yy563 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy563,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy421);
}
}
break;
case 116: /* dbnm ::= */
case 131: /* indexed_opt ::= */ yytestcase(yyruleno==131);
{yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;}
break;
case 118: /* fullname ::= nm */
{
yylhsminor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
if( IN_RENAME_OBJECT && yylhsminor.yy563 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy563->a[0].zName, &yymsp[0].minor.yy0);
}
yymsp[0].minor.yy563 = yylhsminor.yy563;
break;
case 119: /* fullname ::= nm DOT nm */
{
yylhsminor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
if( IN_RENAME_OBJECT && yylhsminor.yy563 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy563->a[0].zName, &yymsp[0].minor.yy0);
}
yymsp[-2].minor.yy563 = yylhsminor.yy563;
break;
case 120: /* xfullname ::= nm */
{yymsp[0].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
break;
case 121: /* xfullname ::= nm DOT nm */
{yymsp[-2].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
case 122: /* xfullname ::= nm DOT nm AS nm */
{
yymsp[-4].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
if( yymsp[-4].minor.yy563 ) yymsp[-4].minor.yy563->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
case 123: /* xfullname ::= nm AS nm */
{
yymsp[-2].minor.yy563 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
if( yymsp[-2].minor.yy563 ) yymsp[-2].minor.yy563->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
break;
case 124: /* joinop ::= COMMA|JOIN */
{ yymsp[0].minor.yy502 = JT_INNER; }
break;
case 125: /* joinop ::= JOIN_KW JOIN */
{yymsp[-1].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/}
break;
case 126: /* joinop ::= JOIN_KW nm JOIN */
{yymsp[-2].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/}
break;
case 127: /* joinop ::= JOIN_KW nm nm JOIN */
{yymsp[-3].minor.yy502 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/}
break;
case 128: /* on_using ::= ON expr */
{yymsp[-1].minor.yy421.pOn = yymsp[0].minor.yy590; yymsp[-1].minor.yy421.pUsing = 0;}
break;
case 129: /* on_using ::= USING LP idlist RP */
{yymsp[-3].minor.yy421.pOn = 0; yymsp[-3].minor.yy421.pUsing = yymsp[-1].minor.yy204;}
break;
case 130: /* on_using ::= */
{yymsp[1].minor.yy421.pOn = 0; yymsp[1].minor.yy421.pUsing = 0;}
break;
case 132: /* indexed_by ::= INDEXED BY nm */
{yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;}
break;
case 133: /* indexed_by ::= NOT INDEXED */
{yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;}
break;
case 135: /* orderby_opt ::= ORDER BY sortlist */
case 145: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==145);
{yymsp[-2].minor.yy402 = yymsp[0].minor.yy402;}
break;
case 136: /* sortlist ::= sortlist COMMA expr sortorder nulls */
{
yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402,yymsp[-2].minor.yy590);
sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy402,yymsp[-1].minor.yy502,yymsp[0].minor.yy502);
}
break;
case 137: /* sortlist ::= expr sortorder nulls */
{
yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy590); /*A-overwrites-Y*/
sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy402,yymsp[-1].minor.yy502,yymsp[0].minor.yy502);
}
break;
case 138: /* sortorder ::= ASC */
{yymsp[0].minor.yy502 = SQLITE_SO_ASC;}
break;
case 139: /* sortorder ::= DESC */
{yymsp[0].minor.yy502 = SQLITE_SO_DESC;}
break;
case 140: /* sortorder ::= */
case 143: /* nulls ::= */ yytestcase(yyruleno==143);
{yymsp[1].minor.yy502 = SQLITE_SO_UNDEFINED;}
break;
case 141: /* nulls ::= NULLS FIRST */
{yymsp[-1].minor.yy502 = SQLITE_SO_ASC;}
break;
case 142: /* nulls ::= NULLS LAST */
{yymsp[-1].minor.yy502 = SQLITE_SO_DESC;}
break;
case 146: /* having_opt ::= */
case 148: /* limit_opt ::= */ yytestcase(yyruleno==148);
case 153: /* where_opt ::= */ yytestcase(yyruleno==153);
case 155: /* where_opt_ret ::= */ yytestcase(yyruleno==155);
case 232: /* case_else ::= */ yytestcase(yyruleno==232);
case 233: /* case_operand ::= */ yytestcase(yyruleno==233);
case 252: /* vinto ::= */ yytestcase(yyruleno==252);
{yymsp[1].minor.yy590 = 0;}
break;
case 147: /* having_opt ::= HAVING expr */
case 154: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==154);
case 156: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==156);
case 231: /* case_else ::= ELSE expr */ yytestcase(yyruleno==231);
case 251: /* vinto ::= INTO expr */ yytestcase(yyruleno==251);
{yymsp[-1].minor.yy590 = yymsp[0].minor.yy590;}
break;
case 149: /* limit_opt ::= LIMIT expr */
{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy590,0);}
break;
case 150: /* limit_opt ::= LIMIT expr OFFSET expr */
{yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);}
break;
case 151: /* limit_opt ::= LIMIT expr COMMA expr */
{yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy590,yymsp[-2].minor.yy590);}
break;
case 152: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
{
sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy563, &yymsp[-1].minor.yy0);
sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy563,yymsp[0].minor.yy590,0,0);
}
break;
case 157: /* where_opt_ret ::= RETURNING selcollist */
{sqlite3AddReturning(pParse,yymsp[0].minor.yy402); yymsp[-1].minor.yy590 = 0;}
break;
case 158: /* where_opt_ret ::= WHERE expr RETURNING selcollist */
{sqlite3AddReturning(pParse,yymsp[0].minor.yy402); yymsp[-3].minor.yy590 = yymsp[-2].minor.yy590;}
break;
case 159: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
{
sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy563, &yymsp[-4].minor.yy0);
sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy402,"set list");
if( yymsp[-1].minor.yy563 ){
SrcList *pFromClause = yymsp[-1].minor.yy563;
if( pFromClause->nSrc>1 ){
Select *pSubquery;
Token as;
pSubquery = sqlite3SelectNew(pParse,0,pFromClause,0,0,0,0,SF_NestedFrom,0);
as.n = 0;
as.z = 0;
pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
}
yymsp[-5].minor.yy563 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy563, pFromClause);
}
sqlite3Update(pParse,yymsp[-5].minor.yy563,yymsp[-2].minor.yy402,yymsp[0].minor.yy590,yymsp[-6].minor.yy502,0,0,0);
}
break;
case 160: /* setlist ::= setlist COMMA nm EQ expr */
{
yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy402, yymsp[0].minor.yy590);
sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy402, &yymsp[-2].minor.yy0, 1);
}
break;
case 161: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
{
yymsp[-6].minor.yy402 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy402, yymsp[-3].minor.yy204, yymsp[0].minor.yy590);
}
break;
case 162: /* setlist ::= nm EQ expr */
{
yylhsminor.yy402 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy590);
sqlite3ExprListSetName(pParse, yylhsminor.yy402, &yymsp[-2].minor.yy0, 1);
}
yymsp[-2].minor.yy402 = yylhsminor.yy402;
break;
case 163: /* setlist ::= LP idlist RP EQ expr */
{
yymsp[-4].minor.yy402 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy204, yymsp[0].minor.yy590);
}
break;
case 164: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
{
sqlite3Insert(pParse, yymsp[-3].minor.yy563, yymsp[-1].minor.yy637, yymsp[-2].minor.yy204, yymsp[-5].minor.yy502, yymsp[0].minor.yy403);
}
break;
case 165: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
{
sqlite3Insert(pParse, yymsp[-4].minor.yy563, 0, yymsp[-3].minor.yy204, yymsp[-6].minor.yy502, 0);
}
break;
case 166: /* upsert ::= */
{ yymsp[1].minor.yy403 = 0; }
break;
case 167: /* upsert ::= RETURNING selcollist */
{ yymsp[-1].minor.yy403 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy402); }
break;
case 168: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
{ yymsp[-11].minor.yy403 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy402,yymsp[-6].minor.yy590,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590,yymsp[0].minor.yy403);}
break;
case 169: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
{ yymsp[-8].minor.yy403 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy402,yymsp[-3].minor.yy590,0,0,yymsp[0].minor.yy403); }
break;
case 170: /* upsert ::= ON CONFLICT DO NOTHING returning */
{ yymsp[-4].minor.yy403 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); }
break;
case 171: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
{ yymsp[-7].minor.yy403 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590,0);}
break;
case 172: /* returning ::= RETURNING selcollist */
{sqlite3AddReturning(pParse,yymsp[0].minor.yy402);}
break;
case 175: /* idlist_opt ::= */
{yymsp[1].minor.yy204 = 0;}
break;
case 176: /* idlist_opt ::= LP idlist RP */
{yymsp[-2].minor.yy204 = yymsp[-1].minor.yy204;}
break;
case 177: /* idlist ::= idlist COMMA nm */
{yymsp[-2].minor.yy204 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy204,&yymsp[0].minor.yy0);}
break;
case 178: /* idlist ::= nm */
{yymsp[0].minor.yy204 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
break;
case 179: /* expr ::= LP expr RP */
{yymsp[-2].minor.yy590 = yymsp[-1].minor.yy590;}
break;
case 180: /* expr ::= ID|INDEXED|JOIN_KW */
{yymsp[0].minor.yy590=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
case 181: /* expr ::= nm DOT nm */
{
Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
yylhsminor.yy590 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
yymsp[-2].minor.yy590 = yylhsminor.yy590;
break;
case 182: /* expr ::= nm DOT nm DOT nm */
{
Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0);
Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0);
Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenRemap(pParse, 0, temp1);
}
yylhsminor.yy590 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
yymsp[-4].minor.yy590 = yylhsminor.yy590;
break;
case 183: /* term ::= NULL|FLOAT|BLOB */
case 184: /* term ::= STRING */ yytestcase(yyruleno==184);
{yymsp[0].minor.yy590=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
break;
case 185: /* term ::= INTEGER */
{
yylhsminor.yy590 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
if( yylhsminor.yy590 ) yylhsminor.yy590->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
}
yymsp[0].minor.yy590 = yylhsminor.yy590;
break;
case 186: /* expr ::= VARIABLE */
{
if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){
u32 n = yymsp[0].minor.yy0.n;
yymsp[0].minor.yy590 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy590, n);
}else{
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
** in the virtual machine. #N is the N-th register. */
Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/
assert( t.n>=2 );
if( pParse->nested==0 ){
parserSyntaxError(pParse, &t);
yymsp[0].minor.yy590 = 0;
}else{
yymsp[0].minor.yy590 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
if( yymsp[0].minor.yy590 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy590->iTable);
}
}
}
break;
case 187: /* expr ::= expr COLLATE ID|STRING */
{
yymsp[-2].minor.yy590 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy590, &yymsp[0].minor.yy0, 1);
}
break;
case 188: /* expr ::= CAST LP expr AS typetoken RP */
{
yymsp[-5].minor.yy590 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy590, yymsp[-3].minor.yy590, 0);
}
break;
case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
{
yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy402, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy502);
}
yymsp[-4].minor.yy590 = yylhsminor.yy590;
break;
case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
{
yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy402, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy502);
sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy590, yymsp[-1].minor.yy402);
}
yymsp[-7].minor.yy590 = yylhsminor.yy590;
break;
case 191: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
{
yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
}
yymsp[-3].minor.yy590 = yylhsminor.yy590;
break;
case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
{
yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy402, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy502);
sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483);
}
yymsp[-5].minor.yy590 = yylhsminor.yy590;
break;
case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
{
yylhsminor.yy590 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy402, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy502);
sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483);
sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy590, yymsp[-2].minor.yy402);
}
yymsp[-8].minor.yy590 = yylhsminor.yy590;
break;
case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
{
yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
sqlite3WindowAttach(pParse, yylhsminor.yy590, yymsp[0].minor.yy483);
}
yymsp[-4].minor.yy590 = yylhsminor.yy590;
break;
case 195: /* term ::= CTIME_KW */
{
yylhsminor.yy590 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
}
yymsp[0].minor.yy590 = yylhsminor.yy590;
break;
case 196: /* expr ::= LP nexprlist COMMA expr RP */
{
ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy402, yymsp[-1].minor.yy590);
yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
if( yymsp[-4].minor.yy590 ){
yymsp[-4].minor.yy590->x.pList = pList;
if( ALWAYS(pList->nExpr) ){
yymsp[-4].minor.yy590->flags |= pList->a[0].pExpr->flags & EP_Propagate;
}
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
}
break;
case 197: /* expr ::= expr AND expr */
{yymsp[-2].minor.yy590=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);}
break;
case 198: /* expr ::= expr OR expr */
case 199: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==199);
case 200: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==200);
case 201: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==201);
case 202: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==202);
case 203: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==203);
case 204: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==204);
{yymsp[-2].minor.yy590=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);}
break;
case 205: /* likeop ::= NOT LIKE_KW|MATCH */
{yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/}
break;
case 206: /* expr ::= expr likeop expr */
{
ExprList *pList;
int bNot = yymsp[-1].minor.yy0.n & 0x80000000;
yymsp[-1].minor.yy0.n &= 0x7fffffff;
pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy590);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy590);
yymsp[-2].minor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
if( bNot ) yymsp[-2].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy590, 0);
if( yymsp[-2].minor.yy590 ) yymsp[-2].minor.yy590->flags |= EP_InfixFunc;
}
break;
case 207: /* expr ::= expr likeop expr ESCAPE expr */
{
ExprList *pList;
int bNot = yymsp[-3].minor.yy0.n & 0x80000000;
yymsp[-3].minor.yy0.n &= 0x7fffffff;
pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy590);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy590);
yymsp[-4].minor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
if( bNot ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0);
if( yymsp[-4].minor.yy590 ) yymsp[-4].minor.yy590->flags |= EP_InfixFunc;
}
break;
case 208: /* expr ::= expr ISNULL|NOTNULL */
{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy590,0);}
break;
case 209: /* expr ::= expr NOT NULL */
{yymsp[-2].minor.yy590 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy590,0);}
break;
case 210: /* expr ::= expr IS expr */
{
yymsp[-2].minor.yy590 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy590,yymsp[0].minor.yy590);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-2].minor.yy590, TK_ISNULL);
}
break;
case 211: /* expr ::= expr IS NOT expr */
{
yymsp[-3].minor.yy590 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy590,yymsp[0].minor.yy590);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-3].minor.yy590, TK_NOTNULL);
}
break;
case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */
{
yymsp[-5].minor.yy590 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy590,yymsp[0].minor.yy590);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-5].minor.yy590, TK_ISNULL);
}
break;
case 213: /* expr ::= expr IS DISTINCT FROM expr */
{
yymsp[-4].minor.yy590 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy590,yymsp[0].minor.yy590);
binaryToUnaryIfNull(pParse, yymsp[0].minor.yy590, yymsp[-4].minor.yy590, TK_NOTNULL);
}
break;
case 214: /* expr ::= NOT expr */
case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215);
{yymsp[-1].minor.yy590 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy590, 0);/*A-overwrites-B*/}
break;
case 216: /* expr ::= PLUS|MINUS expr */
{
Expr *p = yymsp[0].minor.yy590;
u8 op = yymsp[-1].major + (TK_UPLUS-TK_PLUS);
assert( TK_UPLUS>TK_PLUS );
assert( TK_UMINUS == TK_MINUS + (TK_UPLUS - TK_PLUS) );
if( p && p->op==TK_UPLUS ){
p->op = op;
yymsp[-1].minor.yy590 = p;
}else{
yymsp[-1].minor.yy590 = sqlite3PExpr(pParse, op, p, 0);
/*A-overwrites-B*/
}
}
break;
case 217: /* expr ::= expr PTR expr */
{
ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy590);
pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy590);
yylhsminor.yy590 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
}
yymsp[-2].minor.yy590 = yylhsminor.yy590;
break;
case 218: /* between_op ::= BETWEEN */
case 221: /* in_op ::= IN */ yytestcase(yyruleno==221);
{yymsp[0].minor.yy502 = 0;}
break;
case 220: /* expr ::= expr between_op expr AND expr */
{
ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590);
pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy590);
yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy590, 0);
if( yymsp[-4].minor.yy590 ){
yymsp[-4].minor.yy590->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0);
}
break;
case 223: /* expr ::= expr in_op LP exprlist RP */
{
if( yymsp[-1].minor.yy402==0 ){
/* Expressions of the form
**
** expr1 IN ()
** expr1 NOT IN ()
**
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy590);
yymsp[-4].minor.yy590 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy502 ? "true" : "false");
if( yymsp[-4].minor.yy590 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy590);
}else{
Expr *pRHS = yymsp[-1].minor.yy402->a[0].pExpr;
if( yymsp[-1].minor.yy402->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy590->op!=TK_VECTOR ){
yymsp[-1].minor.yy402->a[0].pExpr = 0;
sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402);
pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy590, pRHS);
}else if( yymsp[-1].minor.yy402->nExpr==1 && pRHS->op==TK_SELECT ){
yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0);
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pRHS->x.pSelect);
pRHS->x.pSelect = 0;
sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402);
}else{
yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0);
if( yymsp[-4].minor.yy590==0 ){
sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy402);
}else if( yymsp[-4].minor.yy590->pLeft->op==TK_VECTOR ){
int nExpr = yymsp[-4].minor.yy590->pLeft->x.pList->nExpr;
Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy402);
if( pSelectRHS ){
parserDoubleLinkSelect(pParse, pSelectRHS);
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pSelectRHS);
}
}else{
yymsp[-4].minor.yy590->x.pList = yymsp[-1].minor.yy402;
sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy590);
}
}
if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0);
}
}
break;
case 224: /* expr ::= LP select RP */
{
yymsp[-2].minor.yy590 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy590, yymsp[-1].minor.yy637);
}
break;
case 225: /* expr ::= expr in_op LP select RP */
{
yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0);
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, yymsp[-1].minor.yy637);
if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0);
}
break;
case 226: /* expr ::= expr in_op nm dbnm paren_exprlist */
{
SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
if( yymsp[0].minor.yy402 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy402);
yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy590, 0);
sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy590, pSelect);
if( yymsp[-3].minor.yy502 ) yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy590, 0);
}
break;
case 227: /* expr ::= EXISTS LP select RP */
{
Expr *p;
p = yymsp[-3].minor.yy590 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy637);
}
break;
case 228: /* expr ::= CASE case_operand case_exprlist case_else END */
{
yymsp[-4].minor.yy590 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy590, 0);
if( yymsp[-4].minor.yy590 ){
yymsp[-4].minor.yy590->x.pList = yymsp[-1].minor.yy590 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy402,yymsp[-1].minor.yy590) : yymsp[-2].minor.yy402;
sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy590);
}else{
sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy402);
sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy590);
}
}
break;
case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, yymsp[-2].minor.yy590);
yymsp[-4].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy402, yymsp[0].minor.yy590);
}
break;
case 230: /* case_exprlist ::= WHEN expr THEN expr */
{
yymsp[-3].minor.yy402 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy590);
yymsp[-3].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy402, yymsp[0].minor.yy590);
}
break;
case 235: /* nexprlist ::= nexprlist COMMA expr */
{yymsp[-2].minor.yy402 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy402,yymsp[0].minor.yy590);}
break;
case 236: /* nexprlist ::= expr */
{yymsp[0].minor.yy402 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy590); /*A-overwrites-Y*/}
break;
case 238: /* paren_exprlist ::= LP exprlist RP */
case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243);
{yymsp[-2].minor.yy402 = yymsp[-1].minor.yy402;}
break;
case 239: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
{
sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy402, yymsp[-10].minor.yy502,
&yymsp[-11].minor.yy0, yymsp[0].minor.yy590, SQLITE_SO_ASC, yymsp[-8].minor.yy502, SQLITE_IDXTYPE_APPDEF);
if( IN_RENAME_OBJECT && pParse->pNewIndex ){
sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0);
}
}
break;
case 240: /* uniqueflag ::= UNIQUE */
case 282: /* raisetype ::= ABORT */ yytestcase(yyruleno==282);
{yymsp[0].minor.yy502 = OE_Abort;}
break;
case 241: /* uniqueflag ::= */
{yymsp[1].minor.yy502 = OE_None;}
break;
case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */
{
yymsp[-4].minor.yy402 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy402, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy502, yymsp[0].minor.yy502);
}
break;
case 245: /* eidlist ::= nm collate sortorder */
{
yymsp[-2].minor.yy402 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy502, yymsp[0].minor.yy502); /*A-overwrites-Y*/
}
break;
case 248: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite3DropIndex(pParse, yymsp[0].minor.yy563, yymsp[-1].minor.yy502);}
break;
case 249: /* cmd ::= VACUUM vinto */
{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy590);}
break;
case 250: /* cmd ::= VACUUM nm vinto */
{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy590);}
break;
case 253: /* cmd ::= PRAGMA nm dbnm */
{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
break;
case 254: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
break;
|
| ︙ | ︙ | |||
178689 178690 178691 178692 178693 178694 178695 |
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
case 260: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
| | | > > > > | | | | | | | | | | | | | 179077 179078 179079 179080 179081 179082 179083 179084 179085 179086 179087 179088 179089 179090 179091 179092 179093 179094 179095 179096 179097 179098 179099 179100 179101 179102 179103 179104 179105 179106 179107 179108 179109 179110 179111 179112 179113 179114 179115 179116 179117 179118 179119 179120 179121 179122 179123 179124 179125 179126 179127 179128 179129 179130 179131 179132 179133 179134 179135 179136 179137 179138 |
{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);}
break;
case 260: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
{
Token all;
all.z = yymsp[-3].minor.yy0.z;
all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy319, &all);
}
break;
case 261: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
{
sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy502, yymsp[-4].minor.yy28.a, yymsp[-4].minor.yy28.b, yymsp[-2].minor.yy563, yymsp[0].minor.yy590, yymsp[-10].minor.yy502, yymsp[-8].minor.yy502);
yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/
#ifdef SQLITE_DEBUG
assert( pParse->isCreate ); /* Set by createkw reduce action */
pParse->isCreate = 0; /* But, should not be set for CREATE TRIGGER */
#endif
}
break;
case 262: /* trigger_time ::= BEFORE|AFTER */
{ yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-X*/ }
break;
case 263: /* trigger_time ::= INSTEAD OF */
{ yymsp[-1].minor.yy502 = TK_INSTEAD;}
break;
case 264: /* trigger_time ::= */
{ yymsp[1].minor.yy502 = TK_BEFORE; }
break;
case 265: /* trigger_event ::= DELETE|INSERT */
case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266);
{yymsp[0].minor.yy28.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy28.b = 0;}
break;
case 267: /* trigger_event ::= UPDATE OF idlist */
{yymsp[-2].minor.yy28.a = TK_UPDATE; yymsp[-2].minor.yy28.b = yymsp[0].minor.yy204;}
break;
case 268: /* when_clause ::= */
case 287: /* key_opt ::= */ yytestcase(yyruleno==287);
{ yymsp[1].minor.yy590 = 0; }
break;
case 269: /* when_clause ::= WHEN expr */
case 288: /* key_opt ::= KEY expr */ yytestcase(yyruleno==288);
{ yymsp[-1].minor.yy590 = yymsp[0].minor.yy590; }
break;
case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
assert( yymsp[-2].minor.yy319!=0 );
yymsp[-2].minor.yy319->pLast->pNext = yymsp[-1].minor.yy319;
yymsp[-2].minor.yy319->pLast = yymsp[-1].minor.yy319;
}
break;
case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
assert( yymsp[-1].minor.yy319!=0 );
yymsp[-1].minor.yy319->pLast = yymsp[-1].minor.yy319;
}
break;
case 272: /* trnm ::= nm DOT nm */
{
yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;
sqlite3ErrorMsg(pParse,
"qualified table names are not allowed on INSERT, UPDATE, and DELETE "
|
| ︙ | ︙ | |||
178758 178759 178760 178761 178762 178763 178764 |
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
case 275: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 179150 179151 179152 179153 179154 179155 179156 179157 179158 179159 179160 179161 179162 179163 179164 179165 179166 179167 179168 179169 179170 179171 179172 179173 179174 179175 179176 179177 179178 179179 179180 179181 179182 179183 179184 179185 179186 179187 179188 179189 179190 179191 179192 179193 179194 179195 179196 179197 179198 179199 179200 179201 179202 179203 179204 179205 179206 179207 179208 179209 179210 179211 179212 179213 179214 179215 179216 179217 179218 179219 179220 179221 179222 179223 179224 179225 179226 179227 179228 179229 179230 179231 179232 179233 179234 179235 179236 179237 179238 179239 179240 179241 179242 179243 179244 179245 179246 179247 179248 179249 179250 179251 179252 179253 179254 179255 179256 179257 179258 179259 179260 179261 179262 179263 179264 179265 179266 179267 179268 179269 179270 179271 179272 179273 179274 179275 179276 179277 179278 179279 179280 179281 179282 179283 179284 179285 179286 179287 179288 179289 179290 179291 179292 179293 179294 179295 179296 179297 179298 179299 179300 179301 179302 179303 179304 179305 179306 179307 179308 179309 179310 179311 179312 179313 179314 179315 179316 179317 179318 179319 179320 179321 179322 179323 179324 179325 179326 179327 179328 179329 179330 179331 179332 179333 179334 179335 179336 179337 179338 179339 179340 179341 179342 179343 179344 179345 179346 179347 179348 179349 179350 179351 179352 179353 179354 179355 179356 179357 179358 179359 179360 179361 179362 179363 179364 179365 179366 179367 179368 179369 179370 179371 179372 179373 179374 179375 179376 179377 179378 179379 179380 179381 179382 179383 179384 179385 179386 179387 179388 179389 179390 179391 179392 179393 179394 179395 179396 179397 179398 179399 179400 179401 179402 179403 179404 179405 179406 179407 179408 179409 179410 179411 179412 179413 179414 179415 179416 179417 179418 179419 179420 179421 179422 179423 179424 179425 179426 179427 179428 179429 179430 179431 179432 179433 179434 179435 179436 179437 179438 179439 179440 179441 179442 179443 179444 179445 179446 179447 179448 179449 179450 179451 179452 |
{
sqlite3ErrorMsg(pParse,
"the NOT INDEXED clause is not allowed on UPDATE or DELETE statements "
"within triggers");
}
break;
case 275: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
{yylhsminor.yy319 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy563, yymsp[-3].minor.yy402, yymsp[-1].minor.yy590, yymsp[-7].minor.yy502, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy342);}
yymsp[-8].minor.yy319 = yylhsminor.yy319;
break;
case 276: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
{
yylhsminor.yy319 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy204,yymsp[-2].minor.yy637,yymsp[-6].minor.yy502,yymsp[-1].minor.yy403,yymsp[-7].minor.yy342,yymsp[0].minor.yy342);/*yylhsminor.yy319-overwrites-yymsp[-6].minor.yy502*/
}
yymsp[-7].minor.yy319 = yylhsminor.yy319;
break;
case 277: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
{yylhsminor.yy319 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy590, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy342);}
yymsp[-5].minor.yy319 = yylhsminor.yy319;
break;
case 278: /* trigger_cmd ::= scanpt select scanpt */
{yylhsminor.yy319 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy637, yymsp[-2].minor.yy342, yymsp[0].minor.yy342); /*yylhsminor.yy319-overwrites-yymsp[-1].minor.yy637*/}
yymsp[-2].minor.yy319 = yylhsminor.yy319;
break;
case 279: /* expr ::= RAISE LP IGNORE RP */
{
yymsp[-3].minor.yy590 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
if( yymsp[-3].minor.yy590 ){
yymsp[-3].minor.yy590->affExpr = OE_Ignore;
}
}
break;
case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */
{
yymsp[-5].minor.yy590 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy590, 0);
if( yymsp[-5].minor.yy590 ) {
yymsp[-5].minor.yy590->affExpr = (char)yymsp[-3].minor.yy502;
}
}
break;
case 281: /* raisetype ::= ROLLBACK */
{yymsp[0].minor.yy502 = OE_Rollback;}
break;
case 283: /* raisetype ::= FAIL */
{yymsp[0].minor.yy502 = OE_Fail;}
break;
case 284: /* cmd ::= DROP TRIGGER ifexists fullname */
{
sqlite3DropTrigger(pParse,yymsp[0].minor.yy563,yymsp[-1].minor.yy502);
}
break;
case 285: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
sqlite3Attach(pParse, yymsp[-3].minor.yy590, yymsp[-1].minor.yy590, yymsp[0].minor.yy590);
}
break;
case 286: /* cmd ::= DETACH database_kw_opt expr */
{
sqlite3Detach(pParse, yymsp[0].minor.yy590);
}
break;
case 289: /* cmd ::= REINDEX */
{sqlite3Reindex(pParse, 0, 0);}
break;
case 290: /* cmd ::= REINDEX nm dbnm */
{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
case 291: /* cmd ::= ANALYZE */
{sqlite3Analyze(pParse, 0, 0);}
break;
case 292: /* cmd ::= ANALYZE nm dbnm */
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy563,&yymsp[0].minor.yy0);
}
break;
case 294: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
{
yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
}
break;
case 295: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
{
sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy563, &yymsp[0].minor.yy0);
}
break;
case 296: /* add_column_fullname ::= fullname */
{
disableLookaside(pParse);
sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy563);
}
break;
case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
{
sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy563, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 298: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
case 299: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
case 300: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy502);
}
break;
case 301: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
case 302: /* vtabargtoken ::= ANY */
case 303: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==303);
case 304: /* lp ::= LP */ yytestcase(yyruleno==304);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
case 305: /* with ::= WITH wqlist */
case 306: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==306);
{ sqlite3WithPush(pParse, yymsp[0].minor.yy125, 1); }
break;
case 307: /* wqas ::= AS */
{yymsp[0].minor.yy444 = M10d_Any;}
break;
case 308: /* wqas ::= AS MATERIALIZED */
{yymsp[-1].minor.yy444 = M10d_Yes;}
break;
case 309: /* wqas ::= AS NOT MATERIALIZED */
{yymsp[-2].minor.yy444 = M10d_No;}
break;
case 310: /* wqitem ::= withnm eidlist_opt wqas LP select RP */
{
yymsp[-5].minor.yy361 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy402, yymsp[-1].minor.yy637, yymsp[-3].minor.yy444); /*A-overwrites-X*/
}
break;
case 311: /* withnm ::= nm */
{pParse->bHasWith = 1;}
break;
case 312: /* wqlist ::= wqitem */
{
yymsp[0].minor.yy125 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy361); /*A-overwrites-X*/
}
break;
case 313: /* wqlist ::= wqlist COMMA wqitem */
{
yymsp[-2].minor.yy125 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy125, yymsp[0].minor.yy361);
}
break;
case 314: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
{
assert( yymsp[0].minor.yy483!=0 );
sqlite3WindowChain(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy483);
yymsp[0].minor.yy483->pNextWin = yymsp[-2].minor.yy483;
yylhsminor.yy483 = yymsp[0].minor.yy483;
}
yymsp[-2].minor.yy483 = yylhsminor.yy483;
break;
case 315: /* windowdefn ::= nm AS LP window RP */
{
if( ALWAYS(yymsp[-1].minor.yy483) ){
yymsp[-1].minor.yy483->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
}
yylhsminor.yy483 = yymsp[-1].minor.yy483;
}
yymsp[-4].minor.yy483 = yylhsminor.yy483;
break;
case 316: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
{
yymsp[-4].minor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, 0);
}
break;
case 317: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
{
yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, &yymsp[-5].minor.yy0);
}
yymsp[-5].minor.yy483 = yylhsminor.yy483;
break;
case 318: /* window ::= ORDER BY sortlist frame_opt */
{
yymsp[-3].minor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, yymsp[-1].minor.yy402, 0);
}
break;
case 319: /* window ::= nm ORDER BY sortlist frame_opt */
{
yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, yymsp[-1].minor.yy402, &yymsp[-4].minor.yy0);
}
yymsp[-4].minor.yy483 = yylhsminor.yy483;
break;
case 320: /* window ::= nm frame_opt */
{
yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, 0, &yymsp[-1].minor.yy0);
}
yymsp[-1].minor.yy483 = yylhsminor.yy483;
break;
case 321: /* frame_opt ::= */
{
yymsp[1].minor.yy483 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
}
break;
case 322: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
{
yylhsminor.yy483 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy502, yymsp[-1].minor.yy205.eType, yymsp[-1].minor.yy205.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy444);
}
yymsp[-2].minor.yy483 = yylhsminor.yy483;
break;
case 323: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
{
yylhsminor.yy483 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy502, yymsp[-3].minor.yy205.eType, yymsp[-3].minor.yy205.pExpr, yymsp[-1].minor.yy205.eType, yymsp[-1].minor.yy205.pExpr, yymsp[0].minor.yy444);
}
yymsp[-5].minor.yy483 = yylhsminor.yy483;
break;
case 325: /* frame_bound_s ::= frame_bound */
case 327: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==327);
{yylhsminor.yy205 = yymsp[0].minor.yy205;}
yymsp[0].minor.yy205 = yylhsminor.yy205;
break;
case 326: /* frame_bound_s ::= UNBOUNDED PRECEDING */
case 328: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==328);
case 330: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==330);
{yylhsminor.yy205.eType = yymsp[-1].major; yylhsminor.yy205.pExpr = 0;}
yymsp[-1].minor.yy205 = yylhsminor.yy205;
break;
case 329: /* frame_bound ::= expr PRECEDING|FOLLOWING */
{yylhsminor.yy205.eType = yymsp[0].major; yylhsminor.yy205.pExpr = yymsp[-1].minor.yy590;}
yymsp[-1].minor.yy205 = yylhsminor.yy205;
break;
case 331: /* frame_exclude_opt ::= */
{yymsp[1].minor.yy444 = 0;}
break;
case 332: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
{yymsp[-1].minor.yy444 = yymsp[0].minor.yy444;}
break;
case 333: /* frame_exclude ::= NO OTHERS */
case 334: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==334);
{yymsp[-1].minor.yy444 = yymsp[-1].major; /*A-overwrites-X*/}
break;
case 335: /* frame_exclude ::= GROUP|TIES */
{yymsp[0].minor.yy444 = yymsp[0].major; /*A-overwrites-X*/}
break;
case 336: /* window_clause ::= WINDOW windowdefn_list */
{ yymsp[-1].minor.yy483 = yymsp[0].minor.yy483; }
break;
case 337: /* filter_over ::= filter_clause over_clause */
{
if( yymsp[0].minor.yy483 ){
yymsp[0].minor.yy483->pFilter = yymsp[-1].minor.yy590;
}else{
sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy590);
}
yylhsminor.yy483 = yymsp[0].minor.yy483;
}
yymsp[-1].minor.yy483 = yylhsminor.yy483;
break;
case 338: /* filter_over ::= over_clause */
{
yylhsminor.yy483 = yymsp[0].minor.yy483;
}
yymsp[0].minor.yy483 = yylhsminor.yy483;
break;
case 339: /* filter_over ::= filter_clause */
{
yylhsminor.yy483 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
if( yylhsminor.yy483 ){
yylhsminor.yy483->eFrmType = TK_FILTER;
yylhsminor.yy483->pFilter = yymsp[0].minor.yy590;
}else{
sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy590);
}
}
yymsp[0].minor.yy483 = yylhsminor.yy483;
break;
case 340: /* over_clause ::= OVER LP window RP */
{
yymsp[-3].minor.yy483 = yymsp[-1].minor.yy483;
assert( yymsp[-3].minor.yy483!=0 );
}
break;
case 341: /* over_clause ::= OVER nm */
{
yymsp[-1].minor.yy483 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
if( yymsp[-1].minor.yy483 ){
yymsp[-1].minor.yy483->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
}
}
break;
case 342: /* filter_clause ::= FILTER LP WHERE expr RP */
{ yymsp[-4].minor.yy590 = yymsp[-1].minor.yy590; }
break;
case 343: /* term ::= QNUMBER */
{
yylhsminor.yy590=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0);
sqlite3DequoteNumber(pParse, yylhsminor.yy590);
}
yymsp[0].minor.yy590 = yylhsminor.yy590;
break;
default:
/* (344) input ::= cmdlist */ yytestcase(yyruleno==344);
/* (345) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==345);
/* (346) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=346);
/* (347) ecmd ::= SEMI */ yytestcase(yyruleno==347);
/* (348) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==348);
|
| ︙ | ︙ | |||
180227 180228 180229 180230 180231 180232 180233 |
for(i=1; sqlite3Isspace(z[i]); i++){}
*tokenType = TK_SPACE;
return i;
}
case CC_MINUS: {
if( z[1]=='-' ){
for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
| | | 180619 180620 180621 180622 180623 180624 180625 180626 180627 180628 180629 180630 180631 180632 180633 |
for(i=1; sqlite3Isspace(z[i]); i++){}
*tokenType = TK_SPACE;
return i;
}
case CC_MINUS: {
if( z[1]=='-' ){
for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
*tokenType = TK_COMMENT;
return i;
}else if( z[1]=='>' ){
*tokenType = TK_PTR;
return 2 + (z[2]=='>');
}
*tokenType = TK_MINUS;
return 1;
|
| ︙ | ︙ | |||
180263 180264 180265 180266 180267 180268 180269 |
case CC_SLASH: {
if( z[1]!='*' || z[2]==0 ){
*tokenType = TK_SLASH;
return 1;
}
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
if( c ) i++;
| | | 180655 180656 180657 180658 180659 180660 180661 180662 180663 180664 180665 180666 180667 180668 180669 |
case CC_SLASH: {
if( z[1]!='*' || z[2]==0 ){
*tokenType = TK_SLASH;
return 1;
}
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
if( c ) i++;
*tokenType = TK_COMMENT;
return i;
}
case CC_PERCENT: {
*tokenType = TK_REM;
return 1;
}
case CC_EQ: {
|
| ︙ | ︙ | |||
180592 180593 180594 180595 180596 180597 180598 |
pParse->nErr++;
break;
}
#ifndef SQLITE_OMIT_WINDOWFUNC
if( tokenType>=TK_WINDOW ){
assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER
|| tokenType==TK_ILLEGAL || tokenType==TK_WINDOW
| | | | 180984 180985 180986 180987 180988 180989 180990 180991 180992 180993 180994 180995 180996 180997 180998 180999 181000 181001 181002 181003 |
pParse->nErr++;
break;
}
#ifndef SQLITE_OMIT_WINDOWFUNC
if( tokenType>=TK_WINDOW ){
assert( tokenType==TK_SPACE || tokenType==TK_OVER || tokenType==TK_FILTER
|| tokenType==TK_ILLEGAL || tokenType==TK_WINDOW
|| tokenType==TK_QNUMBER || tokenType==TK_COMMENT
);
#else
if( tokenType>=TK_SPACE ){
assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL
|| tokenType==TK_QNUMBER || tokenType==TK_COMMENT
);
#endif /* SQLITE_OMIT_WINDOWFUNC */
if( AtomicLoad(&db->u1.isInterrupted) ){
pParse->rc = SQLITE_INTERRUPT;
pParse->nErr++;
break;
}
|
| ︙ | ︙ | |||
180631 180632 180633 180634 180635 180636 180637 180638 180639 180640 180641 180642 180643 180644 |
}else if( tokenType==TK_OVER ){
assert( n==4 );
tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed);
}else if( tokenType==TK_FILTER ){
assert( n==6 );
tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
#endif /* SQLITE_OMIT_WINDOWFUNC */
}else if( tokenType!=TK_QNUMBER ){
Token x;
x.z = zSql;
x.n = n;
sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
break;
}
| > > > | 181023 181024 181025 181026 181027 181028 181029 181030 181031 181032 181033 181034 181035 181036 181037 181038 181039 |
}else if( tokenType==TK_OVER ){
assert( n==4 );
tokenType = analyzeOverKeyword((const u8*)&zSql[4], lastTokenParsed);
}else if( tokenType==TK_FILTER ){
assert( n==6 );
tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed);
#endif /* SQLITE_OMIT_WINDOWFUNC */
}else if( tokenType==TK_COMMENT && (db->flags & SQLITE_Comments)!=0 ){
zSql += n;
continue;
}else if( tokenType!=TK_QNUMBER ){
Token x;
x.z = zSql;
x.n = n;
sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
break;
}
|
| ︙ | ︙ | |||
180737 180738 180739 180740 180741 180742 180743 180744 180745 180746 180747 180748 180749 180750 |
for(i=0; zSql[i] && pStr->accError==0; i+=n){
if( tokenType!=TK_SPACE ){
prevType = tokenType;
}
n = sqlite3GetToken((unsigned char*)zSql+i, &tokenType);
if( NEVER(n<=0) ) break;
switch( tokenType ){
case TK_SPACE: {
break;
}
case TK_NULL: {
if( prevType==TK_IS || prevType==TK_NOT ){
sqlite3_str_append(pStr, " NULL", 5);
break;
| > | 181132 181133 181134 181135 181136 181137 181138 181139 181140 181141 181142 181143 181144 181145 181146 |
for(i=0; zSql[i] && pStr->accError==0; i+=n){
if( tokenType!=TK_SPACE ){
prevType = tokenType;
}
n = sqlite3GetToken((unsigned char*)zSql+i, &tokenType);
if( NEVER(n<=0) ) break;
switch( tokenType ){
case TK_COMMENT:
case TK_SPACE: {
break;
}
case TK_NULL: {
if( prevType==TK_IS || prevType==TK_NOT ){
sqlite3_str_append(pStr, " NULL", 5);
break;
|
| ︙ | ︙ | |||
181978 181979 181980 181981 181982 181983 181984 | /* ** Set up the lookaside buffers for a database connection. ** Return SQLITE_OK on success. ** If lookaside is already active, return SQLITE_BUSY. ** ** The sz parameter is the number of bytes in each lookaside slot. | | | | | | > > > > > | | | | | | > > > | > > | | | | | 182374 182375 182376 182377 182378 182379 182380 182381 182382 182383 182384 182385 182386 182387 182388 182389 182390 182391 182392 182393 182394 182395 182396 182397 182398 182399 182400 182401 182402 182403 182404 182405 182406 182407 182408 182409 182410 182411 182412 182413 182414 182415 182416 182417 182418 182419 182420 182421 182422 182423 182424 182425 182426 182427 182428 182429 182430 182431 182432 182433 182434 182435 182436 182437 182438 182439 182440 182441 182442 182443 |
/*
** Set up the lookaside buffers for a database connection.
** Return SQLITE_OK on success.
** If lookaside is already active, return SQLITE_BUSY.
**
** The sz parameter is the number of bytes in each lookaside slot.
** The cnt parameter is the number of slots. If pBuf is NULL the
** space for the lookaside memory is obtained from sqlite3_malloc()
** or similar. If pBuf is not NULL then it is sz*cnt bytes of memory
** to use for the lookaside memory.
*/
static int setupLookaside(
sqlite3 *db, /* Database connection being configured */
void *pBuf, /* Memory to use for lookaside. May be NULL */
int sz, /* Desired size of each lookaside memory slot */
int cnt /* Number of slots to allocate */
){
#ifndef SQLITE_OMIT_LOOKASIDE
void *pStart; /* Start of the lookaside buffer */
sqlite3_int64 szAlloc; /* Total space set aside for lookaside memory */
int nBig; /* Number of full-size slots */
int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */
if( sqlite3LookasideUsed(db,0)>0 ){
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.
*/
if( db->lookaside.bMalloced ){
sqlite3_free(db->lookaside.pStart);
}
/* The size of a lookaside slot after ROUNDDOWN8 needs to be larger
** than a pointer and small enough to fit in a u16.
*/
sz = ROUNDDOWN8(sz);
if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
if( sz>65528 ) sz = 65528;
/* Count must be at least 1 to be useful, but not so large as to use
** more than 0x7fff0000 total bytes for lookaside. */
if( cnt<1 ) cnt = 0;
if( sz>0 && cnt>(0x7fff0000/sz) ) cnt = 0x7fff0000/sz;
szAlloc = (i64)sz*(i64)cnt;
if( szAlloc==0 ){
sz = 0;
pStart = 0;
}else if( pBuf==0 ){
sqlite3BeginBenignMalloc();
pStart = sqlite3Malloc( szAlloc );
sqlite3EndBenignMalloc();
if( pStart ) szAlloc = sqlite3MallocSize(pStart);
}else{
pStart = pBuf;
}
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE
if( sz>=LOOKASIDE_SMALL*3 ){
nBig = szAlloc/(3*LOOKASIDE_SMALL+sz);
nSm = (szAlloc - (i64)sz*(i64)nBig)/LOOKASIDE_SMALL;
}else if( sz>=LOOKASIDE_SMALL*2 ){
nBig = szAlloc/(LOOKASIDE_SMALL+sz);
nSm = (szAlloc - (i64)sz*(i64)nBig)/LOOKASIDE_SMALL;
}else
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
if( sz>0 ){
nBig = szAlloc/sz;
nSm = 0;
}else{
nBig = nSm = 0;
|
| ︙ | ︙ | |||
182178 182179 182180 182181 182182 182183 182184 |
int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */
rc = setupLookaside(db, pBuf, sz, cnt);
break;
}
default: {
static const struct {
int op; /* The opcode */
| | > > > | 182584 182585 182586 182587 182588 182589 182590 182591 182592 182593 182594 182595 182596 182597 182598 182599 182600 182601 182602 182603 182604 182605 182606 182607 182608 182609 182610 182611 182612 182613 182614 182615 182616 182617 182618 182619 182620 182621 |
int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */
rc = setupLookaside(db, pBuf, sz, cnt);
break;
}
default: {
static const struct {
int op; /* The opcode */
u64 mask; /* Mask of the bit in sqlite3.flags to set/clear */
} aFlagOp[] = {
{ SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys },
{ SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger },
{ SQLITE_DBCONFIG_ENABLE_VIEW, SQLITE_EnableView },
{ SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer },
{ SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension },
{ SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose },
{ SQLITE_DBCONFIG_ENABLE_QPSG, SQLITE_EnableQPSG },
{ SQLITE_DBCONFIG_TRIGGER_EQP, SQLITE_TriggerEQP },
{ SQLITE_DBCONFIG_RESET_DATABASE, SQLITE_ResetDatabase },
{ SQLITE_DBCONFIG_DEFENSIVE, SQLITE_Defensive },
{ SQLITE_DBCONFIG_WRITABLE_SCHEMA, SQLITE_WriteSchema|
SQLITE_NoSchemaError },
{ SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, SQLITE_LegacyAlter },
{ SQLITE_DBCONFIG_DQS_DDL, SQLITE_DqsDDL },
{ SQLITE_DBCONFIG_DQS_DML, SQLITE_DqsDML },
{ SQLITE_DBCONFIG_LEGACY_FILE_FORMAT, SQLITE_LegacyFileFmt },
{ SQLITE_DBCONFIG_TRUSTED_SCHEMA, SQLITE_TrustedSchema },
{ SQLITE_DBCONFIG_STMT_SCANSTATUS, SQLITE_StmtScanStatus },
{ SQLITE_DBCONFIG_REVERSE_SCANORDER, SQLITE_ReverseOrder },
{ SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE, SQLITE_AttachCreate },
{ SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE, SQLITE_AttachWrite },
{ SQLITE_DBCONFIG_ENABLE_COMMENTS, SQLITE_Comments },
};
unsigned int i;
rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
for(i=0; i<ArraySize(aFlagOp); i++){
if( aFlagOp[i].op==op ){
int onoff = va_arg(ap, int);
int *pRes = va_arg(ap, int*);
|
| ︙ | ︙ | |||
184076 184077 184078 184079 184080 184081 184082 | #endif #if SQLITE_MAX_COMPOUND_SELECT<2 # error SQLITE_MAX_COMPOUND_SELECT must be at least 2 #endif #if SQLITE_MAX_VDBE_OP<40 # error SQLITE_MAX_VDBE_OP must be at least 40 #endif | | | | 184485 184486 184487 184488 184489 184490 184491 184492 184493 184494 184495 184496 184497 184498 184499 184500 | #endif #if SQLITE_MAX_COMPOUND_SELECT<2 # error SQLITE_MAX_COMPOUND_SELECT must be at least 2 #endif #if SQLITE_MAX_VDBE_OP<40 # error SQLITE_MAX_VDBE_OP must be at least 40 #endif #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>32767 # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 32767 #endif #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 # error SQLITE_MAX_ATTACHED must be between 0 and 125 #endif #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 #endif |
| ︙ | ︙ | |||
184540 184541 184542 184543 184544 184545 184546 184547 184548 184549 184550 184551 184552 184553 |
** SQLITE_TESTCTRL_SORTER_MMAP test-control at runtime. */
db->nMaxSorterMmap = 0x7FFFFFFF;
#endif
db->flags |= SQLITE_ShortColNames
| SQLITE_EnableTrigger
| SQLITE_EnableView
| SQLITE_CacheSpill
#if !defined(SQLITE_TRUSTED_SCHEMA) || SQLITE_TRUSTED_SCHEMA+0!=0
| SQLITE_TrustedSchema
#endif
/* The SQLITE_DQS compile-time option determines the default settings
** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML.
**
** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML
| > > > | 184949 184950 184951 184952 184953 184954 184955 184956 184957 184958 184959 184960 184961 184962 184963 184964 184965 |
** SQLITE_TESTCTRL_SORTER_MMAP test-control at runtime. */
db->nMaxSorterMmap = 0x7FFFFFFF;
#endif
db->flags |= SQLITE_ShortColNames
| SQLITE_EnableTrigger
| SQLITE_EnableView
| SQLITE_CacheSpill
| SQLITE_AttachCreate
| SQLITE_AttachWrite
| SQLITE_Comments
#if !defined(SQLITE_TRUSTED_SCHEMA) || SQLITE_TRUSTED_SCHEMA+0!=0
| SQLITE_TrustedSchema
#endif
/* The SQLITE_DQS compile-time option determines the default settings
** for SQLITE_DBCONFIG_DQS_DDL and SQLITE_DBCONFIG_DQS_DML.
**
** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML
|
| ︙ | ︙ | |||
185156 185157 185158 185159 185160 185161 185162 |
goto error_out;
}
/* Find the column for which info is requested */
if( zColumnName==0 ){
/* Query for existence of table only */
}else{
| > | < < | < < | 185568 185569 185570 185571 185572 185573 185574 185575 185576 185577 185578 185579 185580 185581 185582 185583 185584 185585 |
goto error_out;
}
/* Find the column for which info is requested */
if( zColumnName==0 ){
/* Query for existence of table only */
}else{
iCol = sqlite3ColumnIndex(pTab, zColumnName);
if( iCol>=0 ){
pCol = &pTab->aCol[iCol];
}else{
if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){
iCol = pTab->iPKey;
pCol = iCol>=0 ? &pTab->aCol[iCol] : 0;
}else{
pTab = 0;
goto error_out;
}
|
| ︙ | ︙ | |||
185490 185491 185492 185493 185494 185495 185496 |
assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 );
rc = x;
#if defined(SQLITE_DEBUG)
/* Invoke these debugging routines so that the compiler does not
** issue "defined but not used" warnings. */
if( x==9999 ){
sqlite3ShowExpr(0);
| < < | 185899 185900 185901 185902 185903 185904 185905 185906 185907 185908 185909 185910 185911 185912 185913 185914 185915 185916 185917 185918 185919 185920 185921 185922 185923 185924 185925 185926 185927 185928 |
assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 );
rc = x;
#if defined(SQLITE_DEBUG)
/* Invoke these debugging routines so that the compiler does not
** issue "defined but not used" warnings. */
if( x==9999 ){
sqlite3ShowExpr(0);
sqlite3ShowExprList(0);
sqlite3ShowIdList(0);
sqlite3ShowSrcList(0);
sqlite3ShowWith(0);
sqlite3ShowUpsert(0);
#ifndef SQLITE_OMIT_TRIGGER
sqlite3ShowTriggerStep(0);
sqlite3ShowTriggerStepList(0);
sqlite3ShowTrigger(0);
sqlite3ShowTriggerList(0);
#endif
#ifndef SQLITE_OMIT_WINDOWFUNC
sqlite3ShowWindow(0);
sqlite3ShowWinFunc(0);
#endif
sqlite3ShowSelect(0);
}
#endif
break;
}
/*
|
| ︙ | ︙ | |||
187847 187848 187849 187850 187851 187852 187853 187854 187855 187856 187857 187858 187859 187860 |
SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart(
Fts3Table*, Fts3MultiSegReader*, int, const char*, int);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext(
Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **);
SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
/* fts3_tokenize_vtab.c */
SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *, void(*xDestroy)(void*));
/* fts3_unicode2.c (functions generated by parsing unicode text files) */
#ifndef SQLITE_DISABLE_FTS3_UNICODE
SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int);
| > | 188254 188255 188256 188257 188258 188259 188260 188261 188262 188263 188264 188265 188266 188267 188268 |
SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart(
Fts3Table*, Fts3MultiSegReader*, int, const char*, int);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext(
Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *);
SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **);
SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *);
SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
SQLITE_PRIVATE int sqlite3Fts3MsrCancel(Fts3Cursor*, Fts3Expr*);
/* fts3_tokenize_vtab.c */
SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *, void(*xDestroy)(void*));
/* fts3_unicode2.c (functions generated by parsing unicode text files) */
#ifndef SQLITE_DISABLE_FTS3_UNICODE
SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int);
|
| ︙ | ︙ | |||
192016 192017 192018 192019 192020 192021 192022 |
nDistance = nMaxUndeferred - iPrev;
}else{
p1 = pPhrase->doclist.pList;
p2 = aPoslist;
nDistance = iPrev - nMaxUndeferred;
}
| | | 192424 192425 192426 192427 192428 192429 192430 192431 192432 192433 192434 192435 192436 192437 192438 |
nDistance = nMaxUndeferred - iPrev;
}else{
p1 = pPhrase->doclist.pList;
p2 = aPoslist;
nDistance = iPrev - nMaxUndeferred;
}
aOut = (char *)sqlite3Fts3MallocZero(((i64)nPoslist)+FTS3_BUFFER_PADDING);
if( !aOut ){
sqlite3_free(aPoslist);
return SQLITE_NOMEM;
}
pPhrase->doclist.pList = aOut;
assert( p1 && p2 );
|
| ︙ | ︙ | |||
193364 193365 193366 193367 193368 193369 193370 193371 193372 193373 193374 193375 193376 193377 |
pExpr->bEof = 0;
pExpr->bStart = 0;
fts3EvalRestart(pCsr, pExpr->pLeft, pRc);
fts3EvalRestart(pCsr, pExpr->pRight, pRc);
}
}
/*
** After allocating the Fts3Expr.aMI[] array for each phrase in the
** expression rooted at pExpr, the cursor iterates through all rows matched
** by pExpr, calling this function for each row. This function increments
** the values in Fts3Expr.aMI[] according to the position-list currently
** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase
| > > > > > > > > > > > > > > > > > > | 193772 193773 193774 193775 193776 193777 193778 193779 193780 193781 193782 193783 193784 193785 193786 193787 193788 193789 193790 193791 193792 193793 193794 193795 193796 193797 193798 193799 193800 193801 193802 193803 |
pExpr->bEof = 0;
pExpr->bStart = 0;
fts3EvalRestart(pCsr, pExpr->pLeft, pRc);
fts3EvalRestart(pCsr, pExpr->pRight, pRc);
}
}
/*
** Expression node pExpr is an MSR phrase. This function restarts pExpr
** so that it is a regular phrase query, not an MSR. SQLITE_OK is returned
** if successful, or an SQLite error code otherwise.
*/
SQLITE_PRIVATE int sqlite3Fts3MsrCancel(Fts3Cursor *pCsr, Fts3Expr *pExpr){
int rc = SQLITE_OK;
if( pExpr->bEof==0 ){
i64 iDocid = pExpr->iDocid;
fts3EvalRestart(pCsr, pExpr, &rc);
while( rc==SQLITE_OK && pExpr->iDocid!=iDocid ){
fts3EvalNextRow(pCsr, pExpr, &rc);
if( pExpr->bEof ) rc = FTS_CORRUPT_VTAB;
}
}
return rc;
}
/*
** After allocating the Fts3Expr.aMI[] array for each phrase in the
** expression rooted at pExpr, the cursor iterates through all rows matched
** by pExpr, calling this function for each row. This function increments
** the values in Fts3Expr.aMI[] according to the position-list currently
** found in Fts3Expr.pPhrase->doclist.pList for each of the phrase
|
| ︙ | ︙ | |||
194618 194619 194620 194621 194622 194623 194624 |
){
sqlite3_tokenizer *pTokenizer = pParse->pTokenizer;
sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
int rc;
Fts3Expr *p = 0;
sqlite3_tokenizer_cursor *pCursor = 0;
char *zTemp = 0;
| | | 195044 195045 195046 195047 195048 195049 195050 195051 195052 195053 195054 195055 195056 195057 195058 |
){
sqlite3_tokenizer *pTokenizer = pParse->pTokenizer;
sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
int rc;
Fts3Expr *p = 0;
sqlite3_tokenizer_cursor *pCursor = 0;
char *zTemp = 0;
i64 nTemp = 0;
const int nSpace = sizeof(Fts3Expr) + sizeof(Fts3Phrase);
int nToken = 0;
/* The final Fts3Expr data structure, including the Fts3Phrase,
** Fts3PhraseToken structures token buffers are all stored as a single
** allocation so that the expression can be freed with a single call to
|
| ︙ | ︙ | |||
205321 205322 205323 205324 205325 205326 205327 205328 205329 205330 205331 205332 205333 205334 |
pT->iOff = nTerm-iTerm-1;
pT->pList = pList;
pT->iPos = iPos;
}
return rc;
}
/*
** Implementation of offsets() function.
*/
SQLITE_PRIVATE void sqlite3Fts3Offsets(
sqlite3_context *pCtx, /* SQLite function call context */
Fts3Cursor *pCsr /* Cursor object */
| > > > > > > > > > > > > > > > > | 205747 205748 205749 205750 205751 205752 205753 205754 205755 205756 205757 205758 205759 205760 205761 205762 205763 205764 205765 205766 205767 205768 205769 205770 205771 205772 205773 205774 205775 205776 |
pT->iOff = nTerm-iTerm-1;
pT->pList = pList;
pT->iPos = iPos;
}
return rc;
}
/*
** If expression pExpr is a phrase expression that uses an MSR query,
** restart it as a regular, non-incremental query. Return SQLITE_OK
** if successful, or an SQLite error code otherwise.
*/
static int fts3ExprRestartIfCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
TermOffsetCtx *p = (TermOffsetCtx*)ctx;
int rc = SQLITE_OK;
UNUSED_PARAMETER(iPhrase);
if( pExpr->pPhrase && pExpr->pPhrase->bIncr ){
rc = sqlite3Fts3MsrCancel(p->pCsr, pExpr);
pExpr->pPhrase->bIncr = 0;
}
return rc;
}
/*
** Implementation of offsets() function.
*/
SQLITE_PRIVATE void sqlite3Fts3Offsets(
sqlite3_context *pCtx, /* SQLite function call context */
Fts3Cursor *pCsr /* Cursor object */
|
| ︙ | ︙ | |||
205357 205358 205359 205360 205361 205362 205363 205364 205365 205366 205367 205368 205369 205370 |
sCtx.aTerm = (TermOffset *)sqlite3Fts3MallocZero(sizeof(TermOffset)*nToken);
if( 0==sCtx.aTerm ){
rc = SQLITE_NOMEM;
goto offsets_out;
}
sCtx.iDocid = pCsr->iPrevId;
sCtx.pCsr = pCsr;
/* Loop through the table columns, appending offset information to
** string-buffer res for each column.
*/
for(iCol=0; iCol<pTab->nColumn; iCol++){
sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */
const char *ZDUMMY; /* Dummy argument used with xNext() */
| > > > > > > | 205799 205800 205801 205802 205803 205804 205805 205806 205807 205808 205809 205810 205811 205812 205813 205814 205815 205816 205817 205818 |
sCtx.aTerm = (TermOffset *)sqlite3Fts3MallocZero(sizeof(TermOffset)*nToken);
if( 0==sCtx.aTerm ){
rc = SQLITE_NOMEM;
goto offsets_out;
}
sCtx.iDocid = pCsr->iPrevId;
sCtx.pCsr = pCsr;
/* If a query restart will be required, do it here, rather than later of
** after pointers to poslist buffers that may be invalidated by a restart
** have been saved. */
rc = sqlite3Fts3ExprIterate(pCsr->pExpr, fts3ExprRestartIfCb, (void*)&sCtx);
if( rc!=SQLITE_OK ) goto offsets_out;
/* Loop through the table columns, appending offset information to
** string-buffer res for each column.
*/
for(iCol=0; iCol<pTab->nColumn; iCol++){
sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */
const char *ZDUMMY; /* Dummy argument used with xNext() */
|
| ︙ | ︙ | |||
207367 207368 207369 207370 207371 207372 207373 |
/*
** Expand pParse->aBlob so that it holds at least N bytes.
**
** Return the number of errors.
*/
static int jsonBlobExpand(JsonParse *pParse, u32 N){
u8 *aNew;
| | > | | 207815 207816 207817 207818 207819 207820 207821 207822 207823 207824 207825 207826 207827 207828 207829 207830 207831 207832 207833 207834 207835 207836 207837 207838 207839 207840 207841 |
/*
** Expand pParse->aBlob so that it holds at least N bytes.
**
** Return the number of errors.
*/
static int jsonBlobExpand(JsonParse *pParse, u32 N){
u8 *aNew;
u64 t;
assert( N>pParse->nBlobAlloc );
if( pParse->nBlobAlloc==0 ){
t = 100;
}else{
t = pParse->nBlobAlloc*2;
}
if( t<N ) t = N+100;
aNew = sqlite3DbRealloc(pParse->db, pParse->aBlob, t);
if( aNew==0 ){ pParse->oom = 1; return 1; }
assert( t<0x7fffffff );
pParse->aBlob = aNew;
pParse->nBlobAlloc = (u32)t;
return 0;
}
/*
** If pParse->aBlob is not previously editable (because it is taken
** from sqlite3_value_blob(), as indicated by the fact that
** pParse->nBlobAlloc==0 and pParse->nBlob>0) then make it editable
|
| ︙ | ︙ | |||
208335 208336 208337 208338 208339 208340 208341 |
** payload size in to *pSz. It returns the offset from i to the
** beginning of the payload. Return 0 on error.
*/
static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){
u8 x;
u32 sz;
u32 n;
| | < < < | 208784 208785 208786 208787 208788 208789 208790 208791 208792 208793 208794 208795 208796 208797 208798 |
** payload size in to *pSz. It returns the offset from i to the
** beginning of the payload. Return 0 on error.
*/
static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){
u8 x;
u32 sz;
u32 n;
assert( i<=pParse->nBlob );
x = pParse->aBlob[i]>>4;
if( x<=11 ){
sz = x;
n = 1;
}else if( x==12 ){
if( i+1>=pParse->nBlob ){
*pSz = 0;
|
| ︙ | ︙ | |||
208382 208383 208384 208385 208386 208387 208388 |
sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) +
(pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8];
n = 9;
}
if( (i64)i+sz+n > pParse->nBlob
&& (i64)i+sz+n > pParse->nBlob-pParse->delta
){
| | | | 208828 208829 208830 208831 208832 208833 208834 208835 208836 208837 208838 208839 208840 208841 208842 208843 |
sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) +
(pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8];
n = 9;
}
if( (i64)i+sz+n > pParse->nBlob
&& (i64)i+sz+n > pParse->nBlob-pParse->delta
){
*pSz = 0;
return 0;
}
*pSz = sz;
return n;
}
/*
|
| ︙ | ︙ | |||
208480 208481 208482 208483 208484 208485 208486 |
jsonAppendChar(pOut, '0');
}
}
break;
}
case JSONB_TEXT:
case JSONB_TEXTJ: {
| > | | > | > | 208926 208927 208928 208929 208930 208931 208932 208933 208934 208935 208936 208937 208938 208939 208940 208941 208942 208943 208944 208945 |
jsonAppendChar(pOut, '0');
}
}
break;
}
case JSONB_TEXT:
case JSONB_TEXTJ: {
if( pOut->nUsed+sz+2<=pOut->nAlloc || jsonStringGrow(pOut, sz+2)==0 ){
pOut->zBuf[pOut->nUsed] = '"';
memcpy(pOut->zBuf+pOut->nUsed+1,(const char*)&pParse->aBlob[i+n],sz);
pOut->zBuf[pOut->nUsed+sz+1] = '"';
pOut->nUsed += sz+2;
}
break;
}
case JSONB_TEXT5: {
const char *zIn;
u32 k;
u32 sz2 = sz;
zIn = (const char*)&pParse->aBlob[i+n];
|
| ︙ | ︙ | |||
209397 209398 209399 209400 209401 209402 209403 |
case JSONB_TEXTJ: {
/* Translate JSON formatted string into raw text */
u32 iIn, iOut;
const char *z;
char *zOut;
u32 nOut = sz;
z = (const char*)&pParse->aBlob[i+n];
| | | 209846 209847 209848 209849 209850 209851 209852 209853 209854 209855 209856 209857 209858 209859 209860 |
case JSONB_TEXTJ: {
/* Translate JSON formatted string into raw text */
u32 iIn, iOut;
const char *z;
char *zOut;
u32 nOut = sz;
z = (const char*)&pParse->aBlob[i+n];
zOut = sqlite3DbMallocRaw(db, ((u64)nOut)+1);
if( zOut==0 ) goto returnfromblob_oom;
for(iIn=iOut=0; iIn<sz; iIn++){
char c = z[iIn];
if( c=='\\' ){
u32 v;
u32 szEscape = jsonUnescapeOneChar(&z[iIn], sz-iIn, &v);
if( v<=0x7f ){
|
| ︙ | ︙ | |||
215525 215526 215527 215528 215529 215530 215531 |
#else
sqlite3_str_appendf(pOut, " %d", cell.aCoord[jj].i);
#endif
}
sqlite3_str_append(pOut, "}", 1);
}
errCode = sqlite3_str_errcode(pOut);
| < > | 215974 215975 215976 215977 215978 215979 215980 215981 215982 215983 215984 215985 215986 215987 215988 215989 |
#else
sqlite3_str_appendf(pOut, " %d", cell.aCoord[jj].i);
#endif
}
sqlite3_str_append(pOut, "}", 1);
}
errCode = sqlite3_str_errcode(pOut);
sqlite3_result_error_code(ctx, errCode);
sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free);
}
/* This routine implements an SQL function that returns the "depth" parameter
** from the front of a blob that is an r-tree node. For example:
**
** SELECT rtreedepth(data) FROM rt_node WHERE nodeno=1;
**
|
| ︙ | ︙ | |||
226230 226231 226232 226233 226234 226235 226236 226237 226238 226239 226240 226241 226242 226243 |
}
static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
*pRowid = pCsr->pgno;
return SQLITE_OK;
}
static int dbpageUpdate(
sqlite3_vtab *pVtab,
int argc,
sqlite3_value **argv,
sqlite_int64 *pRowid
){
| > > > > > > > > > > > > > > > > > > | 226679 226680 226681 226682 226683 226684 226685 226686 226687 226688 226689 226690 226691 226692 226693 226694 226695 226696 226697 226698 226699 226700 226701 226702 226703 226704 226705 226706 226707 226708 226709 226710 |
}
static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
DbpageCursor *pCsr = (DbpageCursor *)pCursor;
*pRowid = pCsr->pgno;
return SQLITE_OK;
}
/*
** Open write transactions. Since we do not know in advance which database
** files will be written by the sqlite_dbpage virtual table, start a write
** transaction on them all.
**
** Return SQLITE_OK if successful, or an SQLite error code otherwise.
*/
static int dbpageBeginTrans(DbpageTable *pTab){
sqlite3 *db = pTab->db;
int rc = SQLITE_OK;
int i;
for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( pBt ) rc = sqlite3BtreeBeginTrans(pBt, 1, 0);
}
return rc;
}
static int dbpageUpdate(
sqlite3_vtab *pVtab,
int argc,
sqlite3_value **argv,
sqlite_int64 *pRowid
){
|
| ︙ | ︙ | |||
226298 226299 226300 226301 226302 226303 226304 226305 226306 226307 226308 226309 226310 226311 226312 226313 226314 226315 226316 226317 226318 226319 226320 226321 226322 226323 226324 226325 |
pgno--;
pTab->pgnoTrunc = pgno;
}else{
zErr = "bad page value";
goto update_fail;
}
}
pPager = sqlite3BtreePager(pBt);
rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
if( rc==SQLITE_OK ){
const void *pData = sqlite3_value_blob(argv[3]);
if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
unsigned char *aPage = sqlite3PagerGetData(pDbPage);
memcpy(aPage, pData, szPage);
pTab->pgnoTrunc = 0;
}
}else{
pTab->pgnoTrunc = 0;
}
sqlite3PagerUnref(pDbPage);
return rc;
update_fail:
sqlite3_free(pVtab->zErrMsg);
pVtab->zErrMsg = sqlite3_mprintf("%s", zErr);
return SQLITE_ERROR;
}
| > > > > > > > < < < < < < < < < < > > | > > | | 226765 226766 226767 226768 226769 226770 226771 226772 226773 226774 226775 226776 226777 226778 226779 226780 226781 226782 226783 226784 226785 226786 226787 226788 226789 226790 226791 226792 226793 226794 226795 226796 226797 226798 226799 226800 226801 226802 226803 226804 226805 226806 226807 226808 226809 226810 226811 226812 226813 226814 226815 226816 226817 226818 226819 226820 226821 226822 226823 226824 226825 226826 226827 226828 226829 226830 226831 226832 226833 226834 226835 226836 226837 226838 226839 226840 226841 226842 226843 226844 |
pgno--;
pTab->pgnoTrunc = pgno;
}else{
zErr = "bad page value";
goto update_fail;
}
}
if( dbpageBeginTrans(pTab)!=SQLITE_OK ){
zErr = "failed to open transaction";
goto update_fail;
}
pPager = sqlite3BtreePager(pBt);
rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0);
if( rc==SQLITE_OK ){
const void *pData = sqlite3_value_blob(argv[3]);
if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
unsigned char *aPage = sqlite3PagerGetData(pDbPage);
memcpy(aPage, pData, szPage);
pTab->pgnoTrunc = 0;
}
}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;
pTab->pgnoTrunc = 0;
return SQLITE_OK;
}
/* Invoke sqlite3PagerTruncate() as necessary, just prior to COMMIT
*/
static int dbpageSync(sqlite3_vtab *pVtab){
DbpageTable *pTab = (DbpageTable *)pVtab;
if( pTab->pgnoTrunc>0 ){
Btree *pBt = pTab->db->aDb[pTab->iDbTrunc].pBt;
Pager *pPager = sqlite3BtreePager(pBt);
sqlite3BtreeEnter(pBt);
if( pTab->pgnoTrunc<sqlite3BtreeLastPage(pBt) ){
sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc);
}
sqlite3BtreeLeave(pBt);
}
pTab->pgnoTrunc = 0;
return SQLITE_OK;
}
/* Cancel any pending truncate.
*/
static int dbpageRollbackTo(sqlite3_vtab *pVtab, int notUsed1){
DbpageTable *pTab = (DbpageTable *)pVtab;
pTab->pgnoTrunc = 0;
(void)notUsed1;
return SQLITE_OK;
}
/*
** Invoke this routine to register the "dbpage" virtual table module
*/
SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){
static sqlite3_module dbpage_module = {
2, /* iVersion */
dbpageConnect, /* xCreate */
dbpageConnect, /* xConnect */
dbpageBestIndex, /* xBestIndex */
dbpageDisconnect, /* xDisconnect */
dbpageDisconnect, /* xDestroy */
dbpageOpen, /* xOpen - open a cursor */
dbpageClose, /* xClose - close a cursor */
|
| ︙ | ︙ | |||
226537 226538 226539 226540 226541 226542 226543 |
** then this variable is the compiled version of:
**
** SELECT 1, NULL, 'abc'
*/
struct SessionTable {
SessionTable *pNext;
char *zName; /* Local name of table */
| | > > | 227005 227006 227007 227008 227009 227010 227011 227012 227013 227014 227015 227016 227017 227018 227019 227020 227021 227022 227023 227024 227025 |
** then this variable is the compiled version of:
**
** SELECT 1, NULL, 'abc'
*/
struct SessionTable {
SessionTable *pNext;
char *zName; /* Local name of table */
int nCol; /* Number of non-hidden columns */
int nTotalCol; /* Number of columns including hidden */
int bStat1; /* True if this is sqlite_stat1 */
int bRowid; /* True if this table uses rowid for PK */
const char **azCol; /* Column names */
const char **azDflt; /* Default value expressions */
int *aiIdx; /* Index to pass to xNew/xOld */
u8 *abPK; /* Array of primary key flags */
int nEntry; /* Total number of entries in hash table */
int nChange; /* Size of apChange[] array */
SessionChange **apChange; /* Hash table buckets */
sqlite3_stmt *pDfltStmt;
};
|
| ︙ | ︙ | |||
226944 226945 226946 226947 226948 226949 226950 226951 |
int bNew, /* True to hash the new.* PK */
int *piHash, /* OUT: Hash value */
int *pbNullPK /* OUT: True if there are NULL values in PK */
){
unsigned int h = 0; /* Hash value to return */
int i; /* Used to iterate through columns */
if( pTab->bRowid ){
| > < < > | | | 227414 227415 227416 227417 227418 227419 227420 227421 227422 227423 227424 227425 227426 227427 227428 227429 227430 227431 227432 227433 227434 227435 227436 227437 227438 227439 227440 227441 227442 227443 |
int bNew, /* True to hash the new.* PK */
int *piHash, /* OUT: Hash value */
int *pbNullPK /* OUT: True if there are NULL values in PK */
){
unsigned int h = 0; /* Hash value to return */
int i; /* Used to iterate through columns */
assert( pTab->nTotalCol==pSession->hook.xCount(pSession->hook.pCtx) );
if( pTab->bRowid ){
h = sessionHashAppendI64(h, iRowid);
}else{
assert( *pbNullPK==0 );
for(i=0; i<pTab->nCol; i++){
if( pTab->abPK[i] ){
int rc;
int eType;
sqlite3_value *pVal;
int iIdx = pTab->aiIdx[i];
if( bNew ){
rc = pSession->hook.xNew(pSession->hook.pCtx, iIdx, &pVal);
}else{
rc = pSession->hook.xOld(pSession->hook.pCtx, iIdx, &pVal);
}
if( rc!=SQLITE_OK ) return rc;
eType = sqlite3_value_type(pVal);
h = sessionHashAppendType(h, eType);
if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
i64 iVal;
|
| ︙ | ︙ | |||
227296 227297 227298 227299 227300 227301 227302 227303 227304 227305 227306 227307 227308 227309 227310 |
for(iCol=0; iCol<pTab->nCol; iCol++){
if( !pTab->abPK[iCol] ){
a += sessionSerialLen(a);
}else{
sqlite3_value *pVal; /* Value returned by preupdate_new/old */
int rc; /* Error code from preupdate_new/old */
int eType = *a++; /* Type of value from change record */
/* The following calls to preupdate_new() and preupdate_old() can not
** fail. This is because they cache their return values, and by the
** time control flows to here they have already been called once from
** within sessionPreupdateHash(). The first two asserts below verify
** this (that the method has already been called). */
if( op==SQLITE_INSERT ){
/* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */
| > | | | 227766 227767 227768 227769 227770 227771 227772 227773 227774 227775 227776 227777 227778 227779 227780 227781 227782 227783 227784 227785 227786 227787 227788 227789 227790 227791 227792 |
for(iCol=0; iCol<pTab->nCol; iCol++){
if( !pTab->abPK[iCol] ){
a += sessionSerialLen(a);
}else{
sqlite3_value *pVal; /* Value returned by preupdate_new/old */
int rc; /* Error code from preupdate_new/old */
int eType = *a++; /* Type of value from change record */
int iIdx = pTab->aiIdx[iCol];
/* The following calls to preupdate_new() and preupdate_old() can not
** fail. This is because they cache their return values, and by the
** time control flows to here they have already been called once from
** within sessionPreupdateHash(). The first two asserts below verify
** this (that the method has already been called). */
if( op==SQLITE_INSERT ){
/* assert( db->pPreUpdate->pNewUnpacked || db->pPreUpdate->aNew ); */
rc = pSession->hook.xNew(pSession->hook.pCtx, iIdx, &pVal);
}else{
/* assert( db->pPreUpdate->pUnpacked ); */
rc = pSession->hook.xOld(pSession->hook.pCtx, iIdx, &pVal);
}
assert( rc==SQLITE_OK );
(void)rc; /* Suppress warning about unused variable */
if( sqlite3_value_type(pVal)!=eType ) return 0;
/* A SessionChange object never has a NULL value in a PK column */
assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT
|
| ︙ | ︙ | |||
227432 227433 227434 227435 227436 227437 227438 227439 227440 227441 227442 227443 227444 227445 227446 227447 227448 227449 227450 227451 227452 227453 227454 227455 227456 227457 227458 227459 227460 227461 227462 227463 227464 227465 227466 227467 227468 227469 227470 227471 |
*/
static int sessionTableInfo(
sqlite3_session *pSession, /* For memory accounting. May be NULL */
sqlite3 *db, /* Database connection */
const char *zDb, /* Name of attached database (e.g. "main") */
const char *zThis, /* Table name */
int *pnCol, /* OUT: number of columns */
const char **pzTab, /* OUT: Copy of zThis */
const char ***pazCol, /* OUT: Array of column names for table */
const char ***pazDflt, /* OUT: Array of default value expressions */
u8 **pabPK, /* OUT: Array of booleans - true for PK col */
int *pbRowid /* OUT: True if only PK is a rowid */
){
char *zPragma;
sqlite3_stmt *pStmt;
int rc;
sqlite3_int64 nByte;
int nDbCol = 0;
int nThis;
int i;
u8 *pAlloc = 0;
char **azCol = 0;
char **azDflt = 0;
u8 *abPK = 0;
int bRowid = 0; /* Set to true to use rowid as PK */
assert( pazCol && pabPK );
*pazCol = 0;
*pabPK = 0;
*pnCol = 0;
if( pzTab ) *pzTab = 0;
if( pazDflt ) *pazDflt = 0;
nThis = sqlite3Strlen30(zThis);
if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
if( rc==SQLITE_OK ){
/* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
zPragma = sqlite3_mprintf(
| > > > > > | | | | > | > | | | > > | | | | | | | | | | | | | | | | > | > > > | 227903 227904 227905 227906 227907 227908 227909 227910 227911 227912 227913 227914 227915 227916 227917 227918 227919 227920 227921 227922 227923 227924 227925 227926 227927 227928 227929 227930 227931 227932 227933 227934 227935 227936 227937 227938 227939 227940 227941 227942 227943 227944 227945 227946 227947 227948 227949 227950 227951 227952 227953 227954 227955 227956 227957 227958 227959 227960 227961 227962 227963 227964 227965 227966 227967 227968 227969 227970 227971 227972 227973 227974 227975 227976 227977 227978 227979 227980 227981 227982 227983 227984 227985 227986 227987 227988 227989 227990 227991 227992 227993 227994 227995 227996 227997 227998 227999 228000 228001 228002 228003 228004 228005 228006 228007 228008 228009 228010 228011 228012 228013 228014 228015 228016 228017 228018 228019 228020 228021 228022 228023 228024 228025 228026 228027 228028 228029 228030 228031 228032 228033 228034 228035 228036 228037 228038 228039 228040 228041 228042 228043 228044 228045 228046 228047 228048 228049 228050 228051 228052 228053 228054 228055 228056 228057 228058 |
*/
static int sessionTableInfo(
sqlite3_session *pSession, /* For memory accounting. May be NULL */
sqlite3 *db, /* Database connection */
const char *zDb, /* Name of attached database (e.g. "main") */
const char *zThis, /* Table name */
int *pnCol, /* OUT: number of columns */
int *pnTotalCol, /* OUT: number of hidden columns */
const char **pzTab, /* OUT: Copy of zThis */
const char ***pazCol, /* OUT: Array of column names for table */
const char ***pazDflt, /* OUT: Array of default value expressions */
int **paiIdx, /* OUT: Array of xNew/xOld indexes */
u8 **pabPK, /* OUT: Array of booleans - true for PK col */
int *pbRowid /* OUT: True if only PK is a rowid */
){
char *zPragma;
sqlite3_stmt *pStmt;
int rc;
sqlite3_int64 nByte;
int nDbCol = 0;
int nThis;
int i;
u8 *pAlloc = 0;
char **azCol = 0;
char **azDflt = 0;
u8 *abPK = 0;
int *aiIdx = 0;
int bRowid = 0; /* Set to true to use rowid as PK */
assert( pazCol && pabPK );
*pazCol = 0;
*pabPK = 0;
*pnCol = 0;
if( pnTotalCol ) *pnTotalCol = 0;
if( paiIdx ) *paiIdx = 0;
if( pzTab ) *pzTab = 0;
if( pazDflt ) *pazDflt = 0;
nThis = sqlite3Strlen30(zThis);
if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
if( rc==SQLITE_OK ){
/* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
zPragma = sqlite3_mprintf(
"SELECT 0, 'tbl', '', 0, '', 1, 0 UNION ALL "
"SELECT 1, 'idx', '', 0, '', 2, 0 UNION ALL "
"SELECT 2, 'stat', '', 0, '', 0, 0"
);
}else if( rc==SQLITE_ERROR ){
zPragma = sqlite3_mprintf("");
}else{
return rc;
}
}else{
zPragma = sqlite3_mprintf("PRAGMA '%q'.table_xinfo('%q')", zDb, zThis);
}
if( !zPragma ){
return SQLITE_NOMEM;
}
rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
sqlite3_free(zPragma);
if( rc!=SQLITE_OK ){
return rc;
}
nByte = nThis + 1;
bRowid = (pbRowid!=0);
while( SQLITE_ROW==sqlite3_step(pStmt) ){
nByte += sqlite3_column_bytes(pStmt, 1); /* name */
nByte += sqlite3_column_bytes(pStmt, 4); /* dflt_value */
if( sqlite3_column_int(pStmt, 6)==0 ){ /* !hidden */
nDbCol++;
}
if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; /* pk */
}
if( nDbCol==0 ) bRowid = 0;
nDbCol += bRowid;
nByte += strlen(SESSIONS_ROWID);
rc = sqlite3_reset(pStmt);
if( rc==SQLITE_OK ){
nByte += nDbCol * (sizeof(const char *)*2 +sizeof(int)+sizeof(u8) + 1 + 1);
pAlloc = sessionMalloc64(pSession, nByte);
if( pAlloc==0 ){
rc = SQLITE_NOMEM;
}else{
memset(pAlloc, 0, nByte);
}
}
if( rc==SQLITE_OK ){
azCol = (char **)pAlloc;
azDflt = (char**)&azCol[nDbCol];
aiIdx = (int*)&azDflt[nDbCol];
abPK = (u8 *)&aiIdx[nDbCol];
pAlloc = &abPK[nDbCol];
if( pzTab ){
memcpy(pAlloc, zThis, nThis+1);
*pzTab = (char *)pAlloc;
pAlloc += nThis+1;
}
i = 0;
if( bRowid ){
size_t nName = strlen(SESSIONS_ROWID);
memcpy(pAlloc, SESSIONS_ROWID, nName+1);
azCol[i] = (char*)pAlloc;
pAlloc += nName+1;
abPK[i] = 1;
aiIdx[i] = -1;
i++;
}
while( SQLITE_ROW==sqlite3_step(pStmt) ){
if( sqlite3_column_int(pStmt, 6)==0 ){ /* !hidden */
int nName = sqlite3_column_bytes(pStmt, 1);
int nDflt = sqlite3_column_bytes(pStmt, 4);
const unsigned char *zName = sqlite3_column_text(pStmt, 1);
const unsigned char *zDflt = sqlite3_column_text(pStmt, 4);
if( zName==0 ) break;
memcpy(pAlloc, zName, nName+1);
azCol[i] = (char *)pAlloc;
pAlloc += nName+1;
if( zDflt ){
memcpy(pAlloc, zDflt, nDflt+1);
azDflt[i] = (char *)pAlloc;
pAlloc += nDflt+1;
}else{
azDflt[i] = 0;
}
abPK[i] = sqlite3_column_int(pStmt, 5);
aiIdx[i] = sqlite3_column_int(pStmt, 0);
i++;
}
if( pnTotalCol ) (*pnTotalCol)++;
}
rc = sqlite3_reset(pStmt);
}
/* If successful, populate the output variables. Otherwise, zero them and
** free any allocation made. An error code will be returned in this case.
*/
if( rc==SQLITE_OK ){
*pazCol = (const char**)azCol;
if( pazDflt ) *pazDflt = (const char**)azDflt;
*pabPK = abPK;
*pnCol = nDbCol;
if( paiIdx ) *paiIdx = aiIdx;
}else{
sessionFree(pSession, azCol);
}
if( pbRowid ) *pbRowid = bRowid;
sqlite3_finalize(pStmt);
return rc;
}
|
| ︙ | ︙ | |||
227592 227593 227594 227595 227596 227597 227598 |
){
int rc = SQLITE_OK;
if( pTab->nCol==0 ){
u8 *abPK;
assert( pTab->azCol==0 || pTab->abPK==0 );
rc = sessionTableInfo(pSession, db, zDb,
| | > | 228076 228077 228078 228079 228080 228081 228082 228083 228084 228085 228086 228087 228088 228089 228090 228091 |
){
int rc = SQLITE_OK;
if( pTab->nCol==0 ){
u8 *abPK;
assert( pTab->azCol==0 || pTab->abPK==0 );
rc = sessionTableInfo(pSession, db, zDb,
pTab->zName, &pTab->nCol, &pTab->nTotalCol, 0, &pTab->azCol,
&pTab->azDflt, &pTab->aiIdx, &abPK,
((pSession==0 || pSession->bImplicitPK) ? &pTab->bRowid : 0)
);
if( rc==SQLITE_OK ){
int i;
for(i=0; i<pTab->nCol; i++){
if( abPK[i] ){
pTab->abPK = abPK;
|
| ︙ | ︙ | |||
227627 227628 227629 227630 227631 227632 227633 227634 227635 227636 227637 227638 227639 227640 227641 |
}
/*
** Re-initialize table object pTab.
*/
static int sessionReinitTable(sqlite3_session *pSession, SessionTable *pTab){
int nCol = 0;
const char **azCol = 0;
const char **azDflt = 0;
u8 *abPK = 0;
int bRowid = 0;
assert( pSession->rc==SQLITE_OK );
pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb,
| > > | | 228112 228113 228114 228115 228116 228117 228118 228119 228120 228121 228122 228123 228124 228125 228126 228127 228128 228129 228130 228131 228132 228133 228134 228135 228136 |
}
/*
** Re-initialize table object pTab.
*/
static int sessionReinitTable(sqlite3_session *pSession, SessionTable *pTab){
int nCol = 0;
int nTotalCol = 0;
const char **azCol = 0;
const char **azDflt = 0;
int *aiIdx = 0;
u8 *abPK = 0;
int bRowid = 0;
assert( pSession->rc==SQLITE_OK );
pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb,
pTab->zName, &nCol, &nTotalCol, 0, &azCol, &azDflt, &aiIdx, &abPK,
(pSession->bImplicitPK ? &bRowid : 0)
);
if( pSession->rc==SQLITE_OK ){
if( pTab->nCol>nCol || pTab->bRowid!=bRowid ){
pSession->rc = SQLITE_SCHEMA;
}else{
int ii;
|
| ︙ | ︙ | |||
227658 227659 227660 227661 227662 227663 227664 227665 227666 227667 227668 227669 227670 227671 227672 227673 |
}
}
if( pSession->rc==SQLITE_OK ){
const char **a = pTab->azCol;
pTab->azCol = azCol;
pTab->nCol = nCol;
pTab->azDflt = azDflt;
pTab->abPK = abPK;
azCol = a;
}
if( pSession->bEnableSize ){
pSession->nMaxChangesetSize += (nCol - nOldCol);
pSession->nMaxChangesetSize += sessionVarintLen(nCol);
pSession->nMaxChangesetSize -= sessionVarintLen(nOldCol);
}
| > > | 228145 228146 228147 228148 228149 228150 228151 228152 228153 228154 228155 228156 228157 228158 228159 228160 228161 228162 |
}
}
if( pSession->rc==SQLITE_OK ){
const char **a = pTab->azCol;
pTab->azCol = azCol;
pTab->nCol = nCol;
pTab->nTotalCol = nTotalCol;
pTab->azDflt = azDflt;
pTab->abPK = abPK;
pTab->aiIdx = aiIdx;
azCol = a;
}
if( pSession->bEnableSize ){
pSession->nMaxChangesetSize += (nCol - nOldCol);
pSession->nMaxChangesetSize += sessionVarintLen(nCol);
pSession->nMaxChangesetSize -= sessionVarintLen(nOldCol);
}
|
| ︙ | ︙ | |||
227977 227978 227979 227980 227981 227982 227983 |
i64 nNew = 2;
if( pC->op==SQLITE_INSERT ){
if( pTab->bRowid ) nNew += 9;
if( op!=SQLITE_DELETE ){
int ii;
for(ii=0; ii<pTab->nCol; ii++){
sqlite3_value *p = 0;
| | > | | 228466 228467 228468 228469 228470 228471 228472 228473 228474 228475 228476 228477 228478 228479 228480 228481 228482 228483 228484 228485 228486 228487 228488 228489 228490 228491 228492 228493 228494 228495 228496 228497 228498 228499 228500 228501 228502 |
i64 nNew = 2;
if( pC->op==SQLITE_INSERT ){
if( pTab->bRowid ) nNew += 9;
if( op!=SQLITE_DELETE ){
int ii;
for(ii=0; ii<pTab->nCol; ii++){
sqlite3_value *p = 0;
pSession->hook.xNew(pSession->hook.pCtx, pTab->aiIdx[ii], &p);
sessionSerializeValue(0, p, &nNew);
}
}
}else if( op==SQLITE_DELETE ){
nNew += pC->nRecord;
if( sqlite3_preupdate_blobwrite(pSession->db)>=0 ){
nNew += pC->nRecord;
}
}else{
int ii;
u8 *pCsr = pC->aRecord;
if( pTab->bRowid ){
nNew += 9 + 1;
pCsr += 9;
}
for(ii=pTab->bRowid; ii<pTab->nCol; ii++){
int bChanged = 1;
int nOld = 0;
int eType;
int iIdx = pTab->aiIdx[ii];
sqlite3_value *p = 0;
pSession->hook.xNew(pSession->hook.pCtx, iIdx, &p);
if( p==0 ){
return SQLITE_NOMEM;
}
eType = *pCsr++;
switch( eType ){
case SQLITE_NULL:
|
| ︙ | ︙ | |||
228095 228096 228097 228098 228099 228100 228101 | /* Load table details if required */ if( sessionInitTable(pSession, pTab, pSession->db, pSession->zDb) ) return; /* Check the number of columns in this xPreUpdate call matches the ** number of columns in the table. */ nExpect = pSession->hook.xCount(pSession->hook.pCtx); | | | | 228585 228586 228587 228588 228589 228590 228591 228592 228593 228594 228595 228596 228597 228598 228599 228600 228601 228602 228603 |
/* Load table details if required */
if( sessionInitTable(pSession, pTab, pSession->db, pSession->zDb) ) return;
/* Check the number of columns in this xPreUpdate call matches the
** number of columns in the table. */
nExpect = pSession->hook.xCount(pSession->hook.pCtx);
if( pTab->nTotalCol<nExpect ){
if( sessionReinitTable(pSession, pTab) ) return;
if( sessionUpdateChanges(pSession, pTab) ) return;
}
if( pTab->nTotalCol!=nExpect ){
pSession->rc = SQLITE_SCHEMA;
return;
}
/* Grow the hash table if required */
if( sessionGrowHash(pSession, 0, pTab) ){
pSession->rc = SQLITE_NOMEM;
|
| ︙ | ︙ | |||
228156 228157 228158 228159 228160 228161 228162 |
int i; /* Used to iterate through columns */
assert( rc==SQLITE_OK );
pTab->nEntry++;
/* Figure out how large an allocation is required */
nByte = sizeof(SessionChange);
| | > | | | 228646 228647 228648 228649 228650 228651 228652 228653 228654 228655 228656 228657 228658 228659 228660 228661 228662 228663 228664 228665 228666 228667 228668 |
int i; /* Used to iterate through columns */
assert( rc==SQLITE_OK );
pTab->nEntry++;
/* Figure out how large an allocation is required */
nByte = sizeof(SessionChange);
for(i=pTab->bRowid; i<pTab->nCol; i++){
int iIdx = pTab->aiIdx[i];
sqlite3_value *p = 0;
if( op!=SQLITE_INSERT ){
/* This may fail if the column has a non-NULL default and was added
** using ALTER TABLE ADD COLUMN after this record was created. */
rc = pSession->hook.xOld(pSession->hook.pCtx, iIdx, &p);
}else if( pTab->abPK[i] ){
TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx,iIdx,&p);
assert( trc==SQLITE_OK );
}
if( rc==SQLITE_OK ){
/* This may fail if SQLite value p contains a utf-16 string that must
** be converted to utf-8 and an OOM error occurs while doing so. */
rc = sessionSerializeValue(0, p, &nByte);
|
| ︙ | ︙ | |||
228198 228199 228200 228201 228202 228203 228204 |
** It is not possible for an OOM to occur in this block. */
nByte = 0;
if( pTab->bRowid ){
pC->aRecord[0] = SQLITE_INTEGER;
sessionPutI64(&pC->aRecord[1], iRowid);
nByte = 9;
}
| | > | | | 228689 228690 228691 228692 228693 228694 228695 228696 228697 228698 228699 228700 228701 228702 228703 228704 228705 228706 228707 228708 228709 |
** It is not possible for an OOM to occur in this block. */
nByte = 0;
if( pTab->bRowid ){
pC->aRecord[0] = SQLITE_INTEGER;
sessionPutI64(&pC->aRecord[1], iRowid);
nByte = 9;
}
for(i=pTab->bRowid; i<pTab->nCol; i++){
sqlite3_value *p = 0;
int iIdx = pTab->aiIdx[i];
if( op!=SQLITE_INSERT ){
pSession->hook.xOld(pSession->hook.pCtx, iIdx, &p);
}else if( pTab->abPK[i] ){
pSession->hook.xNew(pSession->hook.pCtx, iIdx, &p);
}
sessionSerializeValue(&pC->aRecord[nByte], p, &nByte);
}
/* Add the change to the hash-table */
if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){
pC->bIndirect = 1;
|
| ︙ | ︙ | |||
228605 228606 228607 228608 228609 228610 228611 |
if( rc==SQLITE_OK ){
int bHasPk = 0;
int bMismatch = 0;
int nCol; /* Columns in zFrom.zTbl */
int bRowid = 0;
u8 *abPK;
const char **azCol = 0;
| | > | 229097 229098 229099 229100 229101 229102 229103 229104 229105 229106 229107 229108 229109 229110 229111 229112 |
if( rc==SQLITE_OK ){
int bHasPk = 0;
int bMismatch = 0;
int nCol; /* Columns in zFrom.zTbl */
int bRowid = 0;
u8 *abPK;
const char **azCol = 0;
rc = sessionTableInfo(0, db, zFrom, zTbl,
&nCol, 0, 0, &azCol, 0, 0, &abPK,
pSession->bImplicitPK ? &bRowid : 0
);
if( rc==SQLITE_OK ){
if( pTo->nCol!=nCol ){
bMismatch = 1;
}else{
int i;
|
| ︙ | ︙ | |||
228929 228930 228931 228932 228933 228934 228935 |
int *pRc /* IN/OUT: Error code */
){
int nStr = sqlite3Strlen30(zStr)*2 + 2 + 2;
if( 0==sessionBufferGrow(p, nStr, pRc) ){
char *zOut = (char *)&p->aBuf[p->nBuf];
const char *zIn = zStr;
*zOut++ = '"';
| > | | | > | 229422 229423 229424 229425 229426 229427 229428 229429 229430 229431 229432 229433 229434 229435 229436 229437 229438 229439 229440 |
int *pRc /* IN/OUT: Error code */
){
int nStr = sqlite3Strlen30(zStr)*2 + 2 + 2;
if( 0==sessionBufferGrow(p, nStr, pRc) ){
char *zOut = (char *)&p->aBuf[p->nBuf];
const char *zIn = zStr;
*zOut++ = '"';
if( zIn!=0 ){
while( *zIn ){
if( *zIn=='"' ) *zOut++ = '"';
*zOut++ = *(zIn++);
}
}
*zOut++ = '"';
p->nBuf = (int)((u8 *)zOut - p->aBuf);
p->aBuf[p->nBuf] = 0x00;
}
}
|
| ︙ | ︙ | |||
229182 229183 229184 229185 229186 229187 229188 |
const char **azCol, /* Names of table columns */
u8 *abPK, /* PRIMARY KEY array */
sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
){
int rc = SQLITE_OK;
char *zSql = 0;
const char *zSep = "";
| < > | > > > > > > > | | 229677 229678 229679 229680 229681 229682 229683 229684 229685 229686 229687 229688 229689 229690 229691 229692 229693 229694 229695 229696 229697 229698 229699 229700 229701 229702 229703 229704 229705 229706 229707 229708 229709 229710 229711 229712 229713 229714 229715 229716 229717 229718 229719 229720 229721 229722 229723 229724 229725 229726 229727 229728 229729 229730 229731 229732 229733 229734 |
const char **azCol, /* Names of table columns */
u8 *abPK, /* PRIMARY KEY array */
sqlite3_stmt **ppStmt /* OUT: Prepared SELECT statement */
){
int rc = SQLITE_OK;
char *zSql = 0;
const char *zSep = "";
int nSql = -1;
int i;
SessionBuffer cols = {0, 0, 0};
SessionBuffer nooptest = {0, 0, 0};
SessionBuffer pkfield = {0, 0, 0};
SessionBuffer pkvar = {0, 0, 0};
sessionAppendStr(&nooptest, ", 1", &rc);
if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
sessionAppendStr(&nooptest, " AND (?6 OR ?3 IS stat)", &rc);
sessionAppendStr(&pkfield, "tbl, idx", &rc);
sessionAppendStr(&pkvar,
"?1, (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", &rc
);
sessionAppendStr(&cols, "tbl, ?2, stat", &rc);
}else{
#if 0
if( bRowid ){
sessionAppendStr(&cols, SESSIONS_ROWID, &rc);
}
#endif
for(i=0; i<nCol; i++){
if( cols.nBuf ) sessionAppendStr(&cols, ", ", &rc);
sessionAppendIdent(&cols, azCol[i], &rc);
if( abPK[i] ){
sessionAppendStr(&pkfield, zSep, &rc);
sessionAppendStr(&pkvar, zSep, &rc);
zSep = ", ";
sessionAppendIdent(&pkfield, azCol[i], &rc);
sessionAppendPrintf(&pkvar, &rc, "?%d", i+1);
}else{
sessionAppendPrintf(&nooptest, &rc,
" AND (?%d OR ?%d IS %w.%w)", i+1+nCol, i+1, zTab, azCol[i]
);
}
}
}
if( rc==SQLITE_OK ){
zSql = sqlite3_mprintf(
"SELECT %s%s FROM %Q.%Q WHERE (%s) IS (%s)",
(char*)cols.aBuf, (bIgnoreNoop ? (char*)nooptest.aBuf : ""),
zDb, zTab, (char*)pkfield.aBuf, (char*)pkvar.aBuf
);
if( zSql==0 ) rc = SQLITE_NOMEM;
}
#if 0
if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
|
| ︙ | ︙ | |||
229261 229262 229263 229264 229265 229266 229267 229268 229269 229270 229271 229272 229273 229274 |
if( rc==SQLITE_OK ){
rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
}
sqlite3_free(zSql);
sqlite3_free(nooptest.aBuf);
sqlite3_free(pkfield.aBuf);
sqlite3_free(pkvar.aBuf);
return rc;
}
/*
** Bind the PRIMARY KEY values from the change passed in argument pChange
** to the SELECT statement passed as the first argument. The SELECT statement
** is as prepared by function sessionSelectStmt().
| > | 229763 229764 229765 229766 229767 229768 229769 229770 229771 229772 229773 229774 229775 229776 229777 |
if( rc==SQLITE_OK ){
rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
}
sqlite3_free(zSql);
sqlite3_free(nooptest.aBuf);
sqlite3_free(pkfield.aBuf);
sqlite3_free(pkvar.aBuf);
sqlite3_free(cols.aBuf);
return rc;
}
/*
** Bind the PRIMARY KEY values from the change passed in argument pChange
** to the SELECT statement passed as the first argument. The SELECT statement
** is as prepared by function sessionSelectStmt().
|
| ︙ | ︙ | |||
231601 231602 231603 231604 231605 231606 231607 |
sApply.azCol = (const char **)zTab;
}else{
int nMinCol = 0;
int i;
sqlite3changeset_pk(pIter, &abPK, 0);
rc = sessionTableInfo(0, db, "main", zNew,
| > | | 232104 232105 232106 232107 232108 232109 232110 232111 232112 232113 232114 232115 232116 232117 232118 232119 |
sApply.azCol = (const char **)zTab;
}else{
int nMinCol = 0;
int i;
sqlite3changeset_pk(pIter, &abPK, 0);
rc = sessionTableInfo(0, db, "main", zNew,
&sApply.nCol, 0, &zTab, &sApply.azCol, 0, 0,
&sApply.abPK, &sApply.bRowid
);
if( rc!=SQLITE_OK ) break;
for(i=0; i<sApply.nCol; i++){
if( sApply.abPK[i] ) nMinCol = i+1;
}
if( sApply.nCol==0 ){
|
| ︙ | ︙ | |||
231681 231682 231683 231684 231685 231686 231687 |
sIter.nCol = nFk;
res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter);
if( res!=SQLITE_CHANGESET_OMIT ){
rc = SQLITE_CONSTRAINT;
}
}
}
| > > | > > < > > | 232185 232186 232187 232188 232189 232190 232191 232192 232193 232194 232195 232196 232197 232198 232199 232200 232201 232202 232203 232204 232205 232206 232207 232208 232209 |
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);
sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
}
}
assert( sApply.bRebase || sApply.rebase.nBuf==0 );
if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
|
| ︙ | ︙ | |||
243193 243194 243195 243196 243197 243198 243199 | fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret); return ret; } /* ** Close the read-only blob handle, if it is open. */ | | > | > | 243702 243703 243704 243705 243706 243707 243708 243709 243710 243711 243712 243713 243714 243715 243716 243717 243718 243719 243720 243721 243722 |
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
|
| ︙ | ︙ | |||
243222 243223 243224 243225 243226 243227 243228 |
** 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 ){
| | | 243733 243734 243735 243736 243737 243738 243739 243740 243741 243742 243743 243744 243745 243746 243747 |
** 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 ){
|
| ︙ | ︙ | |||
243306 243307 243308 243309 243310 243311 243312 |
static int fts5IndexPrepareStmt(
Fts5Index *p,
sqlite3_stmt **ppStmt,
char *zSql
){
if( p->rc==SQLITE_OK ){
if( zSql ){
| | > > > > | 243817 243818 243819 243820 243821 243822 243823 243824 243825 243826 243827 243828 243829 243830 243831 243832 243833 243834 243835 243836 243837 |
static int fts5IndexPrepareStmt(
Fts5Index *p,
sqlite3_stmt **ppStmt,
char *zSql
){
if( p->rc==SQLITE_OK ){
if( zSql ){
int rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB,
ppStmt, 0);
/* If this prepare() call fails with SQLITE_ERROR, then one of the
** %_idx or %_data tables has been removed or modified. Call this
** corruption. */
p->rc = (rc==SQLITE_ERROR ? SQLITE_CORRUPT : rc);
}else{
p->rc = SQLITE_NOMEM;
}
}
sqlite3_free(zSql);
return p->rc;
}
|
| ︙ | ︙ | |||
247419 247420 247421 247422 247423 247424 247425 247426 247427 247428 247429 247430 247431 247432 |
}
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;
};
| > > > > > > > > | 247934 247935 247936 247937 247938 247939 247940 247941 247942 247943 247944 247945 247946 247947 247948 247949 247950 247951 247952 247953 247954 247955 |
}
static int fts5IndexReturn(Fts5Index *p){
int rc = p->rc;
p->rc = SQLITE_OK;
return rc;
}
/*
** Close the read-only blob handle, if it is open.
*/
static void sqlite3Fts5IndexCloseReader(Fts5Index *p){
fts5IndexCloseReader(p);
fts5IndexReturn(p);
}
typedef struct Fts5FlushCtx Fts5FlushCtx;
struct Fts5FlushCtx {
Fts5Index *pIdx;
Fts5SegWriter writer;
};
|
| ︙ | ︙ | |||
247607 247608 247609 247610 247611 247612 247613 | u8 *aIdx = 0; int bLastInDoclist = 0; int iIdx = 0; int iStart = 0; int iDelKeyOff = 0; /* Offset of deleted key, if any */ nIdx = nPg-iPgIdx; | | | 248130 248131 248132 248133 248134 248135 248136 248137 248138 248139 248140 248141 248142 248143 248144 | u8 *aIdx = 0; int bLastInDoclist = 0; int iIdx = 0; int iStart = 0; int iDelKeyOff = 0; /* Offset of deleted key, if any */ nIdx = nPg-iPgIdx; aIdx = sqlite3Fts5MallocZero(&p->rc, ((i64)nIdx)+16); if( p->rc ) return; memcpy(aIdx, &aPg[iPgIdx], nIdx); /* At this point segment iterator pSeg points to the entry ** this function should remove from the b-tree segment. ** ** In detail=full or detail=column mode, pSeg->iLeafOffset is the |
| ︙ | ︙ | |||
247877 247878 247879 247880 247881 247882 247883 247884 | sqlite3_free(aIdx); } /* ** This is called as part of flushing a delete to disk in 'secure-delete' ** mode. It edits the segments within the database described by argument ** pStruct to remove the entries for term zTerm, rowid iRowid. */ | > > > | > > > > > > > > > > > > > > > > > > > | 248400 248401 248402 248403 248404 248405 248406 248407 248408 248409 248410 248411 248412 248413 248414 248415 248416 248417 248418 248419 248420 248421 248422 248423 248424 248425 248426 248427 248428 248429 248430 248431 248432 248433 248434 248435 248436 248437 248438 248439 248440 248441 248442 248443 248444 248445 248446 248447 248448 248449 248450 248451 248452 248453 248454 248455 248456 248457 248458 248459 248460 248461 248462 248463 |
sqlite3_free(aIdx);
}
/*
** This is called as part of flushing a delete to disk in 'secure-delete'
** mode. It edits the segments within the database described by argument
** pStruct to remove the entries for term zTerm, rowid iRowid.
**
** Return SQLITE_OK if successful, or an SQLite error code if an error
** has occurred. Any error code is also stored in the Fts5Index handle.
*/
static int fts5FlushSecureDelete(
Fts5Index *p,
Fts5Structure *pStruct,
const char *zTerm,
int nTerm,
i64 iRowid
){
const int f = FTS5INDEX_QUERY_SKIPHASH;
Fts5Iter *pIter = 0; /* Used to find term instance */
/* If the version number has not been set to SECUREDELETE, do so now. */
if( p->pConfig->iVersion!=FTS5_CURRENT_VERSION_SECUREDELETE ){
Fts5Config *pConfig = p->pConfig;
sqlite3_stmt *pStmt = 0;
fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf(
"REPLACE INTO %Q.'%q_config' VALUES ('version', %d)",
pConfig->zDb, pConfig->zName, FTS5_CURRENT_VERSION_SECUREDELETE
));
if( p->rc==SQLITE_OK ){
int rc;
sqlite3_step(pStmt);
rc = sqlite3_finalize(pStmt);
if( p->rc==SQLITE_OK ) p->rc = rc;
pConfig->iCookie++;
pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE;
}
}
fts5MultiIterNew(p, pStruct, f, 0, (const u8*)zTerm, nTerm, -1, 0, &pIter);
if( fts5MultiIterEof(p, pIter)==0 ){
i64 iThis = fts5MultiIterRowid(pIter);
if( iThis<iRowid ){
fts5MultiIterNextFrom(p, pIter, iRowid);
}
if( p->rc==SQLITE_OK
&& fts5MultiIterEof(p, pIter)==0
&& iRowid==fts5MultiIterRowid(pIter)
){
Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
fts5DoSecureDelete(p, pSeg);
}
}
fts5MultiIterFree(pIter);
return p->rc;
}
/*
** Flush the contents of in-memory hash table iHash to a new level-0
** segment on disk. Also update the corresponding structure record.
**
|
| ︙ | ︙ | |||
247988 247989 247990 247991 247992 247993 247994 |
iRowid += iDelta;
/* If in secure delete mode, and if this entry in the poslist is
** in fact a delete, then edit the existing segments directly
** using fts5FlushSecureDelete(). */
if( bSecureDelete ){
if( eDetail==FTS5_DETAIL_NONE ){
| | | > | | > | 248533 248534 248535 248536 248537 248538 248539 248540 248541 248542 248543 248544 248545 248546 248547 248548 248549 248550 248551 248552 248553 248554 248555 248556 248557 248558 248559 248560 |
iRowid += iDelta;
/* If in secure delete mode, and if this entry in the poslist is
** in fact a delete, then edit the existing segments directly
** using fts5FlushSecureDelete(). */
if( bSecureDelete ){
if( eDetail==FTS5_DETAIL_NONE ){
if( iOff<nDoclist && pDoclist[iOff]==0x00
&& !fts5FlushSecureDelete(p, pStruct, zTerm, nTerm, iRowid)
){
iOff++;
if( iOff<nDoclist && pDoclist[iOff]==0x00 ){
iOff++;
nDoclist = 0;
}else{
continue;
}
}
}else if( (pDoclist[iOff] & 0x01)
&& !fts5FlushSecureDelete(p, pStruct, zTerm, nTerm, iRowid)
){
if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){
iOff++;
continue;
}
}
}
|
| ︙ | ︙ | |||
248177 248178 248179 248180 248181 248182 248183 |
}
fts5StructureRef(pStruct);
return pStruct;
}
assert( pStruct->aLevel[i].nMerge<=nThis );
}
| | | 248724 248725 248726 248727 248728 248729 248730 248731 248732 248733 248734 248735 248736 248737 248738 |
}
fts5StructureRef(pStruct);
return pStruct;
}
assert( pStruct->aLevel[i].nMerge<=nThis );
}
nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel);
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
if( pNew ){
Fts5StructureLevel *pLvl;
nByte = nSeg * sizeof(Fts5StructureSegment);
pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL);
pNew->nRef = 1;
|
| ︙ | ︙ | |||
249065 249066 249067 249068 249069 249070 249071 |
s.xMerge(p, &s.doclist, s.nMerge, &s.aBuf[i]);
}
for(iFree=i; iFree<i+s.nMerge; iFree++){
fts5BufferFree(&s.aBuf[iFree]);
}
}
| | > > > | 249612 249613 249614 249615 249616 249617 249618 249619 249620 249621 249622 249623 249624 249625 249626 249627 249628 249629 249630 249631 249632 249633 249634 249635 249636 |
s.xMerge(p, &s.doclist, s.nMerge, &s.aBuf[i]);
}
for(iFree=i; iFree<i+s.nMerge; iFree++){
fts5BufferFree(&s.aBuf[iFree]);
}
}
pData = fts5IdxMalloc(p, sizeof(*pData)
+ ((i64)s.doclist.n)+FTS5_DATA_ZERO_PADDING);
assert( pData!=0 || p->rc!=SQLITE_OK );
if( pData ){
pData->p = (u8*)&pData[1];
pData->nn = pData->szLeaf = s.doclist.n;
if( s.doclist.n ) memcpy(pData->p, s.doclist.p, s.doclist.n);
fts5MultiIterNew2(p, pData, bDesc, ppIter);
}
assert( (*ppIter)!=0 || p->rc!=SQLITE_OK );
if( p->rc==SQLITE_OK && s.pTokendata ){
fts5TokendataIterSortMap(p, s2.pT);
(*ppIter)->pTokenDataIter = s2.pT;
s2.pT = 0;
}
}
|
| ︙ | ︙ | |||
249121 249122 249123 249124 249125 249126 249127 |
/*
** Commit data to disk.
*/
static int sqlite3Fts5IndexSync(Fts5Index *p){
assert( p->rc==SQLITE_OK );
fts5IndexFlush(p);
| | | < | | 249671 249672 249673 249674 249675 249676 249677 249678 249679 249680 249681 249682 249683 249684 249685 249686 249687 249688 249689 249690 249691 249692 249693 249694 249695 249696 249697 249698 249699 |
/*
** Commit data to disk.
*/
static int sqlite3Fts5IndexSync(Fts5Index *p){
assert( p->rc==SQLITE_OK );
fts5IndexFlush(p);
fts5IndexCloseReader(p);
return fts5IndexReturn(p);
}
/*
** Discard any data stored in the in-memory hash tables. Do not write it
** to the database. Additionally, assume that the contents of the %_data
** table may have changed on disk. So any in-memory caches of %_data
** records must be invalidated.
*/
static int sqlite3Fts5IndexRollback(Fts5Index *p){
fts5IndexCloseReader(p);
fts5IndexDiscardData(p);
fts5StructureInvalidate(p);
return fts5IndexReturn(p);
}
/*
** The %_data table is completely empty when this function is called. This
** function populates it with the initial structure objects for each index,
** and the initial version of the "averages" record (a zero-byte blob).
*/
|
| ︙ | ︙ | |||
249336 249337 249338 249339 249340 249341 249342 249343 249344 249345 249346 249347 249348 249349 |
/*
** 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) */
| > > > > > > > > > > | 249885 249886 249887 249888 249889 249890 249891 249892 249893 249894 249895 249896 249897 249898 249899 249900 249901 249902 249903 249904 249905 249906 249907 249908 |
/*
** 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) */
|
| ︙ | ︙ | |||
249364 249365 249366 249367 249368 249369 249370 |
if( pIn==0 ) memset(pNew, 0, nByte);
pRet = pNew;
pNew->nIterAlloc = nAlloc;
}
}
}
if( p->rc ){
| | | 249923 249924 249925 249926 249927 249928 249929 249930 249931 249932 249933 249934 249935 249936 249937 |
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;
}
|
| ︙ | ︙ | |||
249577 249578 249579 249580 249581 249582 249583 |
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 ){
| | | 250136 250137 250138 250139 250140 250141 250142 250143 250144 250145 250146 250147 250148 250149 250150 |
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--){
|
| ︙ | ︙ | |||
249642 249643 249644 249645 249646 249647 249648 |
}
}
/* 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 ){
| | | 250201 250202 250203 250204 250205 250206 250207 250208 250209 250210 250211 250212 250213 250214 250215 |
}
}
/* 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);
}
|
| ︙ | ︙ | |||
249704 249705 249706 249707 249708 249709 249710 249711 249712 249713 249714 249715 249716 249717 |
/* If the QUERY_SCAN flag is set, all other flags must be clear. */
assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
int iIdx = 0; /* Index to search */
int iPrefixIdx = 0; /* +1 prefix index */
int bTokendata = pConfig->bTokendata;
if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken);
/* The NOTOKENDATA flag is set when each token in a tokendata=1 table
** should be treated individually, instead of merging all those with
** a common prefix into a single entry. This is used, for example, by
** queries performed as part of an integrity-check, or by the fts5vocab
** module. */
| > | 250263 250264 250265 250266 250267 250268 250269 250270 250271 250272 250273 250274 250275 250276 250277 |
/* If the QUERY_SCAN flag is set, all other flags must be clear. */
assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
int iIdx = 0; /* Index to search */
int iPrefixIdx = 0; /* +1 prefix index */
int bTokendata = pConfig->bTokendata;
assert( buf.p!=0 );
if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken);
/* The NOTOKENDATA flag is set when each token in a tokendata=1 table
** should be treated individually, instead of merging all those with
** a common prefix into a single entry. This is used, for example, by
** queries performed as part of an integrity-check, or by the fts5vocab
** module. */
|
| ︙ | ︙ | |||
249770 249771 249772 249773 249774 249775 249776 |
Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
}
}
}
if( p->rc ){
| | | | 250330 250331 250332 250333 250334 250335 250336 250337 250338 250339 250340 250341 250342 250343 250344 250345 250346 |
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);
}
|
| ︙ | ︙ | |||
249865 249866 249867 249868 249869 249870 249871 249872 249873 249874 249875 249876 249877 249878 |
Fts5Index *p = pIter->pIndex;
Fts5Buffer token = {0, 0, 0};
TokendataSetupCtx ctx;
memset(&ctx, 0, sizeof(ctx));
fts5BufferGrow(&p->rc, &token, nToken+1);
ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT));
if( p->rc==SQLITE_OK ){
/* Fill in the token prefix to search for */
token.p[0] = FTS5_MAIN_PREFIX;
memcpy(&token.p[1], pToken, nToken);
| > | 250425 250426 250427 250428 250429 250430 250431 250432 250433 250434 250435 250436 250437 250438 250439 |
Fts5Index *p = pIter->pIndex;
Fts5Buffer token = {0, 0, 0};
TokendataSetupCtx ctx;
memset(&ctx, 0, sizeof(ctx));
fts5BufferGrow(&p->rc, &token, nToken+1);
assert( token.p!=0 || p->rc!=SQLITE_OK );
ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT));
if( p->rc==SQLITE_OK ){
/* Fill in the token prefix to search for */
token.p[0] = FTS5_MAIN_PREFIX;
memcpy(&token.p[1], pToken, nToken);
|
| ︙ | ︙ | |||
250021 250022 250023 250024 250025 250026 250027 |
}
/*
** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
*/
static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
if( pIndexIter ){
| < | < | | | 250582 250583 250584 250585 250586 250587 250588 250589 250590 250591 250592 250593 250594 250595 250596 250597 250598 |
}
/*
** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
*/
static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
if( pIndexIter ){
Fts5Index *pIndex = ((Fts5Iter*)pIndexIter)->pIndex;
fts5IterClose(pIndexIter);
fts5IndexReturn(pIndex);
}
}
/*
** Read and decode the "averages" record from the database.
**
** Parameter anSize must point to an array of size nCol, where nCol is
|
| ︙ | ︙ | |||
250555 250556 250557 250558 250559 250560 250561 |
cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
}
}
if( rc==SQLITE_OK ){
rc = sqlite3Fts5IterNext(pIter);
}
}
| | | 251114 251115 251116 251117 251118 251119 251120 251121 251122 251123 251124 251125 251126 251127 251128 |
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
|
| ︙ | ︙ | |||
251278 251279 251280 251281 251282 251283 251284 | iRowid = sqlite3_value_int64(apVal[0]); /* Make a copy of the second argument (a blob) in aBlob[]. The aBlob[] ** copy is followed by FTS5_DATA_ZERO_PADDING 0x00 bytes, which prevents ** buffer overreads even if the record is corrupt. */ n = sqlite3_value_bytes(apVal[1]); aBlob = sqlite3_value_blob(apVal[1]); | | | 251837 251838 251839 251840 251841 251842 251843 251844 251845 251846 251847 251848 251849 251850 251851 | iRowid = sqlite3_value_int64(apVal[0]); /* Make a copy of the second argument (a blob) in aBlob[]. The aBlob[] ** copy is followed by FTS5_DATA_ZERO_PADDING 0x00 bytes, which prevents ** buffer overreads even if the record is corrupt. */ n = sqlite3_value_bytes(apVal[1]); aBlob = sqlite3_value_blob(apVal[1]); nSpace = ((i64)n) + FTS5_DATA_ZERO_PADDING; a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace); if( a==0 ) goto decode_out; if( n>0 ) memcpy(a, aBlob, n); fts5DecodeRowid(iRowid, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno); fts5DebugRowid(&rc, &s, iRowid); |
| ︙ | ︙ | |||
253724 253725 253726 253727 253728 253729 253730 |
sqlite3_value **apVal, /* Array of arguments */
sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
){
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
Fts5Config *pConfig = pTab->p.pConfig;
int eType0; /* value_type() of apVal[0] */
int rc = SQLITE_OK; /* Return code */
| < | | 254283 254284 254285 254286 254287 254288 254289 254290 254291 254292 254293 254294 254295 254296 254297 254298 254299 254300 254301 254302 254303 254304 254305 254306 254307 254308 |
sqlite3_value **apVal, /* Array of arguments */
sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
){
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
Fts5Config *pConfig = pTab->p.pConfig;
int eType0; /* value_type() of apVal[0] */
int rc = SQLITE_OK; /* Return code */
/* A transaction must be open when this is called. */
assert( pTab->ts.eState==1 || pTab->ts.eState==2 );
assert( pVtab->zErrMsg==0 );
assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER
|| sqlite3_value_type(apVal[0])==SQLITE_NULL
);
assert( pTab->p.pConfig->pzErrmsg==0 );
if( pConfig->pgsz==0 ){
rc = sqlite3Fts5ConfigLoad(pTab->p.pConfig, pTab->p.pConfig->iCookie);
if( rc!=SQLITE_OK ) return rc;
}
pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;
/* Put any active cursors into REQUIRE_SEEK state. */
fts5TripCursors(pTab);
|
| ︙ | ︙ | |||
253761 253762 253763 253764 253765 253766 253767 |
if( pConfig->bContentlessDelete ){
fts5SetVtabError(pTab,
"'delete' may not be used with a contentless_delete=1 table"
);
rc = SQLITE_ERROR;
}else{
rc = fts5SpecialDelete(pTab, apVal);
| < | 254319 254320 254321 254322 254323 254324 254325 254326 254327 254328 254329 254330 254331 254332 |
if( pConfig->bContentlessDelete ){
fts5SetVtabError(pTab,
"'delete' may not be used with a contentless_delete=1 table"
);
rc = SQLITE_ERROR;
}else{
rc = fts5SpecialDelete(pTab, apVal);
}
}else{
rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
}
}else{
/* A regular INSERT, UPDATE or DELETE statement. The trick here is that
** any conflict on the rowid value must be detected before any
|
| ︙ | ︙ | |||
253798 253799 253800 253801 253802 253803 253804 |
fts5SetVtabError(pTab,
"cannot DELETE from contentless fts5 table: %s", pConfig->zName
);
rc = SQLITE_ERROR;
}else{
i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0);
| < | 254355 254356 254357 254358 254359 254360 254361 254362 254363 254364 254365 254366 254367 254368 |
fts5SetVtabError(pTab,
"cannot DELETE from contentless fts5 table: %s", pConfig->zName
);
rc = SQLITE_ERROR;
}else{
i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0, 0);
}
}
/* INSERT or UPDATE */
else{
int eType1 = sqlite3_value_numeric_type(apVal[1]);
|
| ︙ | ︙ | |||
253826 253827 253828 253829 253830 253831 253832 |
if( eType0!=SQLITE_INTEGER ){
/* An INSERT statement. If the conflict-mode is REPLACE, first remove
** the current entry (if any). */
if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0);
| < | 254382 254383 254384 254385 254386 254387 254388 254389 254390 254391 254392 254393 254394 254395 |
if( eType0!=SQLITE_INTEGER ){
/* An INSERT statement. If the conflict-mode is REPLACE, first remove
** the current entry (if any). */
if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){
i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */
rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0, 0);
}
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
/* UPDATE */
else{
Fts5Storage *pStorage = pTab->pStorage;
|
| ︙ | ︙ | |||
253880 253881 253882 253883 253884 253885 253886 |
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageContentInsert(pStorage, 1, apVal, pRowid);
}
}else{
rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1);
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
| < < < < < < < < < < < < < < < | 254435 254436 254437 254438 254439 254440 254441 254442 254443 254444 254445 254446 254447 254448 254449 254450 |
if( rc==SQLITE_OK ){
rc = sqlite3Fts5StorageContentInsert(pStorage, 1, apVal, pRowid);
}
}else{
rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1);
fts5StorageInsert(&rc, pTab, apVal, pRowid);
}
sqlite3Fts5StorageReleaseDeleteRow(pStorage);
}
}
}
update_out:
pTab->p.pConfig->pzErrmsg = 0;
return rc;
}
|
| ︙ | ︙ | |||
253949 253950 253951 253952 253953 253954 253955 253956 253957 253958 253959 253960 253961 253962 |
** hash-table. Any changes made to the database are reverted by SQLite.
*/
static int fts5RollbackMethod(sqlite3_vtab *pVtab){
int rc;
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0);
rc = sqlite3Fts5StorageRollback(pTab->pStorage);
return rc;
}
static int fts5CsrPoslist(Fts5Cursor*, int, const u8**, int*);
static void *fts5ApiUserData(Fts5Context *pCtx){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
| > | 254489 254490 254491 254492 254493 254494 254495 254496 254497 254498 254499 254500 254501 254502 254503 |
** hash-table. Any changes made to the database are reverted by SQLite.
*/
static int fts5RollbackMethod(sqlite3_vtab *pVtab){
int rc;
Fts5FullTable *pTab = (Fts5FullTable*)pVtab;
fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0);
rc = sqlite3Fts5StorageRollback(pTab->pStorage);
pTab->p.pConfig->pgsz = 0;
return rc;
}
static int fts5CsrPoslist(Fts5Cursor*, int, const u8**, int*);
static void *fts5ApiUserData(Fts5Context *pCtx){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
|
| ︙ | ︙ | |||
255417 255418 255419 255420 255421 255422 255423 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
| | | 255958 255959 255960 255961 255962 255963 255964 255965 255966 255967 255968 255969 255970 255971 255972 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2025-02-18 01:16:26 57caa3136d1bfca06e4f2285734a4977b8d3fa1f75bf87453b975867e9de38fc", -1, SQLITE_TRANSIENT);
}
/*
** Implementation of fts5_locale(LOCALE, TEXT) function.
**
** If parameter LOCALE is NULL, or a zero-length string, then a copy of
** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as
|
| ︙ | ︙ | |||
255897 255898 255899 255900 255901 255902 255903 255904 255905 255906 255907 255908 255909 255910 |
if( eStmt>FTS5_STMT_LOOKUP2 ) f |= SQLITE_PREPARE_NO_VTAB;
p->pConfig->bLock++;
rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
p->pConfig->bLock--;
sqlite3_free(zSql);
if( rc!=SQLITE_OK && pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
}
}
}
*ppStmt = p->aStmt[eStmt];
sqlite3_reset(*ppStmt);
return rc;
| > > > > > | 256438 256439 256440 256441 256442 256443 256444 256445 256446 256447 256448 256449 256450 256451 256452 256453 256454 256455 256456 |
if( eStmt>FTS5_STMT_LOOKUP2 ) f |= SQLITE_PREPARE_NO_VTAB;
p->pConfig->bLock++;
rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
p->pConfig->bLock--;
sqlite3_free(zSql);
if( rc!=SQLITE_OK && pzErrMsg ){
*pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
}
if( rc==SQLITE_ERROR && eStmt>FTS5_STMT_LOOKUP2 && eStmt<FTS5_STMT_SCAN ){
/* One of the internal tables - not the %_content table - is missing.
** This counts as a corrupted table. */
rc = SQLITE_CORRUPT;
}
}
}
*ppStmt = p->aStmt[eStmt];
sqlite3_reset(*ppStmt);
return rc;
|
| ︙ | ︙ | |||
260017 260018 260019 260020 260021 260022 260023 |
bDb = (argc==6 && strlen(argv[1])==4 && memcmp("temp", argv[1], 4)==0);
if( argc!=5 && bDb==0 ){
*pzErr = sqlite3_mprintf("wrong number of vtable arguments");
rc = SQLITE_ERROR;
}else{
| | | | | 260563 260564 260565 260566 260567 260568 260569 260570 260571 260572 260573 260574 260575 260576 260577 260578 260579 260580 260581 260582 |
bDb = (argc==6 && strlen(argv[1])==4 && memcmp("temp", argv[1], 4)==0);
if( argc!=5 && bDb==0 ){
*pzErr = sqlite3_mprintf("wrong number of vtable arguments");
rc = SQLITE_ERROR;
}else{
i64 nByte; /* Bytes of space to allocate */
const char *zDb = bDb ? argv[3] : argv[1];
const char *zTab = bDb ? argv[4] : argv[3];
const char *zType = bDb ? argv[5] : argv[4];
i64 nDb = strlen(zDb)+1;
i64 nTab = strlen(zTab)+1;
int eType = 0;
rc = fts5VocabTableType(zType, pzErr, &eType);
if( rc==SQLITE_OK ){
assert( eType>=0 && eType<ArraySize(azSchema) );
rc = sqlite3_declare_vtab(db, azSchema[eType]);
}
|
| ︙ | ︙ |
Changes to extsrc/sqlite3.h.
| ︙ | ︙ | |||
142 143 144 145 146 147 148 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.50.0" #define SQLITE_VERSION_NUMBER 3050000 #define SQLITE_SOURCE_ID "2025-02-18 01:16:26 57caa3136d1bfca06e4f2285734a4977b8d3fa1f75bf87453b975867e9de38fc" /* ** 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 |
| ︙ | ︙ | |||
1985 1986 1987 1988 1989 1990 1991 | ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** the entire mutexing subsystem is omitted from the build and hence calls to ** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will ** return [SQLITE_ERROR].</dd> ** ** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt> ** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine | | | | | | | > > > | 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 |
** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
** the entire mutexing subsystem is omitted from the build and hence calls to
** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will
** return [SQLITE_ERROR].</dd>
**
** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine
** the default size of [lookaside memory] on each [database connection].
** The first argument is the
** size of each lookaside buffer slot ("sz") and the second is the number of
** slots allocated to each database connection ("cnt").)^
** ^(SQLITE_CONFIG_LOOKASIDE sets the <i>default</i> lookaside size.
** The [SQLITE_DBCONFIG_LOOKASIDE] option to [sqlite3_db_config()] can
** be used to change the lookaside configuration on individual connections.)^
** The [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to change the
** default lookaside configuration at compile-time.
** </dd>
**
** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
** <dd> ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is
** a pointer to an [sqlite3_pcache_methods2] object. This object specifies
** the interface to a custom page cache implementation.)^
** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd>
**
|
| ︙ | ︙ | |||
2207 2208 2209 2210 2211 2212 2213 | #define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ #define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */ /* ** CAPI3REF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that | > > | > > > > > > | | > > > > > > > | < | | > | > > > > > > > > > > | | | < | < | | > > > > > > > > > > | > | 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 |
#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */
#define SQLITE_CONFIG_ROWID_IN_VIEW 30 /* int* */
/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
** can be passed as the second parameter to the [sqlite3_db_config()] interface.
**
** The [sqlite3_db_config()] interface is a var-args functions. It takes a
** variable number of parameters, though always at least two. The number of
** parameters passed into sqlite3_db_config() depends on which of these
** constants is given as the second parameter. This documentation page
** refers to parameters beyond the second as "arguments". Thus, when this
** page says "the N-th argument" it means "the N-th parameter past the
** configuration option" or "the (N+2)-th parameter to sqlite3_db_config()".
**
** New configuration options may be added in future releases of SQLite.
** Existing configuration options might be discontinued. Applications
** should check the return code from [sqlite3_db_config()] to make sure that
** the call worked. ^The [sqlite3_db_config()] interface will return a
** non-zero [error code] if a discontinued or unsupported configuration option
** is invoked.
**
** <dl>
** [[SQLITE_DBCONFIG_LOOKASIDE]]
** <dt>SQLITE_DBCONFIG_LOOKASIDE</dt>
** <dd> The SQLITE_DBCONFIG_LOOKASIDE option is used to adjust the
** configuration of the [lookaside memory allocator] within a database
** connection.
** The arguments to the SQLITE_DBCONFIG_LOOKASIDE option are <i>not</i>
** in the [DBCONFIG arguments|usual format].
** The SQLITE_DBCONFIG_LOOKASIDE option takes three arguments, not two,
** so that a call to [sqlite3_db_config()] that uses SQLITE_DBCONFIG_LOOKASIDE
** should have a total of five parameters.
** <ol>
** <li><p>The first argument ("buf") is a
** pointer to a memory buffer to use for lookaside memory.
** The first argument may be NULL in which case SQLite will allocate the
** lookaside buffer itself using [sqlite3_malloc()].
** <li><P>The second argument ("sz") is the
** size of each lookaside buffer slot. Lookaside is disabled if "sz"
** is less than 8. The "sz" argument should be a multiple of 8 less than
** 65536. If "sz" does not meet this constraint, it is reduced in size until
** it does.
** <li><p>The third argument ("cnt") is the number of slots. Lookaside is disabled
** if "cnt"is less than 1. The "cnt" value will be reduced, if necessary, so
** that the product of "sz" and "cnt" does not exceed 2,147,418,112. The "cnt"
** parameter is usually chosen so that the product of "sz" and "cnt" is less
** than 1,000,000.
** </ol>
** <p>If the "buf" argument is not NULL, then it must
** point to a memory buffer with a size that is greater than
** or equal to the product of "sz" and "cnt".
** The buffer must be aligned to an 8-byte boundary.
** The lookaside memory
** configuration for a database connection can only be changed when that
** connection is not currently using lookaside memory, or in other words
** when the value returned by [SQLITE_DBSTATUS_LOOKASIDE_USED] is zero.
** Any attempt to change the lookaside memory configuration when lookaside
** memory is in use leaves the configuration unchanged and returns
** [SQLITE_BUSY].
** If the "buf" argument is NULL and an attempt
** to allocate memory based on "sz" and "cnt" fails, then
** lookaside is silently disabled.
** <p>
** The [SQLITE_CONFIG_LOOKASIDE] configuration option can be used to set the
** default lookaside configuration at initialization. The
** [-DSQLITE_DEFAULT_LOOKASIDE] option can be used to set the default lookaside
** configuration at compile-time. Typical values for lookaside are 1200 for
** "sz" and 40 to 100 for "cnt".
** </dd>
**
** [[SQLITE_DBCONFIG_ENABLE_FKEY]]
** <dt>SQLITE_DBCONFIG_ENABLE_FKEY</dt>
** <dd> ^This option is used to enable or disable the enforcement of
** [foreign key constraints]. This is the same setting that is
** enabled or disabled by the [PRAGMA foreign_keys] statement.
** The first argument is an integer which is 0 to disable FK enforcement,
** positive to enable FK enforcement or negative to leave FK enforcement
** unchanged. The second parameter is a pointer to an integer into which
** is written 0 or 1 to indicate whether FK enforcement is off or on
** following this call. The second parameter may be a NULL pointer, in
** which case the FK enforcement setting is not reported back. </dd>
**
|
| ︙ | ︙ | |||
2265 2266 2267 2268 2269 2270 2271 | ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. ** ** <p>Originally this option disabled all triggers. ^(However, since ** SQLite version 3.35.0, TEMP triggers are still allowed even if ** this option is off. So, in other words, this option now only disables | | | | | > > > > | | | | | | | > | | > | > | | | | 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 | ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. ** ** <p>Originally this option disabled all triggers. ^(However, since ** SQLite version 3.35.0, TEMP triggers are still allowed even if ** this option is off. So, in other words, this option now only disables ** triggers in the main database schema or in the schemas of [ATTACH]-ed ** databases.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] ** <dt>SQLITE_DBCONFIG_ENABLE_VIEW</dt> ** <dd> ^This option is used to enable or disable [CREATE VIEW | views]. ** There must be two additional arguments. ** The first argument is an integer which is 0 to disable views, ** positive to enable views or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the view setting is not reported back. ** ** <p>Originally this option disabled all views. ^(However, since ** SQLite version 3.35.0, TEMP views are still allowed even if ** this option is off. So, in other words, this option now only disables ** views in the main database schema or in the schemas of ATTACH-ed ** databases.)^ </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] ** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt> ** <dd> ^This option is used to enable or disable the ** [fts3_tokenizer()] function which is part of the ** [FTS3] full-text search engine extension. ** There must be two additional arguments. ** The first argument is an integer which is 0 to disable fts3_tokenizer() or ** positive to enable fts3_tokenizer() or negative to leave the setting ** unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the new setting is not reported back. </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]] ** <dt>SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION</dt> ** <dd> ^This option is used to enable or disable the [sqlite3_load_extension()] ** interface independently of the [load_extension()] SQL function. ** The [sqlite3_enable_load_extension()] API enables or disables both the ** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. ** There must be two additional arguments. ** When the first argument to this interface is 1, then only the C-API is ** enabled and the SQL function remains disabled. If the first argument to ** this interface is 0, then both the C-API and the SQL function are disabled. ** If the first argument is -1, then no changes are made to state of either the ** C-API or the SQL function. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface ** is disabled or enabled following this call. The second parameter may ** be a NULL pointer, in which case the new setting is not reported back. ** </dd> ** ** [[SQLITE_DBCONFIG_MAINDBNAME]] <dt>SQLITE_DBCONFIG_MAINDBNAME</dt> ** <dd> ^This option is used to change the name of the "main" database ** schema. This option does not follow the ** [DBCONFIG arguments|usual SQLITE_DBCONFIG argument format]. ** This option takes exactly one additional argument so that the ** [sqlite3_db_config()] call has a total of three parameters. The ** extra argument must be a pointer to a constant UTF8 string which ** will become the new schema name in place of "main". ^SQLite does ** not make a copy of the new main schema name string, so the application ** must ensure that the argument passed into SQLITE_DBCONFIG MAINDBNAME ** is unchanged until after the database connection closes. ** </dd> ** ** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt> ** <dd> Usually, when a database in [WAL mode] is closed or detached from a ** database handle, SQLite checks if if there are other connections to the ** same database, and if there are no other database connection (if the ** connection being closed is the last open connection to the database), ** then SQLite performs a [checkpoint] before closing the connection and ** deletes the WAL file. The SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE option can ** be used to override that behavior. The first argument passed to this ** operation (the third parameter to [sqlite3_db_config()]) is an integer ** which is positive to disable checkpoints-on-close, or zero (the default) ** to enable them, and negative to leave the setting unchanged. ** The second argument (the fourth parameter) is a pointer to an integer ** into which is written 0 or 1 to indicate whether checkpoints-on-close ** have been disabled - 0 if they are not disabled, 1 if they are. ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_QPSG]] <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt> ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates ** the [query planner stability guarantee] (QPSG). When the QPSG is active, |
| ︙ | ︙ | |||
2496 2497 2498 2499 2500 2501 2502 | ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt> ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() ** statistics. For statistics to be collected, the flag must be set on ** the database handle both when the SQL statement is prepared and when it ** is stepped. The flag is set (collection of statistics is enabled) | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 | ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt> ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() ** statistics. For statistics to be collected, the flag must be set on ** the database handle both when the SQL statement is prepared and when it ** is stepped. The flag is set (collection of statistics is enabled) ** by default. <p>This option takes two arguments: an integer and a pointer to ** an integer.. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the statement scanstatus option. If the second argument ** is not NULL, then the value of the statement scanstatus setting after ** processing the first argument is written into the integer that the second ** argument points to. ** </dd> ** ** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]] ** <dt>SQLITE_DBCONFIG_REVERSE_SCANORDER</dt> ** <dd>The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order ** in which tables and indexes are scanned so that the scans start at the end ** and work toward the beginning rather than starting at the beginning and ** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the ** same as setting [PRAGMA reverse_unordered_selects]. <p>This option takes ** two arguments which are an integer and a pointer to an integer. The first ** argument is 1, 0, or -1 to enable, disable, or leave unchanged the ** reverse scan order flag, respectively. If the second argument is not NULL, ** then 0 or 1 is written into the integer that the second argument points to ** depending on if the reverse scan order flag is set after processing the ** first argument. ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE]] ** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE</dt> ** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE option enables or disables ** the ability of the [ATTACH DATABASE] SQL command to create a new database ** file if the database filed named in the ATTACH command does not already ** exist. This ability of ATTACH to create a new database is enabled by ** default. Applications can disable or reenable the ability for ATTACH to ** create new database files using this DBCONFIG option.<p> ** This option takes two arguments which are an integer and a pointer ** to an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the attach-create flag, respectively. If the second ** argument is not NULL, then 0 or 1 is written into the integer that the ** second argument points to depending on if the attach-create flag is set ** after processing the first argument. ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE]] ** <dt>SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE</dt> ** <dd>The SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE option enables or disables the ** ability of the [ATTACH DATABASE] SQL command to open a database for writing. ** This capability is enabled by default. Applications can disable or ** reenable this capability using the current DBCONFIG option. If the ** the this capability is disabled, the [ATTACH] command will still work, ** but the database will be opened read-only. If this option is disabled, ** then the ability to create a new database using [ATTACH] is also disabled, ** regardless of the value of the [SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE] ** option.<p> ** This option takes two arguments which are an integer and a pointer ** to an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the ability to ATTACH another database for writing, ** respectively. If the second argument is not NULL, then 0 or 1 is written ** into the integer to which the second argument points, depending on whether ** the ability to ATTACH a read/write database is enabled or disabled ** after processing the first argument. ** </dd> ** ** [[SQLITE_DBCONFIG_ENABLE_COMMENTS]] ** <dt>SQLITE_DBCONFIG_ENABLE_COMMENTS</dt> ** <dd>The SQLITE_DBCONFIG_ENABLE_COMMENTS option enables or disables the ** ability to include comments in SQL text. Comments are enabled by default. ** An application can disable or reenable comments in SQL text using this ** DBCONFIG option.<p> ** This option takes two arguments which are an integer and a pointer ** to an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the ability to use comments in SQL text, ** respectively. If the second argument is not NULL, then 0 or 1 is written ** into the integer that the second argument points to depending on if ** comments are allowed in SQL text after processing the first argument. ** </dd> ** ** </dl> ** ** [[DBCONFIG arguments]] <h3>Arguments To SQLITE_DBCONFIG Options</h3> ** ** <p>Most of the SQLITE_DBCONFIG options take two arguments, so that the ** overall call to [sqlite3_db_config()] has a total of four parameters. ** The first argument (the third parameter to sqlite3_db_config()) is a integer. ** The second argument is a pointer to an integer. If the first argument is 1, ** then the option becomes enabled. If the first integer argument is 0, then the ** option is disabled. If the first argument is -1, then the option setting ** is unchanged. The second argument, the pointer to an integer, may be NULL. ** If the second argument is not NULL, then a value of 0 or 1 is written into ** the integer to which the second argument points, depending on whether the ** setting is disabled or enabled after applying any changes specified by ** the first argument. ** ** <p>While most SQLITE_DBCONFIG options use the argument format ** described in the previous paragraph, the [SQLITE_DBCONFIG_MAINDBNAME] ** and [SQLITE_DBCONFIG_LOOKASIDE] options are different. See the ** documentation of those exceptional options for details. */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005 /* int int* */ |
| ︙ | ︙ | |||
2541 2542 2543 2544 2545 2546 2547 | #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ #define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ #define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ | > > > | | 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 | #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ #define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ #define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE 1020 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE 1021 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_COMMENTS 1022 /* int int* */ #define SQLITE_DBCONFIG_MAX 1022 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes ** METHOD: sqlite3 ** ** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result |
| ︙ | ︙ | |||
10744 10745 10746 10747 10748 10749 10750 | ** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Serialize a database ** | | | > | 10860 10861 10862 10863 10864 10865 10866 10867 10868 10869 10870 10871 10872 10873 10874 10875 10876 | ** [SQLITE_ENABLE_SNAPSHOT] option. */ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Serialize a database ** ** The sqlite3_serialize(D,S,P,F) interface returns a pointer to ** memory that is a serialization of the S database on ** [database connection] D. If S is a NULL pointer, the main database is used. ** If P is not a NULL pointer, then the size of the database in bytes ** is written into *P. ** ** For an ordinary on-disk database file, the serialization is just a ** copy of the disk file. For an in-memory database or a "TEMP" database, ** the serialization is the same sequence of bytes which would be written ** to disk if that database where backed up to disk. |
| ︙ | ︙ | |||
11911 11912 11913 11914 11915 11916 11917 | int nA, /* Number of bytes in buffer pA */ void *pA, /* Pointer to buffer containing changeset A */ int nB, /* Number of bytes in buffer pB */ void *pB, /* Pointer to buffer containing changeset B */ int *pnOut, /* OUT: Number of bytes in output changeset */ void **ppOut /* OUT: Buffer containing output changeset */ ); | < < < < < < < < < < < < < | 12028 12029 12030 12031 12032 12033 12034 12035 12036 12037 12038 12039 12040 12041 | int nA, /* Number of bytes in buffer pA */ void *pA, /* Pointer to buffer containing changeset A */ int nB, /* Number of bytes in buffer pB */ void *pB, /* Pointer to buffer containing changeset B */ int *pnOut, /* OUT: Number of bytes in output changeset */ void **ppOut /* OUT: Buffer containing output changeset */ ); /* ** CAPI3REF: Changegroup Handle ** ** A changegroup is an object used to combine two or more ** [changesets] or [patchsets] */ |
| ︙ | ︙ |
Changes to skins/darkmode/css.txt.
| ︙ | ︙ | |||
96 97 98 99 100 101 102 103 104 105 |
color: rgba(24,24,24,0.8);
border-radius: 0.1em;
}
.fileage tr:hover,
div.filetreeline:hover {
background-color: #333;
}
.button,
button {
color: #aaa;
| > > > | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
color: rgba(24,24,24,0.8);
border-radius: 0.1em;
}
.fileage tr:hover,
div.filetreeline:hover {
background-color: #333;
}
div.file-change-line button {
background-color: #484848
}
.button,
button {
color: #aaa;
background-color: #484848;
border-radius: 5px;
border: 0
}
.button:hover,
button:hover {
background-color: #FF4500f0;
color: rgba(24,24,24,0.8);
|
| ︙ | ︙ |
Changes to skins/eagle/css.txt.
| ︙ | ︙ | |||
178 179 180 181 182 183 184 |
/* the format for the timeline data table */
table.timelineTable {
cellspacing: 0;
border: 0;
cellpadding: 0;
font-family: "courier new";
border-spacing: 0px 2px;
| | | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
/* the format for the timeline data table */
table.timelineTable {
cellspacing: 0;
border: 0;
cellpadding: 0;
font-family: "courier new";
border-spacing: 0px 2px;
/* border-collapse: collapse; */
}
.timelineSelected {
background-color: #7EA2D9;
}
.timelineSecondary {
background-color: #7EA27E;
|
| ︙ | ︙ |
Changes to src/add.c.
| ︙ | ︙ | |||
351 352 353 354 355 356 357 | ** ** The --ignore and --clean options are comma-separated lists of glob patterns ** for files to be excluded. Example: '*.o,*.obj,*.exe' If the --ignore ** option does not appear on the command line then the "ignore-glob" setting ** is used. If the --clean option does not appear on the command line then ** the "clean-glob" setting is used. ** | | | 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | ** ** The --ignore and --clean options are comma-separated lists of glob patterns ** for files to be excluded. Example: '*.o,*.obj,*.exe' If the --ignore ** option does not appear on the command line then the "ignore-glob" setting ** is used. If the --clean option does not appear on the command line then ** the "clean-glob" setting is used. ** ** When attempting to explicitly add files on the commandline, and if those ** match "ignore-glob", a confirmation is asked first. This can be prevented ** using the -f|--force option. ** ** The --case-sensitive option determines whether or not filenames should ** be treated case sensitive or not. If the option is not given, the default ** depends on the global setting, or the operating system default, if not set. ** |
| ︙ | ︙ | |||
751 752 753 754 755 756 757 | ** all files displayed using the "extras" command) are added as ** if by the "[[add]]" command. ** ** * All files in the repository but missing from the check-out (that is, ** all files that show as MISSING with the "status" command) are ** removed as if by the "[[rm]]" command. ** | < | | 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | ** all files displayed using the "extras" command) are added as ** if by the "[[add]]" command. ** ** * All files in the repository but missing from the check-out (that is, ** all files that show as MISSING with the "status" command) are ** removed as if by the "[[rm]]" command. ** ** Note that this command does not "commit", as that is a separate step. ** ** Files and directories whose names begin with "." are ignored unless ** the --dotfiles option is used. ** ** The --ignore option overrides the "ignore-glob" setting, as do the ** --case-sensitive option with the "case-sensitive" setting and the ** --clean option with the "clean-glob" setting. See the documentation |
| ︙ | ︙ |
Changes to src/backoffice.c.
| ︙ | ︙ | |||
689 690 691 692 693 694 695 | ** ** --min N When polling, invoke backoffice at least ** once every N seconds even if the repository ** never changes. 0 or negative means disable ** this feature. Default: 3600 (once per hour). ** ** --poll N Repeat backoffice calls for repositories that | | | 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 | ** ** --min N When polling, invoke backoffice at least ** once every N seconds even if the repository ** never changes. 0 or negative means disable ** this feature. Default: 3600 (once per hour). ** ** --poll N Repeat backoffice calls for repositories that ** change in approximately N-second intervals. ** N less than 1 turns polling off (the default). ** Recommended polling interval: 60 seconds. ** ** --trace Enable debugging output on stderr ** ** Options intended for internal use only which may change or be ** discontinued in future releases: |
| ︙ | ︙ |
Changes to src/bisect.c.
| ︙ | ︙ | |||
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 |
** Append a new skip entry to the bisect log.
*/
static void bisect_append_skip(int rid){
db_multi_exec(
"UPDATE vvar SET value=value||' s%d' WHERE name='bisect-log'", rid
);
}
/*
** Create a TEMP table named "bilog" that contains the complete history
** of the current bisect.
**
** If iCurrent>0 then it is the RID of the current check-out and is included
** in the history table.
**
** If zDesc is not NULL, then it is the bid= query parameter to /timeline
** that describes a bisect. Use the information in zDesc rather than in
** the bisect-log variable.
**
** If bDetail is true, then also include information about every node
** in between the inner-most GOOD and BAD nodes.
*/
int bisect_create_bilog_table(int iCurrent, const char *zDesc, int bDetail){
char *zLog;
Blob log, id;
| > > > > > > > > > > > > > > > > < > | 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 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
** Append a new skip entry to the bisect log.
*/
static void bisect_append_skip(int rid){
db_multi_exec(
"UPDATE vvar SET value=value||' s%d' WHERE name='bisect-log'", rid
);
}
/*
** Append a VALUES entry to the bilog table insert
*/
static void bisect_log_append(Blob *pSql,int iSeq,const char *zStat,int iRid){
if( (iSeq%6)==3 ){
blob_append_sql(pSql, ",\n ");
}else if( iSeq>1 ){
blob_append_sql(pSql, ",");
}
if( zStat ){
blob_append_sql(pSql, "(%d,%Q,%d)", iSeq, zStat, iRid);
}else{
blob_append_sql(pSql, "(NULL,NULL,%d)", iRid);
}
}
/*
** Create a TEMP table named "bilog" that contains the complete history
** of the current bisect.
**
** If iCurrent>0 then it is the RID of the current check-out and is included
** in the history table.
**
** If zDesc is not NULL, then it is the bid= query parameter to /timeline
** that describes a bisect. Use the information in zDesc rather than in
** the bisect-log variable.
**
** If bDetail is true, then also include information about every node
** in between the inner-most GOOD and BAD nodes.
*/
int bisect_create_bilog_table(int iCurrent, const char *zDesc, int bDetail){
char *zLog;
Blob log, id;
int cnt = 0;
int lastGood = -1;
int lastBad = -1;
Blob ins = BLOB_INITIALIZER;
if( zDesc!=0 ){
blob_init(&log, 0, 0);
while( zDesc[0]=='y' || zDesc[0]=='n' || zDesc[0]=='s' ){
int i;
char c;
int rid;
|
| ︙ | ︙ | |||
251 252 253 254 255 256 257 |
db_multi_exec(
"CREATE TEMP TABLE bilog("
" rid INTEGER PRIMARY KEY," /* Sequence of events */
" stat TEXT," /* Type of occurrence */
" seq INTEGER UNIQUE" /* Check-in number */
");"
);
| | < | | < | < < | < < < | < < < < < | < < | > | 267 268 269 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 |
db_multi_exec(
"CREATE TEMP TABLE bilog("
" rid INTEGER PRIMARY KEY," /* Sequence of events */
" stat TEXT," /* Type of occurrence */
" seq INTEGER UNIQUE" /* Check-in number */
");"
);
blob_append_sql(&ins, "INSERT OR IGNORE INTO bilog(seq,stat,rid) VALUES");
while( blob_token(&log, &id) ){
int rid;
cnt++;
if( blob_str(&id)[0]=='s' ){
rid = atoi(blob_str(&id)+1);
bisect_log_append(&ins, cnt, "SKIP", rid);
}else{
rid = atoi(blob_str(&id));
if( rid>0 ){
bisect_log_append(&ins, cnt, "GOOD", rid);
lastGood = rid;
}else{
bisect_log_append(&ins, cnt, "BAD", -rid);
lastBad = -rid;
}
}
}
if( iCurrent>0 ){
bisect_log_append(&ins, ++cnt, "CURRENT", iCurrent);
}
if( bDetail && lastGood>0 && lastBad>0 ){
PathNode *p;
p = path_shortest(lastGood, lastBad, bisect_option("direct-only"),0, 0);
while( p ){
bisect_log_append(&ins, ++cnt, 0, p->rid);
p = p->u.pTo;
}
path_reset();
}
db_exec_sql(blob_sql_text(&ins));
blob_reset(&ins);
return 1;
}
/* Return a permalink description of a bisect. Space is obtained from
** fossil_malloc() and should be freed by the caller.
**
** A bisect description consists of characters 'y' and 'n' and lowercase
|
| ︙ | ︙ | |||
541 542 543 544 545 546 547 | ** be done, for example, because VERSION does not compile correctly ** or is otherwise unsuitable to participate in this bisect. ** ** > fossil bisect vlist|ls|status ?-a|--all? ** ** List the versions in between the inner-most "bad" and "good". ** | | | > > | 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 |
** be done, for example, because VERSION does not compile correctly
** or is otherwise unsuitable to participate in this bisect.
**
** > fossil bisect vlist|ls|status ?-a|--all?
**
** List the versions in between the inner-most "bad" and "good".
**
** > fossil bisect ui ?HOST@USER:PATH?
**
** Like "fossil ui" except start on a timeline that shows only the
** check-ins that are part of the current bisect. If the optional
** fourth term is added, then information is shown for the bisect that
** occurred in the PATH directory by USER on remote machine HOST.
**
** > fossil bisect undo
**
** Undo the most recent "good", "bad", or "skip" command.
*/
void bisect_cmd(void){
int n;
|
| ︙ | ︙ | |||
717 718 719 720 721 722 723 724 725 726 727 |
}else{
usage("options ?NAME? ?VALUE?");
}
}else if( strncmp(zCmd, "reset", n)==0 ){
bisect_reset();
}else if( strcmp(zCmd, "ui")==0 ){
char *newArgv[8];
newArgv[0] = g.argv[0];
newArgv[1] = "ui";
newArgv[2] = "--page";
newArgv[3] = "timeline?bisect";
| > > | | > | > > > | 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 |
}else{
usage("options ?NAME? ?VALUE?");
}
}else if( strncmp(zCmd, "reset", n)==0 ){
bisect_reset();
}else if( strcmp(zCmd, "ui")==0 ){
char *newArgv[8];
verify_all_options();
newArgv[0] = g.argv[0];
newArgv[1] = "ui";
newArgv[2] = "--page";
newArgv[3] = "timeline?bisect";
if( g.argc==4 ){
newArgv[4] = g.argv[3];
g.argc = 5;
}else{
g.argc = 4;
}
newArgv[g.argc] = 0;
g.argv = newArgv;
cmd_webserver();
}else if( strncmp(zCmd, "vlist", n)==0
|| strncmp(zCmd, "ls", n)==0
|| strncmp(zCmd, "status", n)==0
){
int fAll = find_option("all", "a", 0)!=0;
bisect_list(!fAll);
}else if( !foundCmd ){
usage:
usage("bad|good|log|chart|next|options|reset|run|skip|status|ui|undo");
}
}
|
Changes to src/branch.c.
| ︙ | ︙ | |||
638 639 640 641 642 643 644 | ** -c|--closed List closed branches ** -m|--merged List branches merged into the current branch ** -M|--unmerged List branches not merged into the current branch ** -p List only private branches ** -r Reverse the sort order ** -t Show recently changed branches first ** --self List only branches where you participate | | | | 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 | ** -c|--closed List closed branches ** -m|--merged List branches merged into the current branch ** -M|--unmerged List branches not merged into the current branch ** -p List only private branches ** -r Reverse the sort order ** -t Show recently changed branches first ** --self List only branches where you participate ** --username USER List only branches where USER participates ** --users N List up to N users participating ** ** The current branch is marked with an asterisk. Private branches are ** marked with a hash sign. ** ** If GLOB is given, show only branches matching the pattern. ** ** The "lsh" variant of this subcommand shows recently changed branches, |
| ︙ | ︙ |
Changes to src/cgi.c.
| ︙ | ︙ | |||
1776 1777 1778 1779 1780 1781 1782 |
*/
void cgi_load_environment(void){
/* The following is a list of environment variables that Fossil considers
** to be "relevant". */
static const char *const azCgiVars[] = {
"COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE", "SCGI",
"HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET", "HTTP_ACCEPT_ENCODING",
| | | 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 |
*/
void cgi_load_environment(void){
/* The following is a list of environment variables that Fossil considers
** to be "relevant". */
static const char *const azCgiVars[] = {
"COMSPEC", "DOCUMENT_ROOT", "GATEWAY_INTERFACE", "SCGI",
"HTTP_ACCEPT", "HTTP_ACCEPT_CHARSET", "HTTP_ACCEPT_ENCODING",
"HTTP_ACCEPT_LANGUAGE", "HTTP_AUTHENTICATION",
"HTTP_CONNECTION", "HTTP_HOST",
"HTTP_IF_NONE_MATCH", "HTTP_IF_MODIFIED_SINCE",
"HTTP_USER_AGENT", "HTTP_REFERER", "PATH_INFO", "PATH_TRANSLATED",
"QUERY_STRING", "REMOTE_ADDR", "REMOTE_PORT",
"REMOTE_USER", "REQUEST_METHOD", "REQUEST_SCHEME",
"REQUEST_URI", "SCRIPT_FILENAME", "SCRIPT_NAME", "SERVER_NAME",
"SERVER_PROTOCOL", "HOME", "FOSSIL_HOME", "USERNAME", "USER",
|
| ︙ | ︙ |
Changes to src/checkin.c.
| ︙ | ︙ | |||
1561 1562 1563 1564 1565 1566 1567 |
diffFiles[0].zName[0] = '.';
diffFiles[0].zName[1] = 0;
break;
}
diffFiles[i].nName = strlen(diffFiles[i].zName);
diffFiles[i].nUsed = 0;
}
| | | | 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 |
diffFiles[0].zName[0] = '.';
diffFiles[0].zName[1] = 0;
break;
}
diffFiles[i].nName = strlen(diffFiles[i].zName);
diffFiles[i].nUsed = 0;
}
diff_version_to_checkout(0, &DCfg, diffFiles, &prompt);
for( i=0; diffFiles[i].zName; ++i ){
fossil_free(diffFiles[i].zName);
}
fossil_free(diffFiles);
}else{
diff_version_to_checkout(0, &DCfg, 0, &prompt);
}
}
prompt_for_user_comment(pComment, &prompt);
blob_reset(&prompt);
}
/*
|
| ︙ | ︙ | |||
2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 | ** --branch NEW-BRANCH-NAME Check in to this new branch ** --branchcolor COLOR Apply given COLOR to the branch ** --close Close the branch being committed ** --date-override DATETIME DATE to use instead of 'now' ** --delta Use a delta manifest in the commit process ** --hash Verify file status using hashing rather ** than relying on file mtimes ** --ignore-clock-skew If a clock skew is detected, ignore it and ** behave as if the user had entered 'yes' to ** the question of whether to proceed despite ** the skew. ** --ignore-oversize Do not warn the user about oversized files ** --integrate Close all merged-in branches ** -m|--comment COMMENT-TEXT Use COMMENT-TEXT as commit comment | > > | 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 | ** --branch NEW-BRANCH-NAME Check in to this new branch ** --branchcolor COLOR Apply given COLOR to the branch ** --close Close the branch being committed ** --date-override DATETIME DATE to use instead of 'now' ** --delta Use a delta manifest in the commit process ** --hash Verify file status using hashing rather ** than relying on file mtimes ** --if-changes Make this command a silent no-op if there ** are no changes ** --ignore-clock-skew If a clock skew is detected, ignore it and ** behave as if the user had entered 'yes' to ** the question of whether to proceed despite ** the skew. ** --ignore-oversize Do not warn the user about oversized files ** --integrate Close all merged-in branches ** -m|--comment COMMENT-TEXT Use COMMENT-TEXT as commit comment |
| ︙ | ︙ | |||
2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 | int bTrace = 0; /* Debug tracing */ int noPrompt = 0; /* True if skipping all prompts */ int forceFlag = 0; /* Undocumented: Disables all checks */ int forceDelta = 0; /* Force a delta-manifest */ int forceBaseline = 0; /* Force a baseline-manifest */ int allowConflict = 0; /* Allow unresolve merge conflicts */ int allowEmpty = 0; /* Allow a commit with no changes */ int allowFork = 0; /* Allow the commit to fork */ int allowOlder = 0; /* Allow a commit older than its ancestor */ char *zManifestFile; /* Name of the manifest file */ int useCksum; /* True if checksums should be computed and verified */ int outputManifest; /* True to output "manifest" and "manifest.uuid" */ int dryRunFlag; /* True for a test run. Debugging only */ CheckinInfo sCiInfo; /* Information about this check-in */ | > | 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 | int bTrace = 0; /* Debug tracing */ int noPrompt = 0; /* True if skipping all prompts */ int forceFlag = 0; /* Undocumented: Disables all checks */ int forceDelta = 0; /* Force a delta-manifest */ int forceBaseline = 0; /* Force a baseline-manifest */ int allowConflict = 0; /* Allow unresolve merge conflicts */ int allowEmpty = 0; /* Allow a commit with no changes */ int onlyIfChanges = 0; /* No-op if there are no changes */ int allowFork = 0; /* Allow the commit to fork */ int allowOlder = 0; /* Allow a commit older than its ancestor */ char *zManifestFile; /* Name of the manifest file */ int useCksum; /* True if checksums should be computed and verified */ int outputManifest; /* True to output "manifest" and "manifest.uuid" */ int dryRunFlag; /* True for a test run. Debugging only */ CheckinInfo sCiInfo; /* Information about this check-in */ |
| ︙ | ︙ | |||
2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 |
if( !dryRunFlag ){
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
}
zComment = find_option("comment","m",1);
forceFlag = find_option("force", "f", 0)!=0;
allowConflict = find_option("allow-conflict",0,0)!=0;
allowEmpty = find_option("allow-empty",0,0)!=0;
allowFork = find_option("allow-fork",0,0)!=0;
if( find_option("override-lock",0,0)!=0 ) allowFork = 1;
allowOlder = find_option("allow-older",0,0)!=0;
noPrompt = find_option("no-prompt", 0, 0)!=0;
noWarningFlag = find_option("no-warnings", 0, 0)!=0;
noVerify = find_option("no-verify",0,0)!=0;
bTrace = find_option("trace",0,0)!=0;
| > | 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 |
if( !dryRunFlag ){
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
}
zComment = find_option("comment","m",1);
forceFlag = find_option("force", "f", 0)!=0;
allowConflict = find_option("allow-conflict",0,0)!=0;
allowEmpty = find_option("allow-empty",0,0)!=0;
onlyIfChanges = find_option("if-changes",0,0)!=0;
allowFork = find_option("allow-fork",0,0)!=0;
if( find_option("override-lock",0,0)!=0 ) allowFork = 1;
allowOlder = find_option("allow-older",0,0)!=0;
noPrompt = find_option("no-prompt", 0, 0)!=0;
noWarningFlag = find_option("no-warnings", 0, 0)!=0;
noVerify = find_option("no-verify",0,0)!=0;
bTrace = find_option("trace",0,0)!=0;
|
| ︙ | ︙ | |||
2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 |
/* Escape special characters in tags and put all tags in sorted order */
if( nTag ){
int i;
for(i=0; i<nTag; i++) sCiInfo.azTag[i] = mprintf("%F", sCiInfo.azTag[i]);
qsort((void*)sCiInfo.azTag, nTag, sizeof(sCiInfo.azTag[0]), tagCmp);
}
/*
** Autosync if autosync is enabled and this is not a private check-in.
*/
if( !g.markPrivate ){
int syncFlags = SYNC_PULL;
if( vid!=0 && !allowFork && !forceFlag ){
| > > > > > > | 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 |
/* Escape special characters in tags and put all tags in sorted order */
if( nTag ){
int i;
for(i=0; i<nTag; i++) sCiInfo.azTag[i] = mprintf("%F", sCiInfo.azTag[i]);
qsort((void*)sCiInfo.azTag, nTag, sizeof(sCiInfo.azTag[0]), tagCmp);
}
hasChanges = unsaved_changes(useHash ? CKSIG_HASH : 0);
if( hasChanges==0 && onlyIfChanges ){
/* "fossil commit --if-changes" is a no-op if there are no changes. */
return;
}
/*
** Autosync if autosync is enabled and this is not a private check-in.
*/
if( !g.markPrivate ){
int syncFlags = SYNC_PULL;
if( vid!=0 && !allowFork && !forceFlag ){
|
| ︙ | ︙ | |||
2684 2685 2686 2687 2688 2689 2690 |
const char *zTo = db_column_text(&q, 1);
fossil_fatal("cannot do a partial commit of '%s' without '%s' because "
"'%s' was renamed to '%s'", zFrom, zTo, zFrom, zTo);
}
db_finalize(&q);
}
| < | 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 |
const char *zTo = db_column_text(&q, 1);
fossil_fatal("cannot do a partial commit of '%s' without '%s' because "
"'%s' was renamed to '%s'", zFrom, zTo, zFrom, zTo);
}
db_finalize(&q);
}
db_begin_transaction();
db_record_repository_filename(0);
if( hasChanges==0 && !isAMerge && !allowEmpty && !forceFlag ){
fossil_fatal("nothing has changed; use --allow-empty to override");
}
/* If none of the files that were named on the command line have
|
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
169 170 171 172 173 174 175 |
** the text of the manifest and the artifact ID of the manifest.
** If the manifest setting is set, but is not a boolean value, then treat
** each character as a flag to enable writing "manifest", "manifest.uuid" or
** "manifest.tags".
*/
void manifest_to_disk(int vid){
char *zManFile;
| < < | > | 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 |
** the text of the manifest and the artifact ID of the manifest.
** If the manifest setting is set, but is not a boolean value, then treat
** each character as a flag to enable writing "manifest", "manifest.uuid" or
** "manifest.tags".
*/
void manifest_to_disk(int vid){
char *zManFile;
int flg;
flg = db_get_manifest_setting();
if( flg & MFESTFLG_RAW ){
Blob manifest = BLOB_INITIALIZER;
content_get(vid, &manifest);
sterilize_manifest(&manifest, CFTYPE_MANIFEST);
zManFile = mprintf("%smanifest", g.zLocalRoot);
blob_write_to_file(&manifest, zManFile);
free(zManFile);
blob_reset(&manifest);
}else{
if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){
zManFile = mprintf("%smanifest", g.zLocalRoot);
file_delete(zManFile);
free(zManFile);
}
}
|
| ︙ | ︙ | |||
205 206 207 208 209 210 211 |
if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
file_delete(zManFile);
free(zManFile);
}
}
if( flg & MFESTFLG_TAGS ){
| | | 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
file_delete(zManFile);
free(zManFile);
}
}
if( flg & MFESTFLG_TAGS ){
Blob taglist = BLOB_INITIALIZER;
zManFile = mprintf("%smanifest.tags", g.zLocalRoot);
get_checkin_taglist(vid, &taglist);
blob_write_to_file(&taglist, zManFile);
free(zManFile);
blob_reset(&taglist);
}else{
if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.tags'") ){
|
| ︙ | ︙ |
Changes to src/clearsign.c.
| ︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
** pOut.
*/
int clearsign(Blob *pIn, Blob *pOut){
char *zRand;
char *zIn;
char *zOut;
char *zBase = db_get("pgp-command", "gpg --clearsign -o ");
char *zCmd;
int rc;
if( is_false(zBase) ){
return 0;
}
zRand = db_text(0, "SELECT hex(randomblob(10))");
zOut = mprintf("out-%s", zRand);
| > < > > > > > > | > > > > > > > > > > > > > > > > | > | 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 73 74 75 76 77 78 79 80 81 |
** pOut.
*/
int clearsign(Blob *pIn, Blob *pOut){
char *zRand;
char *zIn;
char *zOut;
char *zBase = db_get("pgp-command", "gpg --clearsign -o ");
int useSsh = 0;
char *zCmd;
int rc;
if( is_false(zBase) ){
return 0;
}
zRand = db_text(0, "SELECT hex(randomblob(10))");
zOut = mprintf("out-%s", zRand);
blob_write_to_file(pIn, zOut);
useSsh = (fossil_strncmp(command_basename(zBase), "ssh", 3)==0);
if( useSsh ){
zIn = mprintf("out-%s.sig", zRand);
zCmd = mprintf("%s %s", zBase, zOut);
}else{
zIn = mprintf("in-%z", zRand);
zCmd = mprintf("%s %s %s", zBase, zIn, zOut);
}
rc = fossil_system(zCmd);
free(zCmd);
if( rc==0 ){
if( pOut==pIn ){
blob_reset(pIn);
}
blob_zero(pOut);
if( useSsh ){
/* As of 2025, SSH cannot create non-detached SSH signatures */
/* We put one together */
Blob tmpBlob;
blob_zero(&tmpBlob);
blob_read_from_file(&tmpBlob, zOut, ExtFILE);
/* Add armor header line and manifest */
blob_appendf(pOut, "%s", "-----BEGIN SSH SIGNED MESSAGE-----\n\n");
blob_appendf(pOut, "%s", blob_str(&tmpBlob));
blob_zero(&tmpBlob);
blob_read_from_file(&tmpBlob, zIn, ExtFILE);
/* Add signature - already armored by SSH */
blob_appendf(pOut, "%s", blob_str(&tmpBlob));
}else{
/* Assume that the external command creates non-detached signatures */
blob_read_from_file(pOut, zIn, ExtFILE);
}
}else{
if( pOut!=pIn ){
blob_copy(pOut, pIn);
}
}
file_delete(zOut);
file_delete(zIn);
|
| ︙ | ︙ |
Changes to src/content.c.
| ︙ | ︙ | |||
944 945 946 947 948 949 950 951 952 953 954 955 956 957 |
** Return true if Blob p looks like it might be a parsable control artifact.
*/
static int looks_like_control_artifact(Blob *p){
const char *z = blob_buffer(p);
int n = blob_size(p);
if( n<10 ) return 0;
if( strncmp(z, "-----BEGIN PGP SIGNED MESSAGE-----", 34)==0 ) return 1;
if( z[0]<'A' || z[0]>'Z' || z[1]!=' ' || z[0]=='I' ) return 0;
if( z[n-1]!='\n' ) return 0;
return 1;
}
/*
** COMMAND: test-integrity
| > | 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 |
** Return true if Blob p looks like it might be a parsable control artifact.
*/
static int looks_like_control_artifact(Blob *p){
const char *z = blob_buffer(p);
int n = blob_size(p);
if( n<10 ) return 0;
if( strncmp(z, "-----BEGIN PGP SIGNED MESSAGE-----", 34)==0 ) return 1;
if( strncmp(z, "-----BEGIN SSH SIGNED MESSAGE-----", 34)==0 ) return 1;
if( z[0]<'A' || z[0]>'Z' || z[1]!=' ' || z[0]=='I' ) return 0;
if( z[n-1]!='\n' ) return 0;
return 1;
}
/*
** COMMAND: test-integrity
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
int iStartLine; /* Line of zStartFile where transaction started */
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
void *pAuthArg; /* Argument to the authorizer */
const char *zAuthName; /* Name of the authorizer */
int bProtectTriggers; /* True if protection triggers already exist */
int nProtect; /* Slots of aProtect used */
unsigned aProtect[12]; /* Saved values of protectMask */
} db = {
PROTECT_USER|PROTECT_CONFIG|PROTECT_BASELINE, /* protectMask */
0, 0, 0, 0, 0, 0, 0, {{0}}, {0}, {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}};
/*
** Arrange for the given file to be deleted on a failure.
*/
| > > | 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
int iStartLine; /* Line of zStartFile where transaction started */
int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
void *pAuthArg; /* Argument to the authorizer */
const char *zAuthName; /* Name of the authorizer */
int bProtectTriggers; /* True if protection triggers already exist */
int nProtect; /* Slots of aProtect used */
unsigned aProtect[12]; /* Saved values of protectMask */
int pauseDmlLog; /* Ignore pDmlLog if positive */
Blob *pDmlLog; /* Append DML statements here, of not NULL */
} db = {
PROTECT_USER|PROTECT_CONFIG|PROTECT_BASELINE, /* protectMask */
0, 0, 0, 0, 0, 0, 0, {{0}}, {0}, {0}, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0}};
/*
** Arrange for the given file to be deleted on a failure.
*/
|
| ︙ | ︙ | |||
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 |
/*
** Possible flags to db_vprepare
*/
#define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */
#define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */
#endif
/*
** Prepare a Stmt. Assume that the Stmt is previously uninitialized.
** If the input string contains multiple SQL statements, only the first
** one is processed. All statements beyond the first are silently ignored.
*/
int db_vprepare(Stmt *pStmt, int flags, const char *zFormat, va_list ap){
int rc;
int prepFlags = 0;
char *zSql;
const char *zExtra = 0;
blob_zero(&pStmt->sql);
blob_vappendf(&pStmt->sql, zFormat, ap);
va_end(ap);
zSql = blob_str(&pStmt->sql);
db.nPrepare++;
if( flags & DB_PREPARE_PERSISTENT ){
prepFlags = SQLITE_PREPARE_PERSISTENT;
}
rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, &zExtra);
if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)==0 ){
db_err("%s\n%s", sqlite3_errmsg(g.db), zSql);
}else if( zExtra && !fossil_all_whitespace(zExtra) ){
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 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 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 |
/*
** Possible flags to db_vprepare
*/
#define DB_PREPARE_IGNORE_ERROR 0x001 /* Suppress errors */
#define DB_PREPARE_PERSISTENT 0x002 /* Stmt will stick around for a while */
#endif
/*
** If zSql is a DML statement, append it db.pDmlLog.
*/
static void db_append_dml(const char *zSql){
size_t nSql;
if( db.pDmlLog==0 ) return;
if( db.pauseDmlLog ) return;
if( zSql==0 ) return;
nSql = strlen(zSql);
while( nSql>0 && fossil_isspace(zSql[0]) ){ nSql--; zSql++; }
while( nSql>0 && fossil_isspace(zSql[nSql-1]) ) nSql--;
if( nSql<6 ) return;
if( fossil_strnicmp(zSql, "SELECT", 6)==0 ) return;
if( fossil_strnicmp(zSql, "PRAGMA", 6)==0 ) return;
blob_append(db.pDmlLog, zSql, nSql);
if( zSql[nSql-1]!=';' ) blob_append_char(db.pDmlLog, ';');
blob_append_char(db.pDmlLog, '\n');
}
/*
** Set the Blob to which DML statement text should be appended. Set it
** to zero to stop appending DML statement text.
*/
void db_append_dml_to_blob(Blob *pBlob){
db.pDmlLog = pBlob;
}
/*
** Pause or unpause the DML log
*/
void db_pause_dml_log(void){ db.pauseDmlLog++; }
void db_unpause_dml_log(void){ db.pauseDmlLog--; }
/*
** Prepare a Stmt. Assume that the Stmt is previously uninitialized.
** If the input string contains multiple SQL statements, only the first
** one is processed. All statements beyond the first are silently ignored.
*/
int db_vprepare(Stmt *pStmt, int flags, const char *zFormat, va_list ap){
int rc;
int prepFlags = 0;
char *zSql;
const char *zExtra = 0;
blob_zero(&pStmt->sql);
blob_vappendf(&pStmt->sql, zFormat, ap);
va_end(ap);
zSql = blob_str(&pStmt->sql);
db.nPrepare++;
db_append_dml(zSql);
if( flags & DB_PREPARE_PERSISTENT ){
prepFlags = SQLITE_PREPARE_PERSISTENT;
}
rc = sqlite3_prepare_v3(g.db, zSql, -1, prepFlags, &pStmt->pStmt, &zExtra);
if( rc!=0 && (flags & DB_PREPARE_IGNORE_ERROR)==0 ){
db_err("%s\n%s", sqlite3_errmsg(g.db), zSql);
}else if( zExtra && !fossil_all_whitespace(zExtra) ){
|
| ︙ | ︙ | |||
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 |
while( rc==SQLITE_OK && z[0] ){
pStmt = 0;
rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd);
if( rc ){
db_err("%s: {%s}", sqlite3_errmsg(g.db), z);
}else if( pStmt ){
db.nPrepare++;
while( sqlite3_step(pStmt)==SQLITE_ROW ){}
rc = sqlite3_finalize(pStmt);
if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z);
}
z = zEnd;
}
return rc;
| > | 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 |
while( rc==SQLITE_OK && z[0] ){
pStmt = 0;
rc = sqlite3_prepare_v2(g.db, z, -1, &pStmt, &zEnd);
if( rc ){
db_err("%s: {%s}", sqlite3_errmsg(g.db), z);
}else if( pStmt ){
db.nPrepare++;
db_append_dml(sqlite3_sql(pStmt));
while( sqlite3_step(pStmt)==SQLITE_ROW ){}
rc = sqlite3_finalize(pStmt);
if( rc ) db_err("%s: {%.*s}", sqlite3_errmsg(g.db), (int)(zEnd-z), z);
}
z = zEnd;
}
return rc;
|
| ︙ | ︙ | |||
1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 |
sqlite3_result_null(context);
}else{
sqlite3_result_int64(context, rid);
}
}
}
/*
** The toLocal() SQL function returns a string that is an argument to a
** date/time function that is appropriate for modifying the time for display.
** If UTC time display is selected, no modification occurs. If local time
** display is selected, the time is adjusted appropriately.
**
** Example usage:
**
** SELECT datetime('now',toLocal());
*/
void db_tolocal_function(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < < < < < | 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 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 |
sqlite3_result_null(context);
}else{
sqlite3_result_int64(context, rid);
}
}
}
/*
** SETTING: timeline-utc boolean default=on
**
** If the timeline-utc setting is true, then Fossil tries to understand
** and display all time values using UTC. If this setting is false, Fossil
** tries to understand and display time values using the local timezone.
**
** The word "timeline" in the name of this setting is historical.
** This setting applies to all user interfaces of Fossil,
** not just the timeline.
**
** Note that when accessing Fossil using the web interface, the localtime
** used is the localtime on the server, not on the client.
*/
/*
** Return true if Fossil is set to display times as UTC. Return false
** if it wants to display times using the local timezone.
**
** False is returned if display is set to localtime even if the localtime
** happens to be the same as UTC.
*/
int fossil_ui_utctime(void){
if( g.fTimeFormat==0 ){
if( db_get_int("timeline-utc", 1) ){
g.fTimeFormat = 1; /* UTC */
}else{
g.fTimeFormat = 2; /* Localtime */
}
}
return g.fTimeFormat==1;
}
/*
** Return true if Fossil is set to display times using the local timezone.
*/
int fossil_ui_localtime(void){
return fossil_ui_utctime()==0;
}
/*
** The toLocal() SQL function returns a string that is an argument to a
** date/time function that is appropriate for modifying the time for display.
** If UTC time display is selected, no modification occurs. If local time
** display is selected, the time is adjusted appropriately.
**
** Example usage:
**
** SELECT datetime('now',toLocal());
*/
void db_tolocal_function(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
if( fossil_ui_utctime() ){
sqlite3_result_text(context, "0 seconds", -1, SQLITE_STATIC);
}else{
sqlite3_result_text(context, "localtime", -1, SQLITE_STATIC);
}
}
/*
|
| ︙ | ︙ | |||
1354 1355 1356 1357 1358 1359 1360 |
** SELECT julianday(:user_input,fromLocal());
*/
void db_fromlocal_function(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
| | < < < < < < < | 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 |
** SELECT julianday(:user_input,fromLocal());
*/
void db_fromlocal_function(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
if( fossil_ui_utctime() ){
sqlite3_result_text(context, "0 seconds", -1, SQLITE_STATIC);
}else{
sqlite3_result_text(context, "utc", -1, SQLITE_STATIC);
}
}
/*
|
| ︙ | ︙ | |||
1522 1523 1524 1525 1526 1527 1528 |
/*
** Register the SQL functions that are useful both to the internal
** representation and to the "fossil sql" command.
*/
void db_add_aux_functions(sqlite3 *db){
sqlite3_create_collation(db, "uintnocase", SQLITE_UTF8,0,uintNocaseCollFunc);
| | > | | > | | > | | > | > | | > | | > | | 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 |
/*
** Register the SQL functions that are useful both to the internal
** representation and to the "fossil sql" command.
*/
void db_add_aux_functions(sqlite3 *db){
sqlite3_create_collation(db, "uintnocase", SQLITE_UTF8,0,uintNocaseCollFunc);
sqlite3_create_function(db, "checkin_mtime", 2,
SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS,
0, db_checkin_mtime_function, 0, 0);
sqlite3_create_function(db, "symbolic_name_to_rid", 1,
SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS,
0, db_sym2rid_function, 0, 0);
sqlite3_create_function(db, "symbolic_name_to_rid", 2,
SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS,
0, db_sym2rid_function, 0, 0);
sqlite3_create_function(db, "now", 0,
SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
db_now_function, 0, 0);
sqlite3_create_function(db, "toLocal", 0,
SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS,
0, db_tolocal_function, 0, 0);
sqlite3_create_function(db, "fromLocal", 0,
SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS,
0, db_fromlocal_function, 0, 0);
sqlite3_create_function(db, "hextoblob", 1,
SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS,
0, db_hextoblob, 0, 0);
sqlite3_create_function(db, "capunion", 1, SQLITE_UTF8, 0,
0, capability_union_step, capability_union_finalize);
sqlite3_create_function(db, "fullcap", 1, SQLITE_UTF8, 0,
capability_fullcap, 0, 0);
sqlite3_create_function(db, "find_emailaddr", 1, SQLITE_UTF8, 0,
alert_find_emailaddr_func, 0, 0);
sqlite3_create_function(db, "display_name", 1, SQLITE_UTF8, 0,
|
| ︙ | ︙ | |||
2103 2104 2105 2106 2107 2108 2109 |
if( strcmp(blob_str(&bNameCheck), g.nameOfExe)==0 ){
extern int sqlite3_appendvfs_init(
sqlite3 *, char **, const sqlite3_api_routines *
);
sqlite3_appendvfs_init(0,0,0);
g.zVfsName = "apndvfs";
}
| | | 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 |
if( strcmp(blob_str(&bNameCheck), g.nameOfExe)==0 ){
extern int sqlite3_appendvfs_init(
sqlite3 *, char **, const sqlite3_api_routines *
);
sqlite3_appendvfs_init(0,0,0);
g.zVfsName = "apndvfs";
}
blob_reset(&bNameCheck);
rc = sqlite3_open_v2(
zDbName, &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
g.zVfsName
);
if( rc!=SQLITE_OK ){
db_err("[%s]: %s", zDbName, sqlite3_errmsg(db));
|
| ︙ | ︙ | |||
2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 |
sqlite3_finalize(pStmt);
sqlite3_close(db);
return res;
}
/*
** COMMAND: test-is-repo
*/
void test_is_repo(void){
int i;
for(i=2; i<g.argc; i++){
fossil_print("%s: %s\n",
db_looks_like_a_repository(g.argv[i]) ? "yes" : " no",
g.argv[i]
);
}
}
| > > > > > | 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 |
sqlite3_finalize(pStmt);
sqlite3_close(db);
return res;
}
/*
** COMMAND: test-is-repo
** Usage: %fossil test-is-repo FILENAME...
**
** Test whether the specified files look like a SQLite database
** containing a Fossil repository schema.
*/
void test_is_repo(void){
int i;
verify_all_options();
for(i=2; i<g.argc; i++){
fossil_print("%s: %s\n",
db_looks_like_a_repository(g.argv[i]) ? "yes" : " no",
g.argv[i]
);
}
}
|
| ︙ | ︙ | |||
4559 4560 4561 4562 4563 4564 4565 | ** that the "clean" command will delete without prompting or allowing ** undo. Example: *.a,*.o,*.so The parsing rules are complex; ** see https://fossil-scm.org/home/doc/trunk/www/globs.md#syntax */ /* ** SETTING: clearsign boolean default=off ** When enabled, fossil will attempt to sign all commits | | | 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 | ** that the "clean" command will delete without prompting or allowing ** undo. Example: *.a,*.o,*.so The parsing rules are complex; ** see https://fossil-scm.org/home/doc/trunk/www/globs.md#syntax */ /* ** SETTING: clearsign boolean default=off ** When enabled, fossil will attempt to sign all commits ** with gpg or ssh. When disabled, commits will be unsigned. */ /* ** SETTING: comment-format width=16 default=1 ** Set the default options for printing timeline comments to the console. ** ** The global --comfmtflags command-line option (or alias --comment-format) ** overrides this setting. |
| ︙ | ︙ | |||
4825 4826 4827 4828 4829 4830 4831 | ** the associated files within the check-out -AND- the "rm" ** and "delete" commands will also remove the associated ** files from within the check-out. */ /* ** SETTING: pgp-command width=40 sensitive ** Command used to clear-sign manifests at check-in. | | > | 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 | ** the associated files within the check-out -AND- the "rm" ** and "delete" commands will also remove the associated ** files from within the check-out. */ /* ** SETTING: pgp-command width=40 sensitive ** Command used to clear-sign manifests at check-in. ** Default value is "gpg --clearsign -o". ** For SSH, use e.g. "ssh-keygen -q -Y sign -n fossilscm -f ~/.ssh/id_ed25519" */ /* ** SETTING: proxy width=32 default=system ** URL of the HTTP proxy. If undefined or "system", the "http_proxy" ** environment variable is consulted. If "off", a direct HTTP connection is ** used. */ |
| ︙ | ︙ |
Changes to src/default.css.
| ︙ | ︙ | |||
746 747 748 749 750 751 752 753 754 755 756 757 758 759 |
}
body.tkt div.content ol.tkt-changes > li:target > p > span {
border-bottom: 3px solid gold;
}
body.tkt div.content ol.tkt-changes > li:target > ol {
border-left: 1px solid gold;
}
span.modpending {
color: #b03800;
font-style: italic;
}
pre.th1result {
white-space: pre-wrap;
| > > > > > > > > > > | 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 |
}
body.tkt div.content ol.tkt-changes > li:target > p > span {
border-bottom: 3px solid gold;
}
body.tkt div.content ol.tkt-changes > li:target > ol {
border-left: 1px solid gold;
}
body.cpage-ckout .file-change-line,
body.cpage-info .file-change-line,
body.cpage-vdiff .file-change-line {
margin-top: 16px;
margin-bottom: 16px;
margin-right: 1em /* keep it from nudging right up against the scrollbar-reveal zone */;
display: flex;
flex-direction: row;
justify-content: space-between;
}
span.modpending {
color: #b03800;
font-style: italic;
}
pre.th1result {
white-space: pre-wrap;
|
| ︙ | ︙ | |||
1816 1817 1818 1819 1820 1821 1822 |
.settings-icon:hover {
border: 1px outset rgba(127,127,127,1);
}
body.fossil-dark-style .settings-icon {
filter: invert(100%);
}
| < < < < | 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 |
.settings-icon:hover {
border: 1px outset rgba(127,127,127,1);
}
body.fossil-dark-style .settings-icon {
filter: invert(100%);
}
body.branch .brlist > table > tbody > tr:hover:not(.selected),
body.branch .brlist > table > tbody > tr.selected {
background-color: #ffc;
}
body.branch .brlist > table > tbody td:first-child > input {
cursor: pointer;
}
|
| ︙ | ︙ |
Changes to src/descendants.c.
| ︙ | ︙ | |||
200 201 202 203 204 205 206 |
double rLimitMtime = 0.0;
if( ridBackTo ){
rLimitMtime = db_double(0.0,
"SELECT mtime FROM event WHERE objid=%d",
ridBackTo);
}
db_multi_exec(
| | | | | | | | | | | | | | | | | | | < | 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 |
double rLimitMtime = 0.0;
if( ridBackTo ){
rLimitMtime = db_double(0.0,
"SELECT mtime FROM event WHERE objid=%d",
ridBackTo);
}
db_multi_exec(
"WITH RECURSIVE\n"
" parent(pid,cid,isCP) AS (\n"
" SELECT plink.pid, plink.cid, 0 AS xisCP FROM plink\n"
" UNION ALL\n"
" SELECT parentid, childid, 1 FROM cherrypick WHERE NOT isExclude\n"
" ),\n"
" ancestor(rid, mtime, isCP) AS (\n"
" SELECT %d, mtime, 0 FROM event WHERE objid=%d\n"
" UNION\n"
" SELECT parent.pid, event.mtime, parent.isCP\n"
" FROM ancestor, parent, event\n"
" WHERE parent.cid=ancestor.rid\n"
" AND event.objid=parent.pid\n"
" AND NOT ancestor.isCP\n"
" AND (event.mtime>=%.17g OR parent.pid=%d)\n"
" ORDER BY mtime DESC LIMIT %d\n"
" )\n"
"INSERT OR IGNORE INTO ok SELECT rid FROM ancestor;",
rid, rid, rLimitMtime, ridBackTo, N
);
if( ridBackTo && db_changes()>1 ){
db_multi_exec("INSERT OR IGNORE INTO ok VALUES(%d)", ridBackTo);
}
}
}
|
| ︙ | ︙ | |||
320 321 322 323 324 325 326 |
void compute_descendants(int rid, int N){
if( !N ){
N = -1;
}else if( N<0 ){
N = -N;
}
db_multi_exec(
| | | | | | | | | | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
void compute_descendants(int rid, int N){
if( !N ){
N = -1;
}else if( N<0 ){
N = -N;
}
db_multi_exec(
"WITH RECURSIVE\n"
" dx(rid,mtime) AS (\n"
" SELECT %d, 0\n"
" UNION\n"
" SELECT plink.cid, plink.mtime FROM dx, plink\n"
" WHERE plink.pid=dx.rid\n"
" ORDER BY 2\n"
" )\n"
"INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
rid, N
);
}
/*
** COMMAND: descendants*
|
| ︙ | ︙ | |||
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 |
#if INTERFACE
/* Flag parameters to compute_uses_file() */
#define USESFILE_DELETE 0x01 /* Include the check-ins where file deleted */
#endif
/*
** Add to table zTab the record ID (rid) of every check-in that contains
** the file fid.
*/
void compute_uses_file(const char *zTab, int fid, int usesFlags){
Bag seen;
Bag pending;
| > > > > > > > > > > > > > > > | > | | < < | < < | < < > | | 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 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 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 |
#if INTERFACE
/* Flag parameters to compute_uses_file() */
#define USESFILE_DELETE 0x01 /* Include the check-ins where file deleted */
#endif
/*
** Append a new VALUES term.
*/
static void uses_file_append_term(Blob *pSql, int *pnCnt, int rid){
if( *pnCnt==0 ){
blob_append_sql(pSql, "(%d)", rid);
*pnCnt = 4;
}else if( (*pnCnt)%10==9 ){
blob_append_sql(pSql, ",\n (%d)", rid);
}else{
blob_append_sql(pSql, ",(%d)", rid);
}
++*pnCnt;
}
/*
** Add to table zTab the record ID (rid) of every check-in that contains
** the file fid.
*/
void compute_uses_file(const char *zTab, int fid, int usesFlags){
Bag seen;
Bag pending;
Blob ins = BLOB_INITIALIZER;
int nIns = 0;
Stmt q;
int rid;
bag_init(&seen);
bag_init(&pending);
blob_append_sql(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES", zTab);
db_prepare(&q, "SELECT mid FROM mlink WHERE fid=%d", fid);
while( db_step(&q)==SQLITE_ROW ){
int mid = db_column_int(&q, 0);
bag_insert(&pending, mid);
bag_insert(&seen, mid);
uses_file_append_term(&ins, &nIns, mid);
}
db_finalize(&q);
db_prepare(&q, "SELECT mid FROM mlink WHERE pid=%d", fid);
while( db_step(&q)==SQLITE_ROW ){
int mid = db_column_int(&q, 0);
bag_insert(&seen, mid);
if( usesFlags & USESFILE_DELETE ){
uses_file_append_term(&ins, &nIns, mid);
}
}
db_finalize(&q);
db_prepare(&q, "SELECT cid FROM plink WHERE pid=:rid AND isprim");
while( (rid = bag_first(&pending))!=0 ){
bag_remove(&pending, rid);
db_bind_int(&q, ":rid", rid);
while( db_step(&q)==SQLITE_ROW ){
int mid = db_column_int(&q, 0);
if( bag_find(&seen, mid) ) continue;
bag_insert(&seen, mid);
bag_insert(&pending, mid);
uses_file_append_term(&ins, &nIns, mid);
}
db_reset(&q);
}
db_finalize(&q);
db_exec_sql(blob_str(&ins));
blob_reset(&ins);
bag_clear(&seen);
bag_clear(&pending);
}
|
Changes to src/diff.c.
| ︙ | ︙ | |||
3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 |
/*
** Initialize the DiffConfig object using command-line options.
**
** Process diff-related command-line options and return an appropriate
** "diffFlags" integer.
**
** --brief Show filenames only DIFF_BRIEF
** -c|--context N N lines of context. nContext
** --html Format for HTML DIFF_HTML
** --invert Invert the diff DIFF_INVERT
** -n|--linenum Show line numbers DIFF_LINENO
** --noopt Disable optimization DIFF_NOOPT
** --numstat Show change counts DIFF_NUMSTAT
** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
** --unified Unified diff. ~DIFF_SIDEBYSIDE
** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS
** -W|--width N N character lines. wColumn
** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
*/
void diff_options(DiffConfig *pCfg, int isGDiff, int bUnifiedTextOnly){
u64 diffFlags = 0;
const char *z;
| > > > > > > > > > | 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 |
/*
** Initialize the DiffConfig object using command-line options.
**
** Process diff-related command-line options and return an appropriate
** "diffFlags" integer.
**
** -b|--browser Show the diff output in a web-browser
** --brief Show filenames only DIFF_BRIEF
** --by Shorthand for "--browser -y"
** -c|--context N N lines of context. nContext
** --dark Use dark mode for Tcl/Tk and HTML output
** --html Format for HTML DIFF_HTML
** -i|--internal Use built-in diff, not an external tool
** --invert Invert the diff DIFF_INVERT
** --json Output formatted as JSON
** -n|--linenum Show line numbers DIFF_LINENO
** -N|--new-file Alias for --verbose
** --noopt Disable optimization DIFF_NOOPT
** --numstat Show change counts DIFF_NUMSTAT
** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR
** --tcl Tcl-formatted output used internally by --tk
** --unified Unified diff. ~DIFF_SIDEBYSIDE
** -v|--verbose Show complete text of added or deleted files
** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS
** --webpage Format output as a stand-alone HTML webpage
** -W|--width N N character lines. wColumn
** -y|--side-by-side Side-by-side diff. DIFF_SIDEBYSIDE
** -Z|--ignore-trailing-space Ignore eol-whitespaces DIFF_IGNORE_EOLWS
*/
void diff_options(DiffConfig *pCfg, int isGDiff, int bUnifiedTextOnly){
u64 diffFlags = 0;
const char *z;
|
| ︙ | ︙ |
Changes to src/diff.tcl.
| ︙ | ︙ | |||
108 109 110 111 112 113 114 |
array set widths {txt 3 ln 3 mkr 1}
set fromIndex [lsearch -glob $fossilcmd *-from]
set toIndex [lsearch -glob $fossilcmd *-to]
set branchIndex [lsearch -glob $fossilcmd *-branch]
set checkinIndex [lsearch -glob $fossilcmd *-checkin]
| > > > | > | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
array set widths {txt 3 ln 3 mkr 1}
set fromIndex [lsearch -glob $fossilcmd *-from]
set toIndex [lsearch -glob $fossilcmd *-to]
set branchIndex [lsearch -glob $fossilcmd *-branch]
set checkinIndex [lsearch -glob $fossilcmd *-checkin]
if {[string match *?--external-baseline* $fossilcmd]} {
set fA {external baseline}
} else {
set fA {base check-in}
}
set fB {current check-out}
if {$fromIndex > -1} {set fA [lindex $fossilcmd $fromIndex+1]}
if {$toIndex > -1} {set fB [lindex $fossilcmd $toIndex+1]}
if {$branchIndex > -1} {set fA "branch point"; set fB "leaf of branch '[lindex $fossilcmd $branchIndex+1]'"}
if {$checkinIndex > -1} {set fA "primary parent"; set fB [lindex $fossilcmd $checkinIndex+1]}
|
| ︙ | ︙ |
Changes to src/diffcmd.c.
| ︙ | ︙ | |||
801 802 803 804 805 806 807 |
rc = memcmp(blob_buffer(&file), blob_buffer(blob), blob_size(&file))==0;
}
blob_reset(&file);
return rc;
}
/*
| | | | > | | | 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 |
rc = memcmp(blob_buffer(&file), blob_buffer(blob), blob_size(&file))==0;
}
blob_reset(&file);
return rc;
}
/*
** Run a diff between the version zFrom and files on disk in the current
** working checkout. zFrom might be NULL which means to simply show the
** difference between the edited files on disk and the check-out on which
** they are based.
**
** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
** command zDiffCmd to do the diffing.
**
** When using an external diff program, zBinGlob contains the GLOB patterns
** for file names to treat as binary. If fIncludeBinary is zero, these files
** will be skipped in addition to files that may contain binary content.
*/
void diff_version_to_checkout(
const char *zFrom, /* Version to difference from */
DiffConfig *pCfg, /* Flags controlling diff output */
FileDirList *pFileDir, /* Which files to diff */
Blob *pOut /* Blob to output diff instead of stdout */
){
int vid;
Blob sql;
Stmt q;
int asNewFile; /* Treat non-existant files as empty files */
int isNumStat; /* True for --numstat */
|
| ︙ | ︙ | |||
945 946 947 948 949 950 951 |
blob_reset(&fname);
}
db_finalize(&q);
db_end_transaction(1); /* ROLLBACK */
}
/*
| | | | 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 |
blob_reset(&fname);
}
db_finalize(&q);
db_end_transaction(1); /* ROLLBACK */
}
/*
** Run a diff from the undo buffer to files on disk.
**
** Use the internal diff logic if zDiffCmd is NULL. Otherwise call the
** command zDiffCmd to do the diffing.
**
** When using an external diff program, zBinGlob contains the GLOB patterns
** for file names to treat as binary. If fIncludeBinary is zero, these files
** will be skipped in addition to files that may contain binary content.
*/
static void diff_undo_to_checkout(
DiffConfig *pCfg, /* Flags controlling diff output */
FileDirList *pFileDir /* List of files and directories to diff */
){
Stmt q;
Blob content;
db_prepare(&q, "SELECT pathname, content FROM undo");
blob_init(&content, 0, 0);
|
| ︙ | ︙ | |||
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 |
pFromFile = manifest_file_next(pFrom,0);
pToFile = manifest_file_next(pTo,0);
}
}
manifest_destroy(pFrom);
manifest_destroy(pTo);
}
/*
** Return the name of the external diff command, or return NULL if
** no external diff command is defined.
*/
const char *diff_command_external(int guiDiff){
const char *zDefault;
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 |
pFromFile = manifest_file_next(pFrom,0);
pToFile = manifest_file_next(pTo,0);
}
}
manifest_destroy(pFrom);
manifest_destroy(pTo);
}
/*
** Compute the difference from an external tree of files to the current
** working checkout with its edits.
**
** To put it another way: Every managed file in the current working
** checkout is compared to the file with same name under zExternBase. The
** zExternBase files are on the left and the files in the current working
** directory are on the right.
*/
void diff_externbase_to_checkout(
const char *zExternBase, /* Remote tree to use as the baseline */
DiffConfig *pCfg, /* Diff settings */
FileDirList *pFileDir /* Only look at these files */
){
int vid;
Stmt q;
vid = db_lget_int("checkout",0);
if( file_isdir(zExternBase, ExtFILE)!=1 ){
fossil_fatal("\"%s\" is not a directory", zExternBase);
}
db_prepare(&q,
"SELECT pathname FROM vfile WHERE vid=%d ORDER BY pathname",
vid
);
while( db_step(&q)==SQLITE_ROW ){
const char *zFile; /* Name of file in the repository */
char *zLhs; /* Full name of left-hand side file */
char *zRhs; /* Full name of right-hand side file */
Blob rhs; /* Full text of RHS */
Blob lhs; /* Full text of LHS */
zFile = db_column_text(&q,0);
if( !file_dir_match(pFileDir, zFile) ) continue;
zLhs = mprintf("%s/%s", zExternBase, zFile);
zRhs = mprintf("%s%s", g.zLocalRoot, zFile);
if( file_size(zLhs, ExtFILE)<0 ){
blob_zero(&lhs);
}else{
blob_read_from_file(&lhs, zLhs, ExtFILE);
}
blob_read_from_file(&rhs, zRhs, ExtFILE);
if( blob_size(&lhs)!=blob_size(&rhs)
|| memcmp(blob_buffer(&lhs), blob_buffer(&rhs), blob_size(&lhs))!=0
){
diff_print_index(zFile, pCfg, 0);
diff_file_mem(&lhs, &rhs, zFile, pCfg);
}
blob_reset(&lhs);
blob_reset(&rhs);
fossil_free(zLhs);
fossil_free(zRhs);
}
db_finalize(&q);
}
/*
** Return the name of the external diff command, or return NULL if
** no external diff command is defined.
*/
const char *diff_command_external(int guiDiff){
const char *zDefault;
|
| ︙ | ︙ | |||
1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 | ** for the diff operation. If not specified, the source check-in is the ** base check-in for the current check-out. Similarly, the "--to VERSION" ** option specifies the check-in from which the second version of the file ** or files is taken. If there is no "--to" option then the (possibly edited) ** files in the current check-out are used. The "--checkin VERSION" option ** shows the changes made by check-in VERSION relative to its primary parent. ** The "--branch BRANCHNAME" shows all the changes on the branch BRANCHNAME. ** ** The "-i" command-line option forces the use of Fossil's own internal ** diff logic rather than any external diff program that might be configured ** using the "setting" command. If no external diff program is configured, ** then the "-i" option is a no-op. The "-i" option converts "gdiff" into ** "diff". ** | > > > > | 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 | ** for the diff operation. If not specified, the source check-in is the ** base check-in for the current check-out. Similarly, the "--to VERSION" ** option specifies the check-in from which the second version of the file ** or files is taken. If there is no "--to" option then the (possibly edited) ** files in the current check-out are used. The "--checkin VERSION" option ** shows the changes made by check-in VERSION relative to its primary parent. ** The "--branch BRANCHNAME" shows all the changes on the branch BRANCHNAME. ** ** With the "--from VERSION" option, if VERSION is actually a directory name ** (not a tag or check-in hash) then the files under that directory are used ** as the baseline for the diff. ** ** The "-i" command-line option forces the use of Fossil's own internal ** diff logic rather than any external diff program that might be configured ** using the "setting" command. If no external diff program is configured, ** then the "-i" option is a no-op. The "-i" option converts "gdiff" into ** "diff". ** |
| ︙ | ︙ | |||
1273 1274 1275 1276 1277 1278 1279 | ** --command PROG External diff program. Overrides "diff-command" ** -c|--context N Show N lines of context around each change, ** with negative N meaning show all content ** --dark Use dark mode for the Tcl/Tk-based GUI and HTML ** --diff-binary BOOL Include binary files with external commands ** --exec-abs-paths Force absolute path names on external commands ** --exec-rel-paths Force relative path names on external commands | | > > | > | | < < > > > > > > > > > > > | 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 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 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 |
** --command PROG External diff program. Overrides "diff-command"
** -c|--context N Show N lines of context around each change,
** with negative N meaning show all content
** --dark Use dark mode for the Tcl/Tk-based GUI and HTML
** --diff-binary BOOL Include binary files with external commands
** --exec-abs-paths Force absolute path names on external commands
** --exec-rel-paths Force relative path names on external commands
** -r|--from VERSION Use VERSION as the baseline for the diff, or
** if VERSION is a directory name, use files in
** that directory as the baseline.
** -w|--ignore-all-space Ignore white space when comparing lines
** -i|--internal Use internal diff logic
** --invert Invert the diff
** --json Output formatted as JSON
** -n|--linenum Show line numbers
** -N|--new-file Alias for --verbose
** --numstat Show only the number of added and deleted lines
** -y|--side-by-side Side-by-side diff
** --strip-trailing-cr Strip trailing CR
** --tcl Tcl-formatted output used internally by --tk
** --tclsh PATH Tcl/Tk shell used for --tk (default: "tclsh")
** --tk Launch a Tcl/Tk GUI for display
** --to VERSION Select VERSION as target for the diff
** --undo Use the undo buffer as the baseline
** --unified Unified diff
** -v|--verbose Output complete text of added or deleted files
** -h|--versions Show compared versions in the diff header
** --webpage Format output as a stand-alone HTML webpage
** -W|--width N Width of lines in side-by-side diff
** -Z|--ignore-trailing-space Ignore changes to end-of-line whitespace
*/
void diff_cmd(void){
int isGDiff; /* True for gdiff. False for normal diff */
const char *zFrom; /* Source version number */
const char *zTo; /* Target version number */
const char *zCheckin; /* Check-in version number */
const char *zBranch; /* Branch to diff */
int againstUndo = 0; /* Diff against files in the undo buffer */
FileDirList *pFileDir = 0; /* Restrict the diff to these files */
DiffConfig DCfg; /* Diff configuration object */
int bFromIsDir = 0; /* True if zFrom is a directory name */
if( find_option("tk",0,0)!=0 || has_option("tclsh") ){
diff_tk("diff", 2);
return;
}
isGDiff = g.argv[1][0]=='g';
zFrom = find_option("from", "r", 1);
zTo = find_option("to", 0, 1);
zCheckin = find_option("checkin", "ci", 1);
zBranch = find_option("branch", 0, 1);
againstUndo = find_option("undo",0,0)!=0;
if( againstUndo && (zFrom!=0 || zTo!=0 || zCheckin!=0 || zBranch!=0) ){
fossil_fatal("cannot use --undo together with --from, --to, --checkin,"
" or --branch");
}
if( zBranch ){
if( zTo || zFrom || zCheckin ){
fossil_fatal("cannot use --from, --to, or --checkin with --branch");
}
zTo = zBranch;
zFrom = mprintf("root:%s", zBranch);
}
if( zCheckin!=0 && (zFrom!=0 || zTo!=0) ){
fossil_fatal("cannot use --checkin together with --from or --to");
}
if( 0==zCheckin ){
if( zTo==0 || againstUndo ){
db_must_be_within_tree();
}else if( zFrom==0 ){
fossil_fatal("must use --from if --to is present");
}else{
db_find_and_open_repository(0, 0);
}
}else{
db_find_and_open_repository(0, 0);
}
determine_exec_relative_option(1);
if( zFrom!=file_tail(zFrom)
&& file_isdir(zFrom, ExtFILE)==1
&& !db_exists("SELECT 1 FROM tag WHERE tagname='sym-%q'", zFrom)
){
bFromIsDir = 1;
if( zTo ){
fossil_fatal("cannot use --to together with \"--from PATH\"");
}
}
diff_options(&DCfg, isGDiff, 0);
verify_all_options();
g.diffCnt[0] = g.diffCnt[1] = g.diffCnt[2] = 0;
if( g.argc>=3 ){
int i;
Blob fname;
pFileDir = fossil_malloc( sizeof(*pFileDir) * (g.argc-1) );
memset(pFileDir, 0, sizeof(*pFileDir) * (g.argc-1));
for(i=2; i<g.argc; i++){
file_tree_name(g.argv[i], &fname, 0, 1);
|
| ︙ | ︙ | |||
1374 1375 1376 1377 1378 1379 1380 |
" WHERE plink.cid=%d AND plink.isprim AND plink.pid=blob.rid",
ridTo);
if( zFrom==0 ){
fossil_fatal("check-in %s has no parent", zTo);
}
}
diff_begin(&DCfg);
| > > | | | | 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 |
" WHERE plink.cid=%d AND plink.isprim AND plink.pid=blob.rid",
ridTo);
if( zFrom==0 ){
fossil_fatal("check-in %s has no parent", zTo);
}
}
diff_begin(&DCfg);
if( bFromIsDir ){
diff_externbase_to_checkout(zFrom, &DCfg, pFileDir);
}else if( againstUndo ){
if( db_lget_int("undo_available",0)==0 ){
fossil_print("No undo or redo is available\n");
return;
}
diff_undo_to_checkout(&DCfg, pFileDir);
}else if( zTo==0 ){
diff_version_to_checkout(zFrom, &DCfg, pFileDir, 0);
}else{
diff_two_versions(zFrom, zTo, &DCfg, pFileDir);
}
if( pFileDir ){
int i;
for(i=0; pFileDir[i].zName; i++){
if( pFileDir[i].nUsed==0
|
| ︙ | ︙ |
Changes to src/doc.c.
| ︙ | ︙ | |||
786 787 788 789 790 791 792 |
const char *zDefaultTitle, /* Default title */
const char *zFilename /* Name of the file being rendered */
){
Blob title;
int isPopup = P("popup")!=0;
blob_init(&title,0,0);
if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
| | > > | 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 |
const char *zDefaultTitle, /* Default title */
const char *zFilename /* Name of the file being rendered */
){
Blob title;
int isPopup = P("popup")!=0;
blob_init(&title,0,0);
if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
Blob tail = BLOB_INITIALIZER;
style_adunit_config(ADUNIT_RIGHT_OK);
if( wiki_find_title(pBody, &title, &tail) ){
if( !isPopup ) style_header("%s", blob_str(&title));
wiki_convert(&tail, 0, WIKI_BUTTONS);
}else{
if( !isPopup ) style_header("%s", zDefaultTitle);
wiki_convert(pBody, 0, WIKI_BUTTONS);
}
if( !isPopup ){
document_emit_js();
style_finish_page();
}
blob_reset(&tail);
}else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
Blob tail = BLOB_INITIALIZER;
markdown_to_html(pBody, &title, &tail);
if( !isPopup ){
if( blob_size(&title)>0 ){
style_header("%s", blob_str(&title));
}else{
style_header("%s", zDefaultTitle);
}
}
convert_href_and_output(&tail);
if( !isPopup ){
document_emit_js();
style_finish_page();
}
blob_reset(&tail);
}else if( fossil_strcmp(zMime, "text/plain")==0 ){
style_header("%s", zDefaultTitle);
@ <blockquote><pre>
@ %h(blob_str(pBody))
@ </pre></blockquote>
document_emit_js();
style_finish_page();
|
| ︙ | ︙ | |||
947 948 949 950 951 952 953 954 955 956 957 958 959 960 |
#endif
};
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_set_current_feature("doc");
blob_init(&title, 0, 0);
zDfltTitle = isUV ? "" : "Documentation";
db_begin_transaction();
while( rid==0 && (++nMiss)<=count(azSuffix) ){
zName = P("name");
if( isUV ){
if( zName==0 ) zName = "index.wiki";
i = 0;
| > | 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 |
#endif
};
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_set_current_feature("doc");
blob_init(&title, 0, 0);
blob_init(&filebody, 0, 0);
zDfltTitle = isUV ? "" : "Documentation";
db_begin_transaction();
while( rid==0 && (++nMiss)<=count(azSuffix) ){
zName = P("name");
if( isUV ){
if( zName==0 ) zName = "index.wiki";
i = 0;
|
| ︙ | ︙ | |||
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 |
Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
" WHERE objid=%d AND type='ci'", vid));
}
cgi_check_for_malice();
document_render(&filebody, zMime, zDfltTitle, zName);
if( nMiss>=count(azSuffix) ) cgi_set_status(404, "Not Found");
db_end_transaction(0);
return;
/* Jump here when unable to locate the document */
doc_not_found:
db_end_transaction(0);
if( isUV && P("name")==0 ){
uvlist_page();
return;
}
cgi_set_status(404, "Not Found");
style_header("Not Found");
@ <p>Document %h(zOrigName) not found
if( fossil_strcmp(zCheckin,"ckout")!=0 ){
@ in %z(href("%R/tree?ci=%T",zCheckin))%h(zCheckin)</a>
}
style_finish_page();
return;
}
/*
** The default logo.
*/
static const unsigned char aLogo[] = {
| > > > > | 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 |
Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
" WHERE objid=%d AND type='ci'", vid));
}
cgi_check_for_malice();
document_render(&filebody, zMime, zDfltTitle, zName);
if( nMiss>=count(azSuffix) ) cgi_set_status(404, "Not Found");
db_end_transaction(0);
blob_reset(&title);
blob_reset(&filebody);
return;
/* Jump here when unable to locate the document */
doc_not_found:
db_end_transaction(0);
if( isUV && P("name")==0 ){
uvlist_page();
return;
}
cgi_set_status(404, "Not Found");
style_header("Not Found");
@ <p>Document %h(zOrigName) not found
if( fossil_strcmp(zCheckin,"ckout")!=0 ){
@ in %z(href("%R/tree?ci=%T",zCheckin))%h(zCheckin)</a>
}
style_finish_page();
blob_reset(&title);
blob_reset(&filebody);
return;
}
/*
** The default logo.
*/
static const unsigned char aLogo[] = {
|
| ︙ | ︙ |
Changes to src/encode.c.
| ︙ | ︙ | |||
727 728 729 730 731 732 733 734 735 736 737 738 739 740 |
*/
void canonical16(char *z, int n){
while( *z && n-- ){
*z = zEncode[zDecode[(*z)&0x7f]&0x1f];
z++;
}
}
/*
** Decode a string encoded using "quoted-printable".
**
** (1) "=" followed by two hex digits becomes a single
** byte specified by the two digits
**
| > > > > > > > > > > > > > > > > > > | 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 |
*/
void canonical16(char *z, int n){
while( *z && n-- ){
*z = zEncode[zDecode[(*z)&0x7f]&0x1f];
z++;
}
}
/*
** Decode hexadecimal into a string and return the new string. Space to
** hold the string is obtained from fossil_malloc() and should be released
** by the caller.
**
** If the input is not hex, return NULL.
*/
char *decode16_dup(const char *zIn){
int nIn = (int)strlen(zIn);
char *zOut;
if( !validate16(zIn, nIn) ) return 0;
zOut = fossil_malloc(nIn/2+1);
decode16((const u8*)zIn, (u8*)zOut, nIn);
zOut[nIn/2] = 0;
return zOut;
}
/*
** Decode a string encoded using "quoted-printable".
**
** (1) "=" followed by two hex digits becomes a single
** byte specified by the two digits
**
|
| ︙ | ︙ |
Changes to src/file.c.
| ︙ | ︙ | |||
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 |
if( !zTail ) return 0;
while( z[0] ){
if( fossil_isdirsep(z[0]) ) zTail = &z[1];
z++;
}
return zTail;
}
/*
** Return the directory of a file path name. The directory is all components
** except the last one. For example, the directory of "/a/b/c.d" is "/a/b".
** If there is no directory, NULL is returned; otherwise, the returned memory
** should be freed via fossil_free().
*/
char *file_dirname(const char *z){
const char *zTail = file_tail(z);
if( zTail && zTail!=z ){
return mprintf("%.*s", (int)(zTail-z-1), z);
}else{
return 0;
}
}
/* SQL Function: file_dirname(NAME)
**
** Return the directory for NAME
*/
void file_dirname_sql_function(
sqlite3_context *context,
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 |
if( !zTail ) return 0;
while( z[0] ){
if( fossil_isdirsep(z[0]) ) zTail = &z[1];
z++;
}
return zTail;
}
/*
** Return the tail of a command: the basename of the putative executable (which
** could be quoted when containing spaces) and the following arguments.
*/
const char *command_tail(const char *z){
const char *zTail = z;
char chQuote = 0;
if( !zTail ) return 0;
while( z[0] && (!fossil_isspace(z[0]) || chQuote) ){
if( z[0]=='"' || z[0]=='\'' ){
chQuote = (chQuote==z[0]) ? 0 : z[0];
}
if( fossil_isdirsep(z[0]) ) zTail = &z[1];
z++;
}
return zTail;
}
/*
** Return the directory of a file path name. The directory is all components
** except the last one. For example, the directory of "/a/b/c.d" is "/a/b".
** If there is no directory, NULL is returned; otherwise, the returned memory
** should be freed via fossil_free().
*/
char *file_dirname(const char *z){
const char *zTail = file_tail(z);
if( zTail && zTail!=z ){
return mprintf("%.*s", (int)(zTail-z-1), z);
}else{
return 0;
}
}
/*
** Return the basename of the putative executable in a command (w/o arguments).
** The returned memory should be freed via fossil_free().
*/
char *command_basename(const char *z){
const char *zTail = command_tail(z);
const char *zEnd = zTail;
while( zEnd[0] && !fossil_isspace(zEnd[0]) && zEnd[0]!='"' && zEnd[0]!='\'' ){
zEnd++;
}
if( zEnd ){
return mprintf("%.*s", (int)(zEnd-zTail), zTail);
}else{
return 0;
}
}
/* SQL Function: file_dirname(NAME)
**
** Return the directory for NAME
*/
void file_dirname_sql_function(
sqlite3_context *context,
|
| ︙ | ︙ | |||
2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 |
/*
** Returns 1 if the given directory contains a file named .fslckout, 2
** if it contains a file named _FOSSIL_, else returns 0.
*/
int dir_has_ckout_db(const char *zDir){
int rc = 0;
char * zCkoutDb = mprintf("%//.fslckout", zDir);
if(file_isfile(zCkoutDb, ExtFILE)){
rc = 1;
}else{
fossil_free(zCkoutDb);
zCkoutDb = mprintf("%//_FOSSIL_", zDir);
if(file_isfile(zCkoutDb, ExtFILE)){
rc = 2;
}
}
fossil_free(zCkoutDb);
return rc;
}
/*
** This is the implementation of inode(FILENAME) SQL function.
| > > > > | 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 |
/*
** Returns 1 if the given directory contains a file named .fslckout, 2
** if it contains a file named _FOSSIL_, else returns 0.
*/
int dir_has_ckout_db(const char *zDir){
int rc = 0;
i64 sz;
char * zCkoutDb = mprintf("%//.fslckout", zDir);
if(file_isfile(zCkoutDb, ExtFILE)){
rc = 1;
}else{
fossil_free(zCkoutDb);
zCkoutDb = mprintf("%//_FOSSIL_", zDir);
if(file_isfile(zCkoutDb, ExtFILE)){
rc = 2;
}
}
if( rc && ((sz = file_size(zCkoutDb, ExtFILE))<1024 || (sz%512)!=0) ){
rc = 0;
}
fossil_free(zCkoutDb);
return rc;
}
/*
** This is the implementation of inode(FILENAME) SQL function.
|
| ︙ | ︙ |
Changes to src/finfo.c.
| ︙ | ︙ | |||
35 36 37 38 39 40 41 | ** ** The -i mode will print various facts about FILENAME, including its ** hash and the check-in and time when the current version of the file ** was created. Use -v for additional information. Add the -r VERSION ** option to see similar information about the same file for the check-in ** specified by VERSION. ** | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | ** ** The -i mode will print various facts about FILENAME, including its ** hash and the check-in and time when the current version of the file ** was created. Use -v for additional information. Add the -r VERSION ** option to see similar information about the same file for the check-in ** specified by VERSION. ** ** The -s mode prints the status as <status> <revision>. This is ** a quick status and does not check for up-to-date-ness of the file. ** ** In the -p mode, there's an optional flag "-r|--revision REVISION". ** The specified version (or the latest checked-out version) is printed ** to stdout. The -p mode is another form of the "cat" command. ** ** Options: |
| ︙ | ︙ |
Changes to src/forum.c.
| ︙ | ︙ | |||
1828 1829 1830 1831 1832 1833 1834 |
@ <h2>Moderators</h2>
if( db_int(0, "SELECT count(*) FROM user "
" WHERE cap GLOB '*5*' AND cap NOT GLOB '*[as6]*'")==0 ){
@ <p>No non-supervisor moderators
}else{
Stmt q = empty_Stmt;
| < < | 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 |
@ <h2>Moderators</h2>
if( db_int(0, "SELECT count(*) FROM user "
" WHERE cap GLOB '*5*' AND cap NOT GLOB '*[as6]*'")==0 ){
@ <p>No non-supervisor moderators
}else{
Stmt q = empty_Stmt;
db_prepare(&q, "SELECT uid, login, cap FROM user "
"WHERE cap GLOB '*5*' AND cap NOT GLOB '*[as6]*'"
" ORDER BY login");
@ <table class='bordered'>
@ <thead><tr><th>User</th><th>Capabilities</th></tr></thead>
@ <tbody>
while( SQLITE_ROW==db_step(&q) ){
const int iUid = db_column_int(&q, 0);
const char *zUser = db_column_text(&q, 1);
const char *zCap = db_column_text(&q, 2);
@ <tr>
@ <td><a href='%R/setup_uedit?id=%d(iUid)'>%h(zUser)</a></td>
@ <td>(%h(zCap))</td>
@ </tr>
}
db_finalize(&q);
@ </tbody></table>
|
| ︙ | ︙ |
Changes to src/fossil.diff.js.
1 2 3 4 5 6 7 8 9 10 |
/**
diff-related JS APIs for fossil.
*/
"use strict";
window.fossil.onPageLoad(function(){
/**
Adds toggle checkboxes to each file entry in the diff views for
/info and similar pages.
*/
const D = window.fossil.dom;
| > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > | < > | > > > > > | | | > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 73 74 75 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 |
/**
diff-related JS APIs for fossil.
*/
"use strict";
/* Locate the UI element (if any) into which we can inject some diff-related
UI controls. */
window.fossil.onPageLoad(function(){
const potentialParents = window.fossil.page.diffControlContainers = [
/* CSS selectors for possible parents for injected diff-related UI
controls. */
/* Put the most likely pages at the end, as array.pop() is more
efficient than array.shift() (see loop below). */
/* /filedit */ 'body.cpage-fileedit #fileedit-tab-diff-buttons',
/* /wikiedit */ 'body.cpage-wikiedit #wikiedit-tab-diff-buttons',
/* /fdiff */ 'body.fdiff form div.submenu',
/* /vdiff */ 'body.vdiff form div.submenu',
/* /info, /vinfo, /ckout */ 'body.vinfo div.sectionmenu.info-changes-menu'
];
window.fossil.page.diffControlContainer = undefined;
while( potentialParents.length ){
if( (window.fossil.page.diffControlContainer
= document.querySelector(potentialParents.pop())) ){
break;
}
}
});
window.fossil.onPageLoad(function(){
/**
Adds toggle checkboxes to each file entry in the diff views for
/info and similar pages.
*/
if( !window.fossil.page.diffControlContainer ){
return;
}
const D = window.fossil.dom;
const allToggles = [/*collection of all diff-toggle checkboxes*/];
let checkedCount =
0 /* When showing more than one diff, keep track of how many
"show/hide" checkboxes are are checked so we can update the
"show/hide all" label dynamically. */;
let btnAll /* UI control to show/hide all diffs */;
/* Install a diff-toggle button for the given diff table element. */
const addToggle = function(diffElem){
const sib = diffElem.previousElementSibling,
ckbox = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
if(!sib) return;
const lblToggle = D.label();
D.append(lblToggle, ckbox, D.text(" show/hide "));
allToggles.push(ckbox);
++checkedCount;
/* Make all of the available empty space a click zone for the checkbox */
lblToggle.style.flexGrow = 1;
lblToggle.style.textAlign = 'right';
D.append(sib, lblToggle);
ckbox.addEventListener('change', function(){
diffElem.classList[this.checked ? 'remove' : 'add']('hidden');
if(btnAll){
checkedCount += (this.checked ? 1 : -1);
btnAll.innerText = (checkedCount < allToggles.length)
? "Show diffs" : "Hide diffs";
}
}, false);
/* Extend the toggle click zone to all of the non-hyperlink
elements in the left of this area (filenames and hashes). */
sib.firstElementChild.addEventListener('click', (event)=>{
if( event.target===sib.firstElementChild ){
/* Don't respond to clicks bubbling via hyperlink children */
ckbox.click();;
}
}, false);
};
if( !document.querySelector('body.fdiff') ){
/* Don't show the diff toggle button for /fdiff because it only
has a single file to show (and also a different DOM layout). */
document.querySelectorAll('table.diff').forEach(addToggle);
}
/**
Set up a "toggle all diffs" button which toggles all of the
above-installed checkboxes, but only if more than one diff is
rendered.
*/
const icm = allToggles.length>1 ? window.fossil.page.diffControlContainer : 0;
if(icm) {
btnAll = D.addClass(D.a("#", "Hide diffs"), "button");
D.append( icm, btnAll );
btnAll.addEventListener('click', function(ev){
ev.preventDefault();
ev.stopPropagation();
const show = checkedCount < allToggles.length;
for( const ckbox of allToggles ){
/* Toggle all entries to match this new state. We use click()
instead of ckbox.checked=... so that the on-change event handler
fires. */
if(ckbox.checked!==show) ckbox.click();
}
}, false);
}
});
window.fossil.onPageLoad(function(){
const F = window.fossil, D = F.dom;
const Diff = F.diff = {
e:{/*certain cached DOM elements*/},
config: {
|
| ︙ | ︙ | |||
633 634 635 636 637 638 639 |
const F = window.fossil, D = F.dom, Diff = F.diff;
/* Look for a parent element to hold the sbs-sync-scroll toggle
checkbox. This differs per page. If we don't find one, simply
elide that toggle and use whatever preference the user last
specified (defaulting to on). */
let cbSync /* scroll-sync checkbox */;
| | < < < < < < < < < < | > | < < | | | 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 |
const F = window.fossil, D = F.dom, Diff = F.diff;
/* Look for a parent element to hold the sbs-sync-scroll toggle
checkbox. This differs per page. If we don't find one, simply
elide that toggle and use whatever preference the user last
specified (defaulting to on). */
let cbSync /* scroll-sync checkbox */;
let eToggleParent = /* element to put the sync-scroll checkbox in */
document.querySelector('table.diff.splitdiff')
? window.fossil.page.diffControlContainer
: undefined;
const keySbsScroll = 'sync-diff-scroll' /* F.storage key for persistent user preference */;
if( eToggleParent ){
/* Add a checkbox to toggle sbs scroll sync. Remember that in
order to be UI-consistent in the /vdiff page we have to ensure
that the checkbox is to the LEFT of of its label. We store the
sync-scroll preference in F.storage (not a cookie) so that it
persists across page loads and different apps. */
cbSync = D.checkbox(keySbsScroll, F.storage.getBool(keySbsScroll,true));
D.append(eToggleParent, D.append(
D.addClass(D.create('span'), 'input-with-label'),
D.append(D.create('label'),
cbSync, "Scroll Sync")
));
cbSync.addEventListener('change', function(e){
F.storage.set(keySbsScroll, e.target.checked);
});
}
const useSync = cbSync ? ()=>cbSync.checked : ()=>F.storage.getBool(keySbsScroll,true);
|
| ︙ | ︙ |
Changes to src/fossil.dom.js.
| ︙ | ︙ | |||
85 86 87 88 89 90 91 |
*/
dom.label = function(forElem, text){
const rc = document.createElement('label');
if(forElem){
if(forElem instanceof HTMLElement){
forElem = this.attr(forElem, 'id');
}
| > | > | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
*/
dom.label = function(forElem, text){
const rc = document.createElement('label');
if(forElem){
if(forElem instanceof HTMLElement){
forElem = this.attr(forElem, 'id');
}
if(forElem){
dom.attr(rc, 'for', forElem);
}
}
if(text) this.append(rc, text);
return rc;
};
/**
Returns an IMG element with an optional src
attribute value.
|
| ︙ | ︙ |
Changes to src/graph.c.
| ︙ | ︙ | |||
493 494 495 496 497 498 499 | ** The tmFlags parameter is zero or more of the TIMELINE_* constants. ** Only the following are honored: ** ** TIMELINE_DISJOINT: Omit descenders ** TIMELINE_FILLGAPS: Use step-children ** TIMELINE_XMERGE: Omit off-graph merge lines */ | | > > > > | 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 |
** The tmFlags parameter is zero or more of the TIMELINE_* constants.
** Only the following are honored:
**
** TIMELINE_DISJOINT: Omit descenders
** TIMELINE_FILLGAPS: Use step-children
** TIMELINE_XMERGE: Omit off-graph merge lines
*/
void graph_finish(
GraphContext *p, /* The graph to be laid out */
Matcher *pLeftBranch, /* Compares true for left-most branch */
u32 tmFlags /* TIMELINE flags */
){
GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
int i, j;
u64 mask;
int hasDup = 0; /* True if one or more isDup entries */
const char *zTrunk;
u8 *aMap; /* Copy of p->aiRailMap */
int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;
|
| ︙ | ︙ | |||
961 962 963 964 965 966 967 |
pRoot->aiRiser[iFrom] = -1;
}
}
}
/*
** Compute the rail mapping that tries to put the branch named
| | | > | > | | < | > > | > > | > > > > | > | > > | 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 |
pRoot->aiRiser[iFrom] = -1;
}
}
}
/*
** Compute the rail mapping that tries to put the branch named
** pLeftBranch at the left margin. Other branches that merge
** with pLeftBranch are to the right with merge rails in between.
**
** aMap[X]=Y means that the X-th rail is drawn as the Y-th rail.
**
** Do not move rails around if there are timewarps, because that can
** seriously mess up the display of timewarps. Timewarps should be
** rare so this should not be a serious limitation to the algorithm.
*/
aMap = p->aiRailMap;
for(i=0; i<=p->mxRail; i++) aMap[i] = i; /* Set up a default mapping */
if( nTimewarp==0 ){
int kk;
/* Priority bits:
**
** 0x04 The preferred branch
**
** 0x02 A merge rail - a rail that contains merge lines into
** the preferred branch. Only applies if a preferred branch
** is defined. This improves the display of r=BRANCH
** options to /timeline.
**
** 0x01 A rail that merges with the preferred branch
*/
u16 aPriority[GR_MAX_RAIL];
int mxMatch = 0;
memset(aPriority, 0, (p->mxRail+1)*sizeof(aPriority[0]));
if( pLeftBranch ){
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
int iMatch = match_text(pLeftBranch, pRow->zBranch);
if( iMatch>0 ){
if( iMatch>10 ) iMatch = 10;
aPriority[pRow->iRail] |= 1<<(iMatch+1);
if( mxMatch<iMatch ) mxMatch = iMatch;
for(i=0; i<=p->mxRail; i++){
if( pRow->mergeIn[i] ) aPriority[i] |= 1;
}
if( pRow->mergeOut>=0 ) aPriority[pRow->mergeOut] |= 1;
}
}
for(i=0; i<=p->mxRail; i++){
if( p->mergeRail & BIT(i) ){
aPriority[i] |= 2;
}
}
}else{
j = 1;
aPriority[0] = 4;
mxMatch = 1;
for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
if( pRow->iRail==0 ){
for(i=0; i<=p->mxRail; i++){
if( pRow->mergeIn[i] ) aPriority[i] |= 1;
}
if( pRow->mergeOut>=0 ) aPriority[pRow->mergeOut] |= 1;
}
}
}
#if 0
fprintf(stderr,"mergeRail: 0x%llx\n", p->mergeRail);
fprintf(stderr,"Priority:");
for(i=0; i<=p->mxRail; i++){
fprintf(stderr," %x.%x",
aPriority[i]/4, aPriority[i]&3);
}
fprintf(stderr,"\n");
#endif
j = 0;
for(kk=4; kk<=1<<(mxMatch+1); kk*=2){
for(i=0; i<=p->mxRail; i++){
if( aPriority[i]>=kk && aPriority[i]<kk*2 ){
aMap[i] = j++;
}
}
}
for(i=p->mxRail; i>=0; i--){
if( aPriority[i]==3 ) aMap[i] = j++;
}
for(i=0; i<=p->mxRail; i++){
if( aPriority[i]==1 || aPriority[i]==2 ) aMap[i] = j++;
}
|
| ︙ | ︙ |
Changes to src/hook.c.
| ︙ | ︙ | |||
231 232 233 234 235 236 237 | ** > fossil hook test [OPTIONS] ID ** ** Run the hook script given by ID for testing purposes. ** Options: ** ** --dry-run Print the script on stdout rather than run it ** --base-rcvid N Pretend that the hook-last-rcvid value is N | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
** > fossil hook test [OPTIONS] ID
**
** Run the hook script given by ID for testing purposes.
** Options:
**
** --dry-run Print the script on stdout rather than run it
** --base-rcvid N Pretend that the hook-last-rcvid value is N
** --new-rcvid M Pretend that the last rcvid value is M
** --aux-file NAME NAME is substituted for %A in the script
**
** The --base-rcvid and --new-rcvid options are silently ignored if
** the hook type is not "after-receive". The default values for
** --base-rcvid and --new-rcvid cause the last receive to be processed.
*/
void hook_cmd(void){
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
318 319 320 321 322 323 324 325 326 327 328 329 330 331 |
|TIMELINE_GRAPH
|TIMELINE_FILLGAPS
|TIMELINE_NOSCROLL
|TIMELINE_XMERGE
|TIMELINE_CHPICK,
0, 0, 0, rid, rid2, 0);
db_finalize(&q);
}
/*
** Append the difference between artifacts to the output
*/
static void append_diff(
| > | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
|TIMELINE_GRAPH
|TIMELINE_FILLGAPS
|TIMELINE_NOSCROLL
|TIMELINE_XMERGE
|TIMELINE_CHPICK,
0, 0, 0, rid, rid2, 0);
db_finalize(&q);
blob_reset(&sql);
}
/*
** Append the difference between artifacts to the output
*/
static void append_diff(
|
| ︙ | ︙ | |||
370 371 372 373 374 375 376 |
const char *zName, /* Name of the file that has changed */
const char *zOld, /* blob.uuid before change. NULL for added files */
const char *zNew, /* blob.uuid after change. NULL for deletes */
const char *zOldName, /* Prior name. NULL if no name change. */
DiffConfig *pCfg, /* Flags for text_diff() or NULL to omit all */
int mperm /* executable or symlink permission for zNew */
){
| | > > > | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
const char *zName, /* Name of the file that has changed */
const char *zOld, /* blob.uuid before change. NULL for added files */
const char *zNew, /* blob.uuid after change. NULL for deletes */
const char *zOldName, /* Prior name. NULL if no name change. */
DiffConfig *pCfg, /* Flags for text_diff() or NULL to omit all */
int mperm /* executable or symlink permission for zNew */
){
@ <div class='file-change-line'><span>
/* Maintenance reminder: the extra level of SPAN is for
** arranging new elements via JS. */
if( !g.perm.Hyperlink ){
if( zNew==0 ){
@ Deleted %h(zName).
}else if( zOld==0 ){
@ Added %h(zName).
}else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
@ Name change from %h(zOldName) to %h(zName).
}else if( fossil_strcmp(zNew, zOld)==0 ){
if( mperm==PERM_EXE ){
@ %h(zName) became executable.
}else if( mperm==PERM_LNK ){
@ %h(zName) became a symlink.
}else{
@ %h(zName) became a regular file.
}
}else{
@ Changes to %h(zName).
}
@ </span></div>
if( pCfg ){
append_diff(zOld, zNew, pCfg);
}
}else{
if( zOld && zNew ){
if( fossil_strcmp(zOld, zNew)!=0 ){
if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){
|
| ︙ | ︙ | |||
436 437 438 439 440 441 442 443 |
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>.
}else{
@ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
}
if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
if( pCfg ){
append_diff(zOld, zNew, pCfg);
| > | < > > > < | 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 |
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zOld))[%S(zOld)]</a>.
}else{
@ Added %z(href("%R/finfo?name=%T&m=%!S&ci=%!S",zName,zNew,zCkin))\
@ %h(zName)</a> version %z(href("%R/artifact/%!S",zNew))[%S(zNew)]</a>.
}
if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
if( pCfg ){
@ </span></div>
append_diff(zOld, zNew, pCfg);
}else{
@ %z(href("%R/fdiff?v1=%!S&v2=%!S",zOld,zNew))[diff]</a>
@ </span></div>
}
}else{
@ </span></div>
}
}
}
/*
** Generate javascript to enhance HTML diffs.
*/
void append_diff_javascript(int diffType){
if( diffType==0 ) return;
|
| ︙ | ︙ | |||
600 601 602 603 604 605 606 607 608 609 610 611 612 613 |
blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC");
db_prepare(&q, "%s", blob_sql_text(&sql));
www_print_timeline(&q, TIMELINE_DISJOINT|TIMELINE_GRAPH|TIMELINE_NOSCROLL,
0, 0, 0, rid, 0, 0);
db_finalize(&q);
style_finish_page();
}
/*
** WEBPAGE: vinfo
** WEBPAGE: ci
** URL: /ci/ARTIFACTID
** OR: /ci?name=ARTIFACTID
**
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 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 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 |
blob_append_sql(&sql, " AND event.objid IN ok ORDER BY mtime DESC");
db_prepare(&q, "%s", blob_sql_text(&sql));
www_print_timeline(&q, TIMELINE_DISJOINT|TIMELINE_GRAPH|TIMELINE_NOSCROLL,
0, 0, 0, rid, 0, 0);
db_finalize(&q);
style_finish_page();
}
/*
** Render a web-page diff of the changes in the working check-out
*/
static void ckout_normal_diff(int vid){
int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
DiffConfig DCfg,*pCfg; /* Diff details */
const char *zW; /* The "w" query parameter */
int nChng; /* Number of changes */
Stmt q;
diffType = preferred_diff_type();
pCfg = construct_diff_flags(diffType, &DCfg);
nChng = db_int(0, "SELECT count(*) FROM vfile"
" WHERE vid=%d AND (deleted OR chnged OR rid==0)", vid);
if( nChng==0 ){
@ <p>No uncommitted changes</p>
return;
}
db_prepare(&q,
/* 0 1 2 3 4 5 6 */
"SELECT pathname, deleted, chnged , rid==0, rid, islink, uuid"
" FROM vfile LEFT JOIN blob USING(rid)"
" WHERE vid=%d"
" AND (deleted OR chnged OR rid==0)"
" ORDER BY pathname /*scan*/",
vid
);
if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
}else{
DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
}
@ <div class="sectionmenu info-changes-menu">
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
if( diffType!=1 ){
@ %z(chref("button","%R?diff=1%s",zW))Unified Diff</a>
}
if( diffType!=2 ){
@ %z(chref("button","%R?diff=2%s",zW))Side-by-Side Diff</a>
}
if( diffType!=0 ){
if( *zW ){
@ %z(chref("button","%R?diff=%d",diffType))\
@ Show Whitespace Changes</a>
}else{
@ %z(chref("button","%R?diff=%d&w",diffType))Ignore Whitespace</a>
}
}
@ </div>
while( db_step(&q)==SQLITE_ROW ){
const char *zTreename = db_column_text(&q,0);
int isDeleted = db_column_int(&q, 1);
int isChnged = db_column_int(&q,2);
int isNew = db_column_int(&q,3);
int srcid = db_column_int(&q, 4);
int isLink = db_column_int(&q, 5);
const char *zUuid = db_column_text(&q, 6);
int showDiff = 1;
DCfg.diffFlags &= (~DIFF_FILE_MASK);
@ <div class='file-change-line'><span>
if( isDeleted ){
@ DELETED %h(zTreename)
DCfg.diffFlags |= DIFF_FILE_DELETED;
showDiff = 0;
}else if( file_access(zTreename, F_OK) ){
@ MISSING %h(zTreename)
showDiff = 0;
}else if( isNew ){
@ ADDED %h(zTreename)
DCfg.diffFlags |= DIFF_FILE_ADDED;
srcid = 0;
showDiff = 0;
}else if( isChnged==3 ){
@ ADDED_BY_MERGE %h(zTreename)
DCfg.diffFlags |= DIFF_FILE_ADDED;
srcid = 0;
showDiff = 0;
}else if( isChnged==5 ){
@ ADDED_BY_INTEGRATE %h(zTreename)
DCfg.diffFlags |= DIFF_FILE_ADDED;
srcid = 0;
showDiff = 0;
}else{
@ CHANGED %h(zTreename)
}
@ </span></div>
if( showDiff && pCfg ){
Blob old, new;
if( !isLink != !file_islink(zTreename) ){
@ %s(DIFF_CANNOT_COMPUTE_SYMLINK)
continue;
}
if( srcid>0 ){
content_get(srcid, &old);
pCfg->zLeftHash = zUuid;
}else{
blob_zero(&old);
pCfg->zLeftHash = 0;
}
blob_read_from_file(&new, zTreename, ExtFILE);
text_diff(&old, &new, cgi_output_blob(), pCfg);
blob_reset(&old);
blob_reset(&new);
}
}
db_finalize(&q);
append_diff_javascript(diffType);
}
/*
** Render a web-page diff of the changes in the working check-out to
** an external reference.
*/
static void ckout_external_base_diff(int vid, const char *zExBase){
int diffType; /* 0: no diff, 1: unified, 2: side-by-side */
DiffConfig DCfg,*pCfg; /* Diff details */
const char *zW; /* The "w" query parameter */
Stmt q;
diffType = preferred_diff_type();
pCfg = construct_diff_flags(diffType, &DCfg);
db_prepare(&q,
"SELECT pathname FROM vfile WHERE vid=%d ORDER BY pathname", vid
);
if( DCfg.diffFlags & DIFF_SIDEBYSIDE ){
DCfg.diffFlags |= DIFF_HTML | DIFF_NOTTOOBIG;
}else{
DCfg.diffFlags |= DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG;
}
@ <div class="sectionmenu info-changes-menu">
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
if( diffType!=1 ){
@ %z(chref("button","%R?diff=1&exbase=%h%s",zExBase,zW))\
@ Unified Diff</a>
}
if( diffType!=2 ){
@ %z(chref("button","%R?diff=2&exbase=%h%s",zExBase,zW))\
@ Side-by-Side Diff</a>
}
if( diffType!=0 ){
if( *zW ){
@ %z(chref("button","%R?diff=%d&exbase=%h",diffType,zExBase))\
@ Show Whitespace Changes</a>
}else{
@ %z(chref("button","%R?diff=%d&exbase=%h&w",diffType,zExBase))\
@ Ignore Whitespace</a>
}
}
@ </div>
while( db_step(&q)==SQLITE_ROW ){
const char *zFile; /* Name of file in the repository */
char *zLhs; /* Full name of left-hand side file */
char *zRhs; /* Full name of right-hand side file */
Blob rhs; /* Full text of RHS */
Blob lhs; /* Full text of LHS */
zFile = db_column_text(&q,0);
zLhs = mprintf("%s/%s", zExBase, zFile);
zRhs = mprintf("%s%s", g.zLocalRoot, zFile);
if( file_size(zLhs, ExtFILE)<0 ){
@ <div class='file-change-line'><span>
@ Missing from external baseline: %h(zFile)
@ </span></div>
}else{
blob_read_from_file(&lhs, zLhs, ExtFILE);
blob_read_from_file(&rhs, zRhs, ExtFILE);
if( blob_size(&lhs)!=blob_size(&rhs)
|| memcmp(blob_buffer(&lhs), blob_buffer(&rhs), blob_size(&lhs))!=0
){
@ <div class='file-change-line'><span>
@ Changes to %h(zFile)
@ </span></div>
if( pCfg ){
char *zFullFN;
char *zHexFN;
zFullFN = file_canonical_name_dup(zLhs);
zHexFN = mprintf("x%H", zFullFN);
fossil_free(zFullFN);
pCfg->zLeftHash = zHexFN;
text_diff(&lhs, &rhs, cgi_output_blob(), pCfg);
pCfg->zLeftHash = 0;
fossil_free(zHexFN);
}
}
blob_reset(&lhs);
blob_reset(&rhs);
}
fossil_free(zLhs);
fossil_free(zRhs);
}
db_finalize(&q);
append_diff_javascript(diffType);
}
/*
** WEBPAGE: ckout
**
** Show information about the current checkout. This page only functions
** if the web server is run on a loopback interface (in other words, was
** started using "fossil ui" or similar) from within an open check-out.
**
** If the "exbase=PATH" query parameter is provided, then the diff shown
** uses the files in PATH as the baseline. This is the same as using
** the "--from PATH" argument to the "fossil diff" command-line. In fact,
** when using "fossil ui --from PATH", the --from argument becomes the value
** of the exbase query parameter for the start page. Note that if PATH
** is a pure hexadecimal string, it is decoded first before being used as
** the pathname. Real pathnames should contain at least one directory
** separator character.
**
** Other query parameters related to diffs are also accepted.
*/
void ckout_page(void){
int vid;
const char *zHome; /* Home directory */
int nHome;
const char *zExBase;
char *zHostname;
char *zCwd;
if( !cgi_is_loopback(g.zIpAddr) || !db_open_local(0) ){
cgi_redirectf("%R/home");
return;
}
file_chdir(g.zLocalRoot, 0);
vid = db_lget_int("checkout", 0);
db_unprotect(PROTECT_ALL);
vfile_check_signature(vid, CKSIG_ENOTFILE);
db_protect_pop();
style_set_current_feature("vinfo");
zHostname = fossil_hostname();
zCwd = file_getcwd(0,0);
zHome = fossil_getenv("HOME");
if( zHome ){
nHome = (int)strlen(zHome);
if( strncmp(zCwd, zHome, nHome)==0 && zCwd[nHome]=='/' ){
zCwd = mprintf("~%s", zCwd+nHome);
}
}else{
nHome = 0;
}
if( zHostname ){
style_header("Checkout Status: %h on %h", zCwd, zHostname);
}else{
style_header("Checkout Status: %h", zCwd);
}
render_checkin_context(vid, 0, 0, 0);
@ <hr>
zExBase = P("exbase");
if( zExBase && zExBase[0] ){
char *zPath = decode16_dup(zExBase);
char *zCBase = file_canonical_name_dup(zPath?zPath:zExBase);
if( nHome && strncmp(zCBase, zHome, nHome)==0 && zCBase[nHome]=='/' ){
@ <p>Using external baseline: ~%h(zCBase+nHome)</p>
}else{
@ <p>Using external baseline: %h(zCBase)</p>
}
ckout_external_base_diff(vid, zCBase);
fossil_free(zCBase);
fossil_free(zPath);
}else{
ckout_normal_diff(vid);
}
style_finish_page();
}
/*
** WEBPAGE: vinfo
** WEBPAGE: ci
** URL: /ci/ARTIFACTID
** OR: /ci?name=ARTIFACTID
**
|
| ︙ | ︙ | |||
626 627 628 629 630 631 632 | const char *zName; /* Name of the check-in to be displayed */ const char *zUuid; /* Hash of zName, found via blob.uuid */ const char *zParent; /* Hash of the parent check-in (if any) */ const char *zRe; /* regex parameter */ ReCompiled *pRe = 0; /* regex */ const char *zW; /* URL param for ignoring whitespace */ const char *zPage = "vinfo"; /* Page that shows diffs */ | < | 899 900 901 902 903 904 905 906 907 908 909 910 911 912 |
const char *zName; /* Name of the check-in to be displayed */
const char *zUuid; /* Hash of zName, found via blob.uuid */
const char *zParent; /* Hash of the parent check-in (if any) */
const char *zRe; /* regex parameter */
ReCompiled *pRe = 0; /* regex */
const char *zW; /* URL param for ignoring whitespace */
const char *zPage = "vinfo"; /* Page that shows diffs */
const char *zBrName; /* Branch name */
DiffConfig DCfg,*pCfg; /* Type of diff */
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_set_current_feature("vinfo");
zName = P("name");
|
| ︙ | ︙ | |||
896 897 898 899 900 901 902 | @ </div><div class="section accordion">Changes</div> @ <div class="accordion_panel"> @ <div class="sectionmenu info-changes-menu"> /* ^^^ .info-changes-menu is used by diff scroll sync */ pCfg = construct_diff_flags(diffType, &DCfg); DCfg.pRe = pRe; zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":""; | < < < < | | | 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 |
@ </div><div class="section accordion">Changes</div>
@ <div class="accordion_panel">
@ <div class="sectionmenu info-changes-menu">
/* ^^^ .info-changes-menu is used by diff scroll sync */
pCfg = construct_diff_flags(diffType, &DCfg);
DCfg.pRe = pRe;
zW = (DCfg.diffFlags&DIFF_IGNORE_ALLWS)?"&w":"";
if( diffType!=1 ){
@ %z(chref("button","%R/%s/%T?diff=1%s",zPage,zName,zW))\
@ Unified Diff</a>
}
if( diffType!=2 ){
@ %z(chref("button","%R/%s/%T?diff=2%s",zPage,zName,zW))\
@ Side-by-Side Diff</a>
}
if( diffType!=0 ){
if( *zW ){
@ %z(chref("button","%R/%s/%T",zPage,zName))
@ Show Whitespace Changes</a>
}else{
@ %z(chref("button","%R/%s/%T?w",zPage,zName))
|
| ︙ | ︙ | |||
1266 1267 1268 1269 1270 1271 1272 |
blob_appendf(&qp, "&w");
}
cgi_check_for_malice();
style_set_current_feature("vdiff");
if( zBranch==0 ){
style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
}
| < < < | 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 |
blob_appendf(&qp, "&w");
}
cgi_check_for_malice();
style_set_current_feature("vdiff");
if( zBranch==0 ){
style_submenu_element("Path", "%R/timeline?me=%T&you=%T", zFrom, zTo);
}
if( diffType!=2 ){
style_submenu_element("Side-by-Side Diff", "%R/vdiff?diff=2&%b%b", &qp,
&qpGlob);
}
if( diffType!=1 ) {
style_submenu_element("Unified Diff", "%R/vdiff?diff=1&%b%b", &qp, &qpGlob);
}
|
| ︙ | ︙ | |||
1666 1667 1668 1669 1670 1671 1672 |
blob_append(pDownloadName, zFilename, -1);
}
tag_private_status(rid);
}
db_finalize(&q);
if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d AND tagid=%d",
rid, TAG_CLUSTER) ){
| | | 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 |
blob_append(pDownloadName, zFilename, -1);
}
tag_private_status(rid);
}
db_finalize(&q);
if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d AND tagid=%d",
rid, TAG_CLUSTER) ){
@ Cluster %z(href("%R/info/%S",zUuid))%S(zUuid)</a>.
cnt++;
}
if( cnt==0 ){
@ Unrecognized artifact
if( pDownloadName && blob_size(pDownloadName)==0 ){
blob_appendf(pDownloadName, "%S.txt", zUuid);
}
|
| ︙ | ︙ | |||
1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 |
/*
** WEBPAGE: jchunk hidden
** URL: /jchunk/HASH?from=N&to=M
**
** Return lines of text from a file as a JSON array - one entry in the
** array for each line of text.
**
** **Warning:** This is an internal-use-only interface that is subject to
** change at any moment. External application should not use this interface
** since the application will break when this interface changes, and this
** interface will undoubtedly change.
**
** This page is intended to be used in an XHR from javascript on a
** diff page, to return unseen context to fill in additional context
** when the user clicks on the appropriate button. The response is
** always in JSON form and errors are reported as documented for
** ajax_route_error().
*/
void jchunk_page(void){
int rid = 0;
const char *zName = PD("name", "");
int iFrom = atoi(PD("from","0"));
int iTo = atoi(PD("to","0"));
int ln;
int go = 1;
const char *zSep;
Blob content;
Blob line;
Blob *pOut;
if(0){
ajax_route_error(400, "Just testing client-side error handling.");
return;
}
login_check_credentials();
cgi_check_for_malice();
if( !g.perm.Read ){
ajax_route_error(403, "Access requires Read permissions.");
return;
}
#if 1
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | | | | | | | < < < | < | 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 |
/*
** WEBPAGE: jchunk hidden
** URL: /jchunk/HASH?from=N&to=M
**
** Return lines of text from a file as a JSON array - one entry in the
** array for each line of text.
**
** The HASH is normally a sha1 or sha3 hash that identifies an artifact
** in the BLOB table of the database. However, if HASH starts with an "x"
** and is followed by valid hexadecimal, and if we are running in a
** "fossil ui" situation (locally and with privilege), then decode the hex
** into a filename and read the file content from that name.
**
** **Warning:** This is an internal-use-only interface that is subject to
** change at any moment. External application should not use this interface
** since the application will break when this interface changes, and this
** interface will undoubtedly change.
**
** This page is intended to be used in an XHR from javascript on a
** diff page, to return unseen context to fill in additional context
** when the user clicks on the appropriate button. The response is
** always in JSON form and errors are reported as documented for
** ajax_route_error().
*/
void jchunk_page(void){
int rid = 0;
const char *zName = PD("name", "");
int nName = (int)(strlen(zName)&0x7fffffff);
int iFrom = atoi(PD("from","0"));
int iTo = atoi(PD("to","0"));
int ln;
int go = 1;
const char *zSep;
Blob content;
Blob line;
Blob *pOut;
if(0){
ajax_route_error(400, "Just testing client-side error handling.");
return;
}
login_check_credentials();
cgi_check_for_malice();
if( !g.perm.Read ){
ajax_route_error(403, "Access requires Read permissions.");
return;
}
if( iFrom<1 || iTo<iFrom ){
ajax_route_error(500, "Invalid line range from=%d, to=%d.",
iFrom, iTo);
return;
}
if( zName[0]=='x'
&& ((nName-1)&1)==0
&& validate16(&zName[1],nName-1)
&& g.perm.Admin
&& cgi_is_loopback(g.zIpAddr)
&& db_open_local(0)
){
/* Treat the HASH as a hex-encoded filename */
int n = (nName-1)/2;
char *zFN = fossil_malloc(n+1);
decode16((const u8*)&zName[1], (u8*)zFN, nName-1);
zFN[n] = 0;
if( file_size(zFN, ExtFILE)<0 ){
blob_zero(&content);
}else{
blob_read_from_file(&content, zFN, ExtFILE);
}
fossil_free(zFN);
}else{
/* Treat the HASH as an artifact hash matching BLOB.UUID */
#if 1
/* Re-enable this block once this code is integrated somewhere into
the UI. */
rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zName);
if( rid==0 ){
ajax_route_error(404, "Unknown artifact: %h", zName);
return;
}
#else
/* This impl is only to simplify "manual" testing via the JS
console. */
rid = symbolic_name_to_rid(zName, "*");
if( rid==0 ){
ajax_route_error(404, "Unknown artifact: %h", zName);
return;
}else if( rid<0 ){
ajax_route_error(418, "Ambiguous artifact name: %h", zName);
return;
}
#endif
content_get(rid, &content);
}
g.isConst = 1;
cgi_set_content_type("application/json");
ln = 0;
while( go && ln<iFrom ){
go = blob_line(&content, &line);
ln++;
}
|
| ︙ | ︙ | |||
2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 | @ <div class="section">Changes</div> @ <p> ticket_output_change_artifact(pTktChng, 0, 1, 0); manifest_destroy(pTktChng); style_finish_page(); } /* ** WEBPAGE: info ** URL: info/NAME ** ** The NAME argument is any valid artifact name: an artifact hash, ** a timestamp, a tag name, etc. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 |
@ <div class="section">Changes</div>
@ <p>
ticket_output_change_artifact(pTktChng, 0, 1, 0);
manifest_destroy(pTktChng);
style_finish_page();
}
/*
** rid is a cluster. Paint a page that contains detailed information
** about that cluster.
*/
static void cluster_info(int rid, const char *zName){
Manifest *pCluster;
int i;
Blob where = BLOB_INITIALIZER;
Blob unks = BLOB_INITIALIZER;
Stmt q;
char *zSha1Bg;
char *zSha3Bg;
int badRid = 0;
int rcvid;
int hashClr = PB("hclr");
const char *zDate;
pCluster = manifest_get(rid, CFTYPE_CLUSTER, 0);
if( pCluster==0 ){
artifact_page();
return;
}
style_header("Cluster %S", zName);
rcvid = db_int(0, "SELECT rcvid FROM blob WHERE rid=%d", rid);
if( rcvid==0 ){
zDate = 0;
}else{
zDate = db_text(0, "SELECT datetime(mtime) FROM rcvfrom WHERE rcvid=%d",
rcvid);
}
@ <p>Artifact %z(href("%R/artifact/%h",zName))%S(zName)</a> is a cluster
@ with %d(pCluster->nCChild) entries
if( g.perm.Admin ){
@ received <a href="%R/rcvfrom?rcvid=%d(rcvid)">%h(zDate)</a>:
}else{
@ received %h(zDate):
}
blob_appendf(&where,"IN(0");
for(i=0; i<pCluster->nCChild; i++){
int rid = fast_uuid_to_rid(pCluster->azCChild[i]);
if( rid ){
blob_appendf(&where,",%d", rid);
}else{
if( blob_size(&unks)>0 ) blob_append_char(&unks, ',');
badRid++;
blob_append_sql(&unks,"(%d,%Q)",-badRid,pCluster->azCChild[i]);
}
}
blob_append_char(&where,')');
describe_artifacts(blob_str(&where));
blob_reset(&where);
if( badRid>0 ){
db_multi_exec(
"WITH unks(rx,hx) AS (VALUES %s)\n"
"INSERT INTO description(rid,uuid,type,summary) "
" SELECT rx, hx, 'phantom', '' FROM unks;",
blob_sql_text(&unks)
);
}
blob_reset(&unks);
db_prepare(&q,
"SELECT rid, uuid, summary, isPrivate, type='phantom', rcvid, ref"
" FROM description ORDER BY uuid"
);
if( skin_detail_boolean("white-foreground") ){
zSha1Bg = "#714417";
zSha3Bg = "#177117";
}else{
zSha1Bg = "#ebffb0";
zSha3Bg = "#b0ffb0";
}
@ <table cellpadding="2" cellspacing="0" border="1">
if( g.perm.Admin ){
@ <tr><th>RID<th>Hash<th>Rcvid<th>Description<th>Ref<th>Remarks
}else{
@ <tr><th>RID<th>Hash<th>Description<th>Ref<th>Remarks
}
while( db_step(&q)==SQLITE_ROW ){
int rid = db_column_int(&q,0);
const char *zUuid = db_column_text(&q, 1);
const char *zDesc = db_column_text(&q, 2);
int isPriv = db_column_int(&q,3);
int isPhantom = db_column_int(&q,4);
const char *zRef = db_column_text(&q,6);
if( isPriv && !isPhantom && !g.perm.Private && !g.perm.Admin ){
/* Don't show private artifacts to users without Private (x) permission */
continue;
}
if( rid<=0 ){
@ <tr><td> </td>
}else if( hashClr ){
const char *zClr = db_column_bytes(&q,1)>40 ? zSha3Bg : zSha1Bg;
@ <tr style='background-color:%s(zClr);'><td align="right">%d(rid)</td>
}else{
@ <tr><td align="right">%d(rid)</td>
}
if( rid<=0 ){
@ <td> %S(zUuid) </td>
}else{
@ <td> %z(href("%R/info/%!S",zUuid))%S(zUuid)</a> </td>
}
if( g.perm.Admin ){
int rcvid = db_column_int(&q,5);
if( rcvid<=0 ){
@ <td>
}else{
@ <td><a href='%R/rcvfrom?rcvid=%d(rcvid)'>%d(rcvid)</a>
}
}
@ <td align="left">%h(zDesc)</td>
if( zRef && zRef[0] ){
@ <td>%z(href("%R/info/%!S",zRef))%S(zRef)</a>
}else{
@ <td>
}
if( isPriv || isPhantom ){
if( isPriv==0 ){
@ <td>phantom</td>
}else if( isPhantom==0 ){
@ <td>private</td>
}else{
@ <td>private,phantom</td>
}
}else{
@ <td>
}
@ </tr>
}
@ </table>
db_finalize(&q);
style_finish_page();
}
/*
** WEBPAGE: info
** URL: info/NAME
**
** The NAME argument is any valid artifact name: an artifact hash,
** a timestamp, a tag name, etc.
|
| ︙ | ︙ | |||
2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 |
ci_page();
}else
if( db_exists("SELECT 1 FROM plink WHERE pid=%d", rid) ){
ci_page();
}else
if( db_exists("SELECT 1 FROM attachment WHERE attachid=%d", rid) ){
ainfo_page();
}else
{
artifact_page();
}
}
/*
| > > > > | 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 |
ci_page();
}else
if( db_exists("SELECT 1 FROM plink WHERE pid=%d", rid) ){
ci_page();
}else
if( db_exists("SELECT 1 FROM attachment WHERE attachid=%d", rid) ){
ainfo_page();
}else
if( db_exists("SELECT 1 FROM tagxref WHERE rid=%d AND tagid=%d",
rid, TAG_CLUSTER) ){
cluster_info(rid, zName);
}else
{
artifact_page();
}
}
/*
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 |
while( find_option("verbose","v",0)!=0 ) verboseFlag++;
while( find_option("vv",0,0)!=0 ) verboseFlag += 2;
/* We should be done with options.. */
verify_all_options();
fossil_version_blob(&versionInfo, verboseFlag);
fossil_print("%s", blob_str(&versionInfo));
}
/*
** WEBPAGE: version
**
** Show the version information for Fossil.
| > | 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 |
while( find_option("verbose","v",0)!=0 ) verboseFlag++;
while( find_option("vv",0,0)!=0 ) verboseFlag += 2;
/* We should be done with options.. */
verify_all_options();
fossil_version_blob(&versionInfo, verboseFlag);
fossil_print("%s", blob_str(&versionInfo));
blob_reset(&versionInfo);
}
/*
** WEBPAGE: version
**
** Show the version information for Fossil.
|
| ︙ | ︙ | |||
1632 1633 1634 1635 1636 1637 1638 | exit(1); } /* ** Return true if it is appropriate to redirect requests to HTTPS. ** ** Redirect to https is appropriate if all of the above are true: | | | 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 |
exit(1);
}
/*
** Return true if it is appropriate to redirect requests to HTTPS.
**
** Redirect to https is appropriate if all of the above are true:
** (1) The redirect-to-https flag has a value of iLevel or greater.
** (2) The current connection is http, not https or ssh
** (3) The sslNotAvailable flag is clear
*/
int fossil_wants_https(int iLevel){
if( g.sslNotAvailable ) return 0;
if( db_get_int("redirect-to-https",0)<iLevel ) return 0;
if( P("HTTPS")!=0 ) return 0;
|
| ︙ | ︙ | |||
2038 2039 2040 2041 2042 2043 2044 |
/* Use the first element of PATH_INFO as the page name
** and deliver the appropriate page back to the user.
*/
set_base_url(0);
if( fossil_redirect_to_https_if_needed(2) ) return;
if( zPathInfo==0 || zPathInfo[0]==0
|| (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
| | > | > | > > > > | > | 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 |
/* Use the first element of PATH_INFO as the page name
** and deliver the appropriate page back to the user.
*/
set_base_url(0);
if( fossil_redirect_to_https_if_needed(2) ) return;
if( zPathInfo==0 || zPathInfo[0]==0
|| (zPathInfo[0]=='/' && zPathInfo[1]==0) ){
/* Second special case: If the PATH_INFO is blank, issue a redirect:
** (1) to "/ckout" if g.useLocalauth and g.localOpen are both set.
** (2) to the home page identified by the "index-page" setting
** in the repository CONFIG table
** (3) to "/index" if there no "index-page" setting in CONFIG
*/
#ifdef FOSSIL_ENABLE_JSON
if(g.json.isJsonMode){
json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
fossil_exit(0);
}
#endif
if( g.useLocalauth && g.localOpen ){
cgi_redirectf("%R/ckout");
}else{
fossil_redirect_home() /*does not return*/;
}
}else{
zPath = mprintf("%s", zPathInfo);
}
/* Make g.zPath point to the first element of the path. Make
** g.zExtra point to everything past that point.
*/
|
| ︙ | ︙ | |||
2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 |
}else{
g.httpOut = stdout;
#if defined(_WIN32)
_setmode(_fileno(stdout), _O_BINARY);
#endif
}
zIpAddr = find_option("ipaddr",0,1);
useSCGI = find_option("scgi", 0, 0)!=0;
if( useSCGI ) g.zReqType = "SCGI";
zAltBase = find_option("baseurl", 0, 1);
if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
if( zAltBase ) set_base_url(zAltBase);
if( find_option("https",0,0)!=0 ){
zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
| > > > > > > > > > > > > > | 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 |
}else{
g.httpOut = stdout;
#if defined(_WIN32)
_setmode(_fileno(stdout), _O_BINARY);
#endif
}
zIpAddr = find_option("ipaddr",0,1);
#if defined(_WIN32)
/* The undocumented option "--as NAME" causes NAME to become
** the fake command name. This only happens on Windows and only
** if preceded by --in, --out, and --ipaddr. It is a work-around
** to get the original command-name down into the "http" command that
** is run in a subprocess to manage HTTP requests on Windows for
** commands like "fossil ui" and "fossil server".
*/
if( zInFile && zOutFile && zIpAddr ){
const char *z = find_option("as",0,1);
if( z ) g.zCmdName = z;
}
#endif
useSCGI = find_option("scgi", 0, 0)!=0;
if( useSCGI ) g.zReqType = "SCGI";
zAltBase = find_option("baseurl", 0, 1);
if( find_option("nodelay",0,0)!=0 ) backoffice_no_delay();
if( zAltBase ) set_base_url(zAltBase);
if( find_option("https",0,0)!=0 ){
zIpAddr = fossil_getenv("REMOTE_HOST"); /* From stunnel */
|
| ︙ | ︙ | |||
3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 | ** /doc/ckout/... ** --create Create a new REPOSITORY if it does not already exist ** --errorlog FILE Append HTTP error messages to FILE ** --extroot DIR Document root for the /ext extension mechanism ** --files GLOBLIST Comma-separated list of glob patterns for static files ** --fossilcmd PATH The pathname of the "fossil" executable on the remote ** system when REPOSITORY is remote. ** --localauth Enable automatic login for requests from localhost ** --localhost Listen on 127.0.0.1 only (always true for "ui") ** --https Indicates that the input is coming through a reverse ** proxy that has already translated HTTPS into HTTP. ** --jsmode MODE Determine how JavaScript is delivered with pages. ** Mode can be one of: ** inline All JavaScript is inserted inline at | > | 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 | ** /doc/ckout/... ** --create Create a new REPOSITORY if it does not already exist ** --errorlog FILE Append HTTP error messages to FILE ** --extroot DIR Document root for the /ext extension mechanism ** --files GLOBLIST Comma-separated list of glob patterns for static files ** --fossilcmd PATH The pathname of the "fossil" executable on the remote ** system when REPOSITORY is remote. ** --from PATH Use PATH as the diff baseline for the /ckout page ** --localauth Enable automatic login for requests from localhost ** --localhost Listen on 127.0.0.1 only (always true for "ui") ** --https Indicates that the input is coming through a reverse ** proxy that has already translated HTTPS into HTTP. ** --jsmode MODE Determine how JavaScript is delivered with pages. ** Mode can be one of: ** inline All JavaScript is inserted inline at |
| ︙ | ︙ | |||
3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 | int fCreate = 0; /* The --create flag */ int fNoBrowser = 0; /* Do not auto-launch web-browser */ const char *zInitPage = 0; /* Start on this page. --page option */ int findServerArg = 2; /* argv index for find_server_repository() */ char *zRemote = 0; /* Remote host on which to run "fossil ui" */ const char *zJsMode; /* The --jsmode parameter */ const char *zFossilCmd =0; /* Name of "fossil" binary on remote system */ #if USE_SEE db_setup_for_saved_encryption_key(); #endif #if defined(_WIN32) | > | 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 | int fCreate = 0; /* The --create flag */ int fNoBrowser = 0; /* Do not auto-launch web-browser */ const char *zInitPage = 0; /* Start on this page. --page option */ int findServerArg = 2; /* argv index for find_server_repository() */ char *zRemote = 0; /* Remote host on which to run "fossil ui" */ const char *zJsMode; /* The --jsmode parameter */ const char *zFossilCmd =0; /* Name of "fossil" binary on remote system */ const char *zFrom; /* Value for --from */ #if USE_SEE db_setup_for_saved_encryption_key(); #endif #if defined(_WIN32) |
| ︙ | ︙ | |||
3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 |
zTimeout = find_option("max-latency",0,1);
#endif
g.useLocalauth = find_option("localauth", 0, 0)!=0;
Th_InitTraceLog();
zPort = find_option("port", "P", 1);
isUiCmd = g.argv[1][0]=='u';
if( isUiCmd ){
zInitPage = find_option("page", "p", 1);
if( zInitPage && zInitPage[0]=='/' ) zInitPage++;
zFossilCmd = find_option("fossilcmd", 0, 1);
}
zNotFound = find_option("notfound", 0, 1);
allowRepoList = find_option("repolist",0,0)!=0;
if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1;
zAltBase = find_option("baseurl", 0, 1);
fCreate = find_option("create",0,0)!=0;
g.zReqType = "HTTP";
| > > > > > > > > | 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 |
zTimeout = find_option("max-latency",0,1);
#endif
g.useLocalauth = find_option("localauth", 0, 0)!=0;
Th_InitTraceLog();
zPort = find_option("port", "P", 1);
isUiCmd = g.argv[1][0]=='u';
if( isUiCmd ){
zFrom = find_option("from", 0, 1);
if( zFrom && zFrom==file_tail(zFrom) ){
fossil_fatal("the argument to --from must be a pathname for"
" the \"ui\" command");
}
zInitPage = find_option("page", "p", 1);
if( zInitPage && zInitPage[0]=='/' ) zInitPage++;
zFossilCmd = find_option("fossilcmd", 0, 1);
if( zFrom && zInitPage==0 ){
zInitPage = mprintf("ckout?exbase=%H", zFrom);
}
}
zNotFound = find_option("notfound", 0, 1);
allowRepoList = find_option("repolist",0,0)!=0;
if( find_option("nocompress",0,0)!=0 ) g.fNoHttpCompress = 1;
zAltBase = find_option("baseurl", 0, 1);
fCreate = find_option("create",0,0)!=0;
g.zReqType = "HTTP";
|
| ︙ | ︙ | |||
3382 3383 3384 3385 3386 3387 3388 |
g.useLocalauth = 1;
allowRepoList = 1;
}
if( !zRemote ){
find_server_repository(findServerArg, fCreate);
}
if( zInitPage==0 ){
| < < < | < | 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 |
g.useLocalauth = 1;
allowRepoList = 1;
}
if( !zRemote ){
find_server_repository(findServerArg, fCreate);
}
if( zInitPage==0 ){
zInitPage = "";
}
if( zPort ){
if( strchr(zPort,':') ){
int i;
for(i=strlen(zPort)-1; i>=0 && zPort[i]!=':'; i--){}
if( i>0 ){
if( zPort[0]=='[' && zPort[i-1]==']' ){
|
| ︙ | ︙ |
Changes to src/main.mk.
| ︙ | ︙ | |||
97 98 99 100 101 102 103 104 105 106 107 108 109 110 | $(SRCDIR)/loadctrl.c \ $(SRCDIR)/login.c \ $(SRCDIR)/lookslike.c \ $(SRCDIR)/main.c \ $(SRCDIR)/manifest.c \ $(SRCDIR)/markdown.c \ $(SRCDIR)/markdown_html.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/moderate.c \ $(SRCDIR)/name.c \ $(SRCDIR)/patch.c \ $(SRCDIR)/path.c \ | > | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | $(SRCDIR)/loadctrl.c \ $(SRCDIR)/login.c \ $(SRCDIR)/lookslike.c \ $(SRCDIR)/main.c \ $(SRCDIR)/manifest.c \ $(SRCDIR)/markdown.c \ $(SRCDIR)/markdown_html.c \ $(SRCDIR)/match.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/moderate.c \ $(SRCDIR)/name.c \ $(SRCDIR)/patch.c \ $(SRCDIR)/path.c \ |
| ︙ | ︙ | |||
362 363 364 365 366 367 368 369 370 371 372 373 374 375 | $(OBJDIR)/loadctrl_.c \ $(OBJDIR)/login_.c \ $(OBJDIR)/lookslike_.c \ $(OBJDIR)/main_.c \ $(OBJDIR)/manifest_.c \ $(OBJDIR)/markdown_.c \ $(OBJDIR)/markdown_html_.c \ $(OBJDIR)/md5_.c \ $(OBJDIR)/merge_.c \ $(OBJDIR)/merge3_.c \ $(OBJDIR)/moderate_.c \ $(OBJDIR)/name_.c \ $(OBJDIR)/patch_.c \ $(OBJDIR)/path_.c \ | > | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | $(OBJDIR)/loadctrl_.c \ $(OBJDIR)/login_.c \ $(OBJDIR)/lookslike_.c \ $(OBJDIR)/main_.c \ $(OBJDIR)/manifest_.c \ $(OBJDIR)/markdown_.c \ $(OBJDIR)/markdown_html_.c \ $(OBJDIR)/match_.c \ $(OBJDIR)/md5_.c \ $(OBJDIR)/merge_.c \ $(OBJDIR)/merge3_.c \ $(OBJDIR)/moderate_.c \ $(OBJDIR)/name_.c \ $(OBJDIR)/patch_.c \ $(OBJDIR)/path_.c \ |
| ︙ | ︙ | |||
511 512 513 514 515 516 517 518 519 520 521 522 523 524 | $(OBJDIR)/loadctrl.o \ $(OBJDIR)/login.o \ $(OBJDIR)/lookslike.o \ $(OBJDIR)/main.o \ $(OBJDIR)/manifest.o \ $(OBJDIR)/markdown.o \ $(OBJDIR)/markdown_html.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/moderate.o \ $(OBJDIR)/name.o \ $(OBJDIR)/patch.o \ $(OBJDIR)/path.o \ | > | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | $(OBJDIR)/loadctrl.o \ $(OBJDIR)/login.o \ $(OBJDIR)/lookslike.o \ $(OBJDIR)/main.o \ $(OBJDIR)/manifest.o \ $(OBJDIR)/markdown.o \ $(OBJDIR)/markdown_html.o \ $(OBJDIR)/match.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/moderate.o \ $(OBJDIR)/name.o \ $(OBJDIR)/patch.o \ $(OBJDIR)/path.o \ |
| ︙ | ︙ | |||
586 587 588 589 590 591 592 593 594 595 596 597 598 599 | codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1 $(OBJDIR)/codecheck1 $(TRANS_SRC) $(OBJDIR): -mkdir $(OBJDIR) $(OBJDIR)/translate: $(SRCDIR_tools)/translate.c $(XBCC) -o $(OBJDIR)/translate $(SRCDIR_tools)/translate.c $(OBJDIR)/makeheaders: $(SRCDIR_tools)/makeheaders.c $(XBCC) -o $(OBJDIR)/makeheaders $(SRCDIR_tools)/makeheaders.c $(OBJDIR)/mkindex: $(SRCDIR_tools)/mkindex.c $(XBCC) -o $(OBJDIR)/mkindex $(SRCDIR_tools)/mkindex.c | > | 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 | codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1 $(OBJDIR)/codecheck1 $(TRANS_SRC) $(OBJDIR): -mkdir $(OBJDIR) $(OBJDIR)/translate: $(SRCDIR_tools)/translate.c -mkdir -p $(OBJDIR) $(XBCC) -o $(OBJDIR)/translate $(SRCDIR_tools)/translate.c $(OBJDIR)/makeheaders: $(SRCDIR_tools)/makeheaders.c $(XBCC) -o $(OBJDIR)/makeheaders $(SRCDIR_tools)/makeheaders.c $(OBJDIR)/mkindex: $(SRCDIR_tools)/mkindex.c $(XBCC) -o $(OBJDIR)/mkindex $(SRCDIR_tools)/mkindex.c |
| ︙ | ︙ | |||
642 643 644 645 646 647 648 649 650 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
| > | | | 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP
# Setup the options used to compile the included SQLite shell.
|
| ︙ | ︙ | |||
667 668 669 670 671 672 673 674 675 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
| > | | | 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-Dmain=sqlite3_shell \
-DSQLITE_SHELL_IS_UTF8=1 \
|
| ︙ | ︙ | |||
846 847 848 849 850 851 852 853 854 855 856 857 858 859 | $(OBJDIR)/loadctrl_.c:$(OBJDIR)/loadctrl.h \ $(OBJDIR)/login_.c:$(OBJDIR)/login.h \ $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h \ $(OBJDIR)/main_.c:$(OBJDIR)/main.h \ $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \ $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \ $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \ $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \ $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h \ $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h \ $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \ $(OBJDIR)/name_.c:$(OBJDIR)/name.h \ $(OBJDIR)/patch_.c:$(OBJDIR)/patch.h \ $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ | > | 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 | $(OBJDIR)/loadctrl_.c:$(OBJDIR)/loadctrl.h \ $(OBJDIR)/login_.c:$(OBJDIR)/login.h \ $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h \ $(OBJDIR)/main_.c:$(OBJDIR)/main.h \ $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \ $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \ $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \ $(OBJDIR)/match_.c:$(OBJDIR)/match.h \ $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \ $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h \ $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h \ $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \ $(OBJDIR)/name_.c:$(OBJDIR)/name.h \ $(OBJDIR)/patch_.c:$(OBJDIR)/patch.h \ $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ |
| ︙ | ︙ | |||
1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 | $(OBJDIR)/markdown_html_.c: $(SRCDIR)/markdown_html.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/markdown_html.c >$@ $(OBJDIR)/markdown_html.o: $(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/markdown_html.o -c $(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h: $(OBJDIR)/headers $(OBJDIR)/md5_.c: $(SRCDIR)/md5.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/md5.c >$@ $(OBJDIR)/md5.o: $(OBJDIR)/md5_.c $(OBJDIR)/md5.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/md5.o -c $(OBJDIR)/md5_.c | > > > > > > > > | 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 | $(OBJDIR)/markdown_html_.c: $(SRCDIR)/markdown_html.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/markdown_html.c >$@ $(OBJDIR)/markdown_html.o: $(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/markdown_html.o -c $(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h: $(OBJDIR)/headers $(OBJDIR)/match_.c: $(SRCDIR)/match.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/match.c >$@ $(OBJDIR)/match.o: $(OBJDIR)/match_.c $(OBJDIR)/match.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/match.o -c $(OBJDIR)/match_.c $(OBJDIR)/match.h: $(OBJDIR)/headers $(OBJDIR)/md5_.c: $(SRCDIR)/md5.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/md5.c >$@ $(OBJDIR)/md5.o: $(OBJDIR)/md5_.c $(OBJDIR)/md5.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/md5.o -c $(OBJDIR)/md5_.c |
| ︙ | ︙ |
Changes to src/manifest.c.
| ︙ | ︙ | |||
316 317 318 319 320 321 322 |
/*
** Remove the PGP signature from the artifact, if there is one.
*/
static void remove_pgp_signature(const char **pz, int *pn){
const char *z = *pz;
int n = *pn;
int i;
| | > > | > | > | 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 |
/*
** Remove the PGP signature from the artifact, if there is one.
*/
static void remove_pgp_signature(const char **pz, int *pn){
const char *z = *pz;
int n = *pn;
int i;
if( strncmp(z, "-----BEGIN PGP SIGNED MESSAGE-----", 34)==0 ) i = 34;
else if( strncmp(z, "-----BEGIN SSH SIGNED MESSAGE-----", 34)==0 ) i = 34;
else return;
for(; i<n && !after_blank_line(z+i); i++){}
if( i>=n ) return;
z += i;
n -= i;
*pz = z;
for(i=n-1; i>=0; i--){
if( z[i]=='\n' &&
(strncmp(&z[i],"\n-----BEGIN PGP SIGNATURE-----", 29)==0
|| strncmp(&z[i],"\n-----BEGIN SSH SIGNATURE-----", 29)==0 )){
n = i+1;
break;
}
}
*pn = n;
return;
}
|
| ︙ | ︙ |
Added src/match.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 73 74 75 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 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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 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 233 234 235 236 237 238 239 240 241 242 243 244 245 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 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 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 |
/*
** Copyright (c) 2007 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code to implement string comparisons using a
** variety of algorithm. The comparison algorithm can be any of:
**
** MS_EXACT The string must exactly match the pattern.
**
** MS_BRLIST The pattern is a space- and/or comma-separated
** list of strings, any one of which may match
** the input string.
**
** MS_GLOB Like BRLIST, except each component of the pattern
** is a GLOB expression.
**
** MS_LIKE Like BRLIST, except each component of the pattern
** is an SQL LIKE expression.
**
** MS_REGEXP Like BRLIST, except each component of the pattern
** is a regular expression.
**
*/
#include "config.h"
#include <string.h>
#include "match.h"
#if INTERFACE
/*
** Types of comparisons that we are able to perform:
*/
typedef enum {
MS_EXACT=1, /* Exact string comparison */
MS_GLOB=2, /* Matches against a list of GLOB patterns. */
MS_LIKE=3, /* Matches against a list of LIKE patterns. */
MS_REGEXP=4, /* Matches against a list of regular expressions. */
MS_BRLIST=5, /* Matches any element of a list */
} MatchStyle;
/*
** The following object represents a precompiled pattern to use for
** string matching.
**
** * Create an instance of this object using match_create().
** * Do comparisons using match_text().
** * Destroy using match_free() when you are done.
**
*/
struct Matcher {
MatchStyle style; /* Which algorithm to use */
int nPattern; /* How many patterns are their */
char **azPattern; /* List of patterns */
ReCompiled **aRe; /* List of compiled regular expressions */
};
#endif /*INTERFACE*/
/*
** Translate a "match style" text name into the MS_* enum value.
** Return eDflt if no match is found.
*/
MatchStyle match_style(const char *zStyle, MatchStyle eDflt){
if( zStyle==0 ) return eDflt;
if( fossil_stricmp(zStyle, "brlist")==0 ) return MS_BRLIST;
if( fossil_stricmp(zStyle, "list")==0 ) return MS_BRLIST;
if( fossil_stricmp(zStyle, "regexp")==0 ) return MS_REGEXP;
if( fossil_stricmp(zStyle, "re")==0 ) return MS_REGEXP;
if( fossil_stricmp(zStyle, "glob")==0 ) return MS_GLOB;
if( fossil_stricmp(zStyle, "like")==0 ) return MS_LIKE;
if( fossil_stricmp(zStyle, "exact")==0 ) return MS_EXACT;
return eDflt;
}
/*
** Create a new Matcher object using the pattern provided.
*/
Matcher *match_create(MatchStyle style, const char *zPat){
char cDel; /* Delimiter character */
int i; /* Loop counter */
Matcher *p; /* The new Matcher to be constructed */
char *zOne; /* One element of the pattern */
if( zPat==0 ) return 0;
p = fossil_malloc( sizeof(*p) );
memset(p, 0, sizeof(*p));
p->style = style;
if( style==MS_EXACT ){
p->nPattern = 1;
p->azPattern = fossil_malloc( sizeof(p->azPattern[0]) );
p->azPattern[0] = fossil_strdup(zPat);
return p;
}
while( 1 ){
/* Skip leading delimiters. */
for( ; fossil_isspace(*zPat) || *zPat==','; ++zPat );
/* Next non-delimiter character determines quoting. */
if( zPat[0]==0 ){
/* Terminate loop at end of string. */
break;
}else if( zPat[0]=='\'' || zPat[0]=='"' ){
/* If word is quoted, prepare to stop at end quote. */
cDel = zPat[0];
++zPat;
}else{
/* If word is not quoted, prepare to stop at delimiter. */
cDel = ',';
}
/* Find the next delimiter character or end of string. */
for( i=0; zPat[i] && zPat[i]!=cDel; ++i ){
/* If delimiter is comma, also recognize spaces as delimiters. */
if( cDel==',' && fossil_isspace(zPat[i]) ){
break;
}
/* In regexp mode, ignore delimiters following backslashes. */
if( style==MS_REGEXP && zPat[i]=='\\' && zPat[i+1] ){
++i;
}
}
/* zOne is a zero-terminated copy of the pattern, without delimiters */
zOne = fossil_strndup(zPat, i);
zPat += i;
if( zPat[0] ) zPat++;
/* Check for regular expression syntax errors. */
if( style==MS_REGEXP ){
ReCompiled *regexp;
const char *zFail = re_compile(®exp, zOne, 0);
if( zFail ){
re_free(regexp);
continue;
}
p->nPattern++;
p->aRe = fossil_realloc(p->aRe, sizeof(p->aRe)*p->nPattern);
p->aRe[p->nPattern-1] = regexp;
fossil_free(zOne);
}else{
p->nPattern++;
p->azPattern = fossil_realloc(p->azPattern, sizeof(char*)*p->nPattern);
p->azPattern[p->nPattern-1] = zOne;
}
}
return p;
}
/*
** Return non-zero (true) if the input string matches the pattern
** described by the matcher.
**
** The return value is really the 1-based index of the particular
** pattern that matched.
*/
int match_text(Matcher *p, const char *zText){
int i;
if( p==0 ){
return zText==0;
}
switch( p->style ){
case MS_BRLIST:
case MS_EXACT: {
for(i=0; i<p->nPattern; i++){
if( strcmp(p->azPattern[i], zText)==0 ) return i+1;
}
break;
}
case MS_GLOB: {
for(i=0; i<p->nPattern; i++){
if( sqlite3_strglob(p->azPattern[i], zText)==0 ) return i+1;
}
break;
}
case MS_LIKE: {
for(i=0; i<p->nPattern; i++){
if( sqlite3_strlike(p->azPattern[i], zText, 0)==0 ) return i+1;
}
break;
}
case MS_REGEXP: {
int nText = (int)strlen(zText);
for(i=0; i<p->nPattern; i++){
if( re_match(p->aRe[i], (const u8*)zText, nText) ) return i+1;
}
break;
}
}
return 0;
}
/*
** Destroy a previously allocated Matcher object.
*/
void match_free(Matcher *p){
int i;
if( p==0 ) return;
if( p->style==MS_REGEXP ){
for(i=0; i<p->nPattern; i++) re_free(p->aRe[i]);
fossil_free(p->aRe);
}else{
for(i=0; i<p->nPattern; i++) fossil_free(p->azPattern[i]);
fossil_free(p->azPattern);
}
memset(p, 0, sizeof(*p));
fossil_free(p);
}
/*
** Quote a tag string by surrounding it with double quotes and preceding
** internal double quotes and backslashes with backslashes.
*/
static const char *tagQuote(
int len, /* Maximum length of zTag, or negative for unlimited */
const char *zTag /* Tag string */
){
Blob blob = BLOB_INITIALIZER;
int i, j;
blob_zero(&blob);
blob_append(&blob, "\"", 1);
for( i=j=0; zTag[j] && (len<0 || j<len); ++j ){
if( zTag[j]=='\"' || zTag[j]=='\\' ){
if( j>i ){
blob_append(&blob, zTag+i, j-i);
}
blob_append(&blob, "\\", 1);
i = j;
}
}
if( j>i ){
blob_append(&blob, zTag+i, j-i);
}
blob_append(&blob, "\"", 1);
return blob_str(&blob);
}
/*
** Construct the SQL expression that goes into the WHERE clause of a join
** that involves the TAG table and that selects a particular tag out of
** that table.
**
** This function is adapted from glob_expr() to support the MS_EXACT, MS_GLOB,
** MS_LIKE, MS_REGEXP, and MS_BRLIST match styles.
**
** For MS_EXACT, the returned expression
** checks for integer match against the tag ID which is looked up directly by
** this function. For the other modes, the returned SQL expression performs
** string comparisons against the tag names, so it is necessary to join against
** the tag table to access the "tagname" column.
**
** Each pattern is adjusted to to start with "sym-" and be anchored at end.
**
** In MS_REGEXP mode, backslash can be used to protect delimiter characters.
** The backslashes are not removed from the regular expression.
**
** In addition to assembling and returning an SQL expression, this function
** makes an English-language description of the patterns being matched, suitable
** for display in the web interface.
**
** If any errors arise during processing, *zError is set to an error message.
** Otherwise it is set to NULL.
*/
const char *match_tag_sqlexpr(
MatchStyle matchStyle, /* Match style code */
const char *zTag, /* Tag name, match pattern, or pattern list */
const char **zDesc, /* Output expression description string */
const char **zError /* Output error string */
){
Blob expr = BLOB_INITIALIZER; /* SQL expression string assembly buffer */
Blob desc = BLOB_INITIALIZER; /* English description of match patterns */
Blob err = BLOB_INITIALIZER; /* Error text assembly buffer */
const char *zStart; /* Text at start of expression */
const char *zDelimiter; /* Text between expression terms */
const char *zEnd; /* Text at end of expression */
const char *zPrefix; /* Text before each match pattern */
const char *zSuffix; /* Text after each match pattern */
const char *zIntro; /* Text introducing pattern description */
const char *zPattern = 0; /* Previous quoted pattern */
const char *zFail = 0; /* Current failure message or NULL if okay */
const char *zOr = " or "; /* Text before final quoted pattern */
char cDel; /* Input delimiter character */
int i; /* Input match pattern length counter */
/* Optimize exact matches by looking up the ID in advance to create a simple
* numeric comparison. Bypass the remainder of this function. */
if( matchStyle==MS_EXACT ){
*zDesc = tagQuote(-1, zTag);
return mprintf("(tagid=%d)", db_int(-1,
"SELECT tagid FROM tag WHERE tagname='sym-%q'", zTag));
}
/* Decide pattern prefix and suffix strings according to match style. */
if( matchStyle==MS_GLOB ){
zStart = "(";
zDelimiter = " OR ";
zEnd = ")";
zPrefix = "tagname GLOB 'sym-";
zSuffix = "'";
zIntro = "glob pattern ";
}else if( matchStyle==MS_LIKE ){
zStart = "(";
zDelimiter = " OR ";
zEnd = ")";
zPrefix = "tagname LIKE 'sym-";
zSuffix = "'";
zIntro = "SQL LIKE pattern ";
}else if( matchStyle==MS_REGEXP ){
zStart = "(tagname REGEXP '^sym-(";
zDelimiter = "|";
zEnd = ")$')";
zPrefix = "";
zSuffix = "";
zIntro = "regular expression ";
}else/* if( matchStyle==MS_BRLIST )*/{
zStart = "tagname IN ('sym-";
zDelimiter = "','sym-";
zEnd = "')";
zPrefix = "";
zSuffix = "";
zIntro = "";
}
/* Convert the list of matches into an SQL expression and text description. */
blob_zero(&expr);
blob_zero(&desc);
blob_zero(&err);
while( 1 ){
/* Skip leading delimiters. */
for( ; fossil_isspace(*zTag) || *zTag==','; ++zTag );
/* Next non-delimiter character determines quoting. */
if( !*zTag ){
/* Terminate loop at end of string. */
break;
}else if( *zTag=='\'' || *zTag=='"' ){
/* If word is quoted, prepare to stop at end quote. */
cDel = *zTag;
++zTag;
}else{
/* If word is not quoted, prepare to stop at delimiter. */
cDel = ',';
}
/* Find the next delimiter character or end of string. */
for( i=0; zTag[i] && zTag[i]!=cDel; ++i ){
/* If delimiter is comma, also recognize spaces as delimiters. */
if( cDel==',' && fossil_isspace(zTag[i]) ){
break;
}
/* In regexp mode, ignore delimiters following backslashes. */
if( matchStyle==MS_REGEXP && zTag[i]=='\\' && zTag[i+1] ){
++i;
}
}
/* Check for regular expression syntax errors. */
if( matchStyle==MS_REGEXP ){
ReCompiled *regexp;
char *zTagDup = fossil_strndup(zTag, i);
zFail = re_compile(®exp, zTagDup, 0);
re_free(regexp);
fossil_free(zTagDup);
}
/* Process success and error results. */
if( !zFail ){
/* Incorporate the match word into the output expression. %q is used to
* protect against SQL injection attacks by replacing ' with ''. */
blob_appendf(&expr, "%s%s%#q%s", blob_size(&expr) ? zDelimiter : zStart,
zPrefix, i, zTag, zSuffix);
/* Build up the description string. */
if( !blob_size(&desc) ){
/* First tag: start with intro followed by first quoted tag. */
blob_append(&desc, zIntro, -1);
blob_append(&desc, tagQuote(i, zTag), -1);
}else{
if( zPattern ){
/* Third and subsequent tags: append comma then previous tag. */
blob_append(&desc, ", ", 2);
blob_append(&desc, zPattern, -1);
zOr = ", or ";
}
/* Second and subsequent tags: store quoted tag for next iteration. */
zPattern = tagQuote(i, zTag);
}
}else{
/* On error, skip the match word and build up the error message buffer. */
if( !blob_size(&err) ){
blob_append(&err, "Error: ", 7);
}else{
blob_append(&err, ", ", 2);
}
blob_appendf(&err, "(%s%s: %s)", zIntro, tagQuote(i, zTag), zFail);
}
/* Advance past all consumed input characters. */
zTag += i;
if( cDel!=',' && *zTag==cDel ){
++zTag;
}
}
/* Finalize and extract the pattern description. */
if( zPattern ){
blob_append(&desc, zOr, -1);
blob_append(&desc, zPattern, -1);
}
*zDesc = blob_str(&desc);
/* Finalize and extract the error text. */
*zError = blob_size(&err) ? blob_str(&err) : 0;
/* Finalize and extract the SQL expression. */
if( blob_size(&expr) ){
blob_append(&expr, zEnd, -1);
return blob_str(&expr);
}
/* If execution reaches this point, the pattern was empty. Return NULL. */
return 0;
}
|
Changes to src/merge.c.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
/*
** Bring up a Tcl/Tk GUI to show details of the most recent merge.
*/
static void merge_info_tk(int bDark, int bAll, int nContext){
int i;
Blob script;
const char *zTempFile = 0;
char *zCmd;
const char *zTclsh;
zTclsh = find_option("tclsh",0,1);
if( zTclsh==0 ){
zTclsh = db_get("tclsh",0);
}
/* The undocumented --script FILENAME option causes the Tk script to
** be written into the FILENAME instead of being run. This is used
** for testing and debugging. */
zTempFile = find_option("script",0,1);
verify_all_options();
blob_zero(&script);
blob_appendf(&script, "set ncontext %d\n", nContext);
blob_appendf(&script, "set fossilcmd {| \"%/\" merge-info}\n",
g.nameOfExe);
blob_appendf(&script, "set filelist [list");
| > > | 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 |
/*
** Bring up a Tcl/Tk GUI to show details of the most recent merge.
*/
static void merge_info_tk(int bDark, int bAll, int nContext){
int i;
Blob script;
const char *zTempFile = 0;
int bDebug;
char *zCmd;
const char *zTclsh;
zTclsh = find_option("tclsh",0,1);
if( zTclsh==0 ){
zTclsh = db_get("tclsh",0);
}
/* The undocumented --script FILENAME option causes the Tk script to
** be written into the FILENAME instead of being run. This is used
** for testing and debugging. */
zTempFile = find_option("script",0,1);
bDebug = find_option("debug",0,0)!=0;
verify_all_options();
blob_zero(&script);
blob_appendf(&script, "set ncontext %d\n", nContext);
blob_appendf(&script, "set fossilcmd {| \"%/\" merge-info}\n",
g.nameOfExe);
blob_appendf(&script, "set filelist [list");
|
| ︙ | ︙ | |||
91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
fossil_free(zOp);
blob_append_tcl_literal(&script, zTreename, (int)strlen(zTreename));
blob_reset(&fname);
}
}
blob_appendf(&script, "]\n");
blob_appendf(&script, "set darkmode %d\n", bDark!=0);
blob_appendf(&script, "%s", builtin_file("merge.tcl", 0));
if( zTempFile ){
blob_write_to_file(&script, zTempFile);
fossil_print("To see the merge, run: %s \"%s\"\n", zTclsh, zTempFile);
}else{
#if defined(FOSSIL_ENABLE_TCL)
Th_FossilInit(TH_INIT_DEFAULT);
| > | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
fossil_free(zOp);
blob_append_tcl_literal(&script, zTreename, (int)strlen(zTreename));
blob_reset(&fname);
}
}
blob_appendf(&script, "]\n");
blob_appendf(&script, "set darkmode %d\n", bDark!=0);
blob_appendf(&script, "set debug %d\n", bDebug!=0);
blob_appendf(&script, "%s", builtin_file("merge.tcl", 0));
if( zTempFile ){
blob_write_to_file(&script, zTempFile);
fossil_print("To see the merge, run: %s \"%s\"\n", zTclsh, zTempFile);
}else{
#if defined(FOSSIL_ENABLE_TCL)
Th_FossilInit(TH_INIT_DEFAULT);
|
| ︙ | ︙ | |||
112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
* could not be found by the loaded Tcl, or that Tcl cannot be loaded
* dynamically (e.g. x64 Tcl with x86 Fossil). Therefore, fallback
* to using the external "tclsh", if available.
*/
#endif
zTempFile = write_blob_to_temp_file(&script);
zCmd = mprintf("%$ %$", zTclsh, zTempFile);
fossil_system(zCmd);
file_delete(zTempFile);
fossil_free(zCmd);
}
blob_reset(&script);
}
| > > > > | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
* could not be found by the loaded Tcl, or that Tcl cannot be loaded
* dynamically (e.g. x64 Tcl with x86 Fossil). Therefore, fallback
* to using the external "tclsh", if available.
*/
#endif
zTempFile = write_blob_to_temp_file(&script);
zCmd = mprintf("%$ %$", zTclsh, zTempFile);
if( bDebug ){
fossil_print("%s\n", zCmd);
fflush(stdout);
}
fossil_system(zCmd);
file_delete(zTempFile);
fossil_free(zCmd);
}
blob_reset(&script);
}
|
| ︙ | ︙ | |||
486 487 488 489 490 491 492 493 494 495 496 497 498 499 |
** information needed to display the changes to
** FILE caused by the most recent merge. FILE must
** be a pathname relative to the root of the check-out.
** --tk Bring up a Tcl/Tk GUI that shows the changes
** associated with the most recent merge.
** --html Like --tk but emits HTML to stdout.
** -b|--browser Like --html but show the result in a web browser.
*/
void merge_info_cmd(void){
const char *zCnt;
const char *zTcl;
int bTk;
int bBrowser;
int bHtml;
| > > > > | 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 |
** information needed to display the changes to
** FILE caused by the most recent merge. FILE must
** be a pathname relative to the root of the check-out.
** --tk Bring up a Tcl/Tk GUI that shows the changes
** associated with the most recent merge.
** --html Like --tk but emits HTML to stdout.
** -b|--browser Like --html but show the result in a web browser.
** Additional debugging options available only when --tk is used:
** --debug Show sub-commands run to implement --tk
** --script FILE Write script used to implement --tk into FILE
*/
void merge_info_cmd(void){
const char *zCnt;
const char *zTcl;
int bTk;
int bBrowser;
int bHtml;
|
| ︙ | ︙ | |||
922 923 924 925 926 927 928 929 930 931 932 933 934 935 |
** --force-missing Force the merge even if there is missing content
** --integrate Merged branch will be closed when committing
** -K|--keep-merge-files On merge conflict, retain the temporary files
** used for merging, named *-baseline, *-original,
** and *-merge.
** -n|--dry-run Do not actually change files on disk
** --nosync Do not auto-sync prior to merging
** -v|--verbose Show additional details of the merge
*/
void merge_cmd(void){
int vid; /* Current version "V" */
int mid; /* Version we are merging from "M" */
int pid = 0; /* The pivot version - most recent common ancestor P */
int nid = 0; /* The name pivot version "N" */
| > | 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 |
** --force-missing Force the merge even if there is missing content
** --integrate Merged branch will be closed when committing
** -K|--keep-merge-files On merge conflict, retain the temporary files
** used for merging, named *-baseline, *-original,
** and *-merge.
** -n|--dry-run Do not actually change files on disk
** --nosync Do not auto-sync prior to merging
** --noundo Do not record changes in the undo log
** -v|--verbose Show additional details of the merge
*/
void merge_cmd(void){
int vid; /* Current version "V" */
int mid; /* Version we are merging from "M" */
int pid = 0; /* The pivot version - most recent common ancestor P */
int nid = 0; /* The name pivot version "N" */
|
| ︙ | ︙ | |||
947 948 949 950 951 952 953 954 955 956 957 958 959 960 | int keepMergeFlag; /* True if --keep-merge-files is present */ int nConflict = 0; /* Number of conflicts seen */ int nOverwrite = 0; /* Number of unmanaged files overwritten */ char vAncestor = 'p'; /* If P is an ancestor of V then 'p', else 'n' */ const char *zVersion; /* The VERSION argument */ int bMultiMerge = 0; /* True if there are two or more VERSION arguments */ int nMerge = 0; /* Number of prior merges processed */ Stmt q; /* SQL statment used for merge processing */ /* Notation: ** ** V The current check-out ** M The version being merged in | > | 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 | int keepMergeFlag; /* True if --keep-merge-files is present */ int nConflict = 0; /* Number of conflicts seen */ int nOverwrite = 0; /* Number of unmanaged files overwritten */ char vAncestor = 'p'; /* If P is an ancestor of V then 'p', else 'n' */ const char *zVersion; /* The VERSION argument */ int bMultiMerge = 0; /* True if there are two or more VERSION arguments */ int nMerge = 0; /* Number of prior merges processed */ int useUndo = 1; /* True to record changes in the undo log */ Stmt q; /* SQL statment used for merge processing */ /* Notation: ** ** V The current check-out ** M The version being merged in |
| ︙ | ︙ | |||
995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 |
** Hints:
** * Combine --debug and --verbose for still more output.
** * The --dry-run option is also useful in combination with --debug.
*/
debugFlag = find_option("debug",0,0)!=0;
if( debugFlag && verboseFlag ) debugFlag = 2;
showVfileFlag = find_option("show-vfile",0,0)!=0;
verify_all_options();
db_must_be_within_tree();
if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
vid = db_lget_int("checkout", 0);
if( vid==0 ){
fossil_fatal("nothing is checked out");
| > > | 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 |
** Hints:
** * Combine --debug and --verbose for still more output.
** * The --dry-run option is also useful in combination with --debug.
*/
debugFlag = find_option("debug",0,0)!=0;
if( debugFlag && verboseFlag ) debugFlag = 2;
showVfileFlag = find_option("show-vfile",0,0)!=0;
useUndo = find_option("noundo",0,0)==0;
if( dryRunFlag ) useUndo = 0;
verify_all_options();
db_must_be_within_tree();
if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0);
vid = db_lget_int("checkout", 0);
if( vid==0 ){
fossil_fatal("nothing is checked out");
|
| ︙ | ︙ | |||
1161 1162 1163 1164 1165 1166 1167 |
if( verboseFlag ){
print_checkin_description(mid, 12,
integrateFlag ? "integrate:" : "merge-from:");
print_checkin_description(pid, 12, "baseline:");
}
vfile_check_signature(vid, CKSIG_ENOTFILE);
if( nMerge==0 ) db_begin_transaction();
| | | 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 |
if( verboseFlag ){
print_checkin_description(mid, 12,
integrateFlag ? "integrate:" : "merge-from:");
print_checkin_description(pid, 12, "baseline:");
}
vfile_check_signature(vid, CKSIG_ENOTFILE);
if( nMerge==0 ) db_begin_transaction();
if( useUndo ) undo_begin();
if( load_vfile_from_rid(mid) && !forceMissingFlag ){
fossil_fatal("missing content, unable to merge");
}
if( load_vfile_from_rid(pid) && !forceMissingFlag ){
fossil_fatal("missing content, unable to merge");
}
if( zPivot ){
|
| ︙ | ︙ | |||
1418 1419 1420 1421 1422 1423 1424 1425 |
while( db_step(&q)==SQLITE_ROW ){
int idv = db_column_int(&q, 0);
int ridm = db_column_int(&q, 1);
const char *zName = db_column_text(&q, 2);
int islinkm = db_column_int(&q, 3);
/* Copy content from idm over into idv. Overwrite idv. */
fossil_print("UPDATE %s\n", zName);
if( !dryRunFlag ){
| > < | 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 |
while( db_step(&q)==SQLITE_ROW ){
int idv = db_column_int(&q, 0);
int ridm = db_column_int(&q, 1);
const char *zName = db_column_text(&q, 2);
int islinkm = db_column_int(&q, 3);
/* Copy content from idm over into idv. Overwrite idv. */
fossil_print("UPDATE %s\n", zName);
if( useUndo ) undo_save(zName);
if( !dryRunFlag ){
db_multi_exec(
"UPDATE vfile SET mtime=0, mrid=%d, chnged=%d, islink=%d,"
" mhash=CASE WHEN rid<>%d"
" THEN (SELECT uuid FROM blob WHERE blob.rid=%d) END"
" WHERE id=%d", ridm, integrateFlag?4:2, islinkm, ridm, ridm, idv
);
vfile_to_disk(0, idv, 0, 0);
|
| ︙ | ︙ | |||
1500 1501 1502 1503 1504 1505 1506 |
/* fnr */ zName
);
}else{
i64 sz;
const char *zErrMsg = 0;
int nc = 0;
| | | 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 |
/* fnr */ zName
);
}else{
i64 sz;
const char *zErrMsg = 0;
int nc = 0;
if( useUndo ) undo_save(zName);
zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
sz = file_size(zFullPath, ExtFILE);
content_get(ridp, &p);
content_get(ridm, &m);
if( isBinary ){
rc = -1;
blob_zero(&r);
|
| ︙ | ︙ | |||
1587 1588 1589 1590 1591 1592 1593 |
ridv = 0;
nc = 1;
zErrMsg = "local edits lost";
zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
sz = file_size(zFullPath, ExtFILE);
fossil_free(zFullPath);
}
| | | 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 |
ridv = 0;
nc = 1;
zErrMsg = "local edits lost";
zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
sz = file_size(zFullPath, ExtFILE);
fossil_free(zFullPath);
}
if( useUndo ) undo_save(zName);
db_multi_exec(
"UPDATE vfile SET deleted=1 WHERE id=%d", idv
);
if( !dryRunFlag ){
char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName);
file_delete(zFullPath);
free(zFullPath);
|
| ︙ | ︙ | |||
1634 1635 1636 1637 1638 1639 1640 |
);
while( db_step(&q)==SQLITE_ROW ){
int idv = db_column_int(&q, 0);
const char *zOldName = db_column_text(&q, 1);
const char *zNewName = db_column_text(&q, 2);
int isExe = db_column_int(&q, 3);
fossil_print("RENAME %s -> %s\n", zOldName, zNewName);
| | | | 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 |
);
while( db_step(&q)==SQLITE_ROW ){
int idv = db_column_int(&q, 0);
const char *zOldName = db_column_text(&q, 1);
const char *zNewName = db_column_text(&q, 2);
int isExe = db_column_int(&q, 3);
fossil_print("RENAME %s -> %s\n", zOldName, zNewName);
if( useUndo ) undo_save(zOldName);
if( useUndo ) undo_save(zNewName);
db_multi_exec(
"UPDATE mergestat SET fnr=fnm WHERE fnp=%Q",
zOldName
);
db_multi_exec(
"UPDATE vfile SET pathname=NULL, origname=pathname"
" WHERE vid=%d AND pathname=%Q;"
|
| ︙ | ︙ | |||
1733 1734 1735 1736 1737 1738 1739 1740 |
db_multi_exec(
"INSERT INTO mergestat(op,fnm,ridm,fnr)"
"VALUES('ADDED',%Q,%d,%Q)",
/* fnm */ zName,
/* ridm */ db_column_int(&q,2),
/* fnr */ zName
);
if( !dryRunFlag ){
| > < | 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 |
db_multi_exec(
"INSERT INTO mergestat(op,fnm,ridm,fnr)"
"VALUES('ADDED',%Q,%d,%Q)",
/* fnm */ zName,
/* ridm */ db_column_int(&q,2),
/* fnr */ zName
);
if( useUndo ) undo_save(zName);
if( !dryRunFlag ){
vfile_to_disk(0, idm, 0, 0);
}
}
db_finalize(&q);
/* Report on conflicts
*/
|
| ︙ | ︙ | |||
1793 1794 1795 1796 1797 1798 1799 |
}else{
vmerge_insert(0, mid);
}
if( bMultiMerge && nConflict==0 ){
nMerge++;
goto merge_next_child;
}
| | | 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 |
}else{
vmerge_insert(0, mid);
}
if( bMultiMerge && nConflict==0 ){
nMerge++;
goto merge_next_child;
}
if( useUndo ) undo_finish();
db_end_transaction(dryRunFlag);
}
|
Changes to src/merge.tcl.
| ︙ | ︙ | |||
91 92 93 94 95 96 97 |
proc colType {c} {
regexp {[a-z]+} $c type
return $type
}
proc readMerge {args} {
| | > > > > > | 91 92 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 |
proc colType {c} {
regexp {[a-z]+} $c type
return $type
}
proc readMerge {args} {
global fossilcmd ncontext current_file debug
if {$ncontext=="All"} {
set cmd "$fossilcmd -c -1"
} else {
set cmd "$fossilcmd -c $ncontext"
}
if {[info exists current_file]} {
regsub {^[A-Z]+ } $current_file {} fn
append cmd " -tcl [list $fn]"
}
if {$debug} {
regsub {^\| +} $cmd {} cmd2
puts $cmd2
flush stdout
}
if {[catch {
set in [open $cmd r]
fconfigure $in -encoding utf-8
set mergetxt [read $in]
close $in
} msg]} {
tk_messageBox -message "Unable to run command: \"$cmd\""
|
| ︙ | ︙ |
Changes to src/name.c.
| ︙ | ︙ | |||
63 64 65 66 67 68 69 |
**
** If the bVerifyNotAHash flag is true, then a check is made to see if
** the string is a hash prefix and NULL is returned if it is. If the
** bVerifyNotAHash flag is false, then the result is determined by syntax
** of the input string only, without reference to the artifact table.
*/
char *fossil_expand_datetime(const char *zIn, int bVerifyNotAHash){
| | > | > > | | | > > > > > > | > > | | > > > > > > > | 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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
**
** If the bVerifyNotAHash flag is true, then a check is made to see if
** the string is a hash prefix and NULL is returned if it is. If the
** bVerifyNotAHash flag is false, then the result is determined by syntax
** of the input string only, without reference to the artifact table.
*/
char *fossil_expand_datetime(const char *zIn, int bVerifyNotAHash){
static char zEDate[24];
static const char aPunct[] = { 0, 0, '-', '-', ' ', ':', ':' };
int n = (int)strlen(zIn);
int i, j;
int addZulu = 0;
/* These forms are allowed:
**
** 123456789 1234 123456789 123456789
** (1) YYYYMMDD => YYYY-MM-DD
** (2) YYYYMMDDHHMM => YYYY-MM-DD HH:MM
** (3) YYYYMMDDHHMMSS => YYYY-MM-DD HH:MM:SS
**
** An optional "Z" zulu timezone designator is allowed at the end.
*/
if( n>0 && (zIn[n-1]=='Z' || zIn[n-1]=='z') ){
n--;
addZulu = 1;
}
if( n!=8 && n!=12 && n!=14 ){
return 0;
}
/* Every character must be a digit */
for(i=0; fossil_isdigit(zIn[i]); i++){}
if( i!=n && (!addZulu || i!=n+1) ) return 0;
/* Expand the date */
for(i=j=0; i<n; i++){
if( i>=4 && (i%2)==0 ){
zEDate[j++] = aPunct[i/2];
}
zEDate[j++] = zIn[i];
}
if( addZulu ){
if( j==10 ){
memcpy(&zEDate[10]," 00:00", 6);
j += 6;
}
zEDate[j++] = 'Z';
}
zEDate[j] = 0;
/* Check for reasonable date values.
** Offset references:
** YYYY-MM-DD HH:MM:SS
** 0123456789 12345678
*/
|
| ︙ | ︙ | |||
109 110 111 112 113 114 115 |
if( i>24 ) return 0;
i = atoi(zEDate+14);
if( i>60 ) return 0;
if( n==14 && atoi(zEDate+17)>60 ) return 0;
}
/* The string is not also a hash prefix */
| | | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
if( i>24 ) return 0;
i = atoi(zEDate+14);
if( i>60 ) return 0;
if( n==14 && atoi(zEDate+17)>60 ) return 0;
}
/* The string is not also a hash prefix */
if( bVerifyNotAHash && !addZulu ){
if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%q*'",zIn) ) return 0;
}
/* It looks like this may be a date. Return it with punctuation added. */
return zEDate;
}
|
| ︙ | ︙ | |||
451 452 453 454 455 456 457 458 459 460 461 462 463 464 |
rid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim",
ridCkout);
}else if( fossil_strcmp(zTag, "next")==0 ){
rid = db_int(0, "SELECT cid FROM plink WHERE pid=%d"
" ORDER BY isprim DESC, mtime DESC", ridCkout);
}else if( isCheckin>1 && fossil_strcmp(zTag, "ckout")==0 ){
rid = RID_CKOUT;
}
if( rid ) return rid;
}
/* Date and times */
if( memcmp(zTag, "date:", 5)==0 ){
zDate = fossil_expand_datetime(&zTag[5],0);
| > > | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 |
rid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim",
ridCkout);
}else if( fossil_strcmp(zTag, "next")==0 ){
rid = db_int(0, "SELECT cid FROM plink WHERE pid=%d"
" ORDER BY isprim DESC, mtime DESC", ridCkout);
}else if( isCheckin>1 && fossil_strcmp(zTag, "ckout")==0 ){
rid = RID_CKOUT;
assert(ridCkout>0);
g.localOpen = ridCkout;
}
if( rid ) return rid;
}
/* Date and times */
if( memcmp(zTag, "date:", 5)==0 ){
zDate = fossil_expand_datetime(&zTag[5],0);
|
| ︙ | ︙ | |||
697 698 699 700 701 702 703 704 705 706 707 708 709 710 |
fossil_error(iErrPriority, "ambiguous name: %s", zName);
return 2;
}else if( rid==0 ){
fossil_error(iErrPriority, "cannot resolve name: %s", zName);
return 1;
}else{
blob_reset(pName);
db_blob(pName, "SELECT uuid FROM blob WHERE rid=%d", rid);
return 0;
}
}
/*
** This routine is similar to name_to_uuid() except in the form it
| > > > | 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 |
fossil_error(iErrPriority, "ambiguous name: %s", zName);
return 2;
}else if( rid==0 ){
fossil_error(iErrPriority, "cannot resolve name: %s", zName);
return 1;
}else{
blob_reset(pName);
if( RID_CKOUT==rid ) {
rid = g.localOpen;
}
db_blob(pName, "SELECT uuid FROM blob WHERE rid=%d", rid);
return 0;
}
}
/*
** This routine is similar to name_to_uuid() except in the form it
|
| ︙ | ︙ | |||
1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 |
** Return a page showing all artifacts in the repository. Query parameters:
**
** n=N Show N artifacts
** s=S Start with artifact number S
** priv Show only unpublished or private artifacts
** phan Show only phantom artifacts
** hclr Color code hash types (SHA1 vs SHA3)
*/
void bloblist_page(void){
Stmt q;
int s = atoi(PD("s","0"));
int n = atoi(PD("n","5000"));
int mx = db_int(0, "SELECT max(rid) FROM blob");
int privOnly = PB("priv");
int phantomOnly = PB("phan");
int hashClr = PB("hclr");
char *zRange;
char *zSha1Bg;
char *zSha3Bg;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
cgi_check_for_malice();
style_header("List Of Artifacts");
style_submenu_element("250 Largest", "bigbloblist");
if( g.perm.Admin ){
style_submenu_element("Artifact Log", "rcvfromlist");
}
if( !phantomOnly ){
style_submenu_element("Phantoms", "bloblist?phan");
}
if( g.perm.Private || g.perm.Admin ){
if( !privOnly ){
style_submenu_element("Private", "bloblist?priv");
}
}else{
privOnly = 0;
}
if( g.perm.Write ){
style_submenu_element("Artifact Stats", "artifact_stats");
}
| > > > > > > > > > > | > > > > > > > > > > > > | > | > > < | < < < | > | < | | | < | 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 |
** Return a page showing all artifacts in the repository. Query parameters:
**
** n=N Show N artifacts
** s=S Start with artifact number S
** priv Show only unpublished or private artifacts
** phan Show only phantom artifacts
** hclr Color code hash types (SHA1 vs SHA3)
** recent Show the most recent N artifacts
*/
void bloblist_page(void){
Stmt q;
int s = atoi(PD("s","0"));
int n = atoi(PD("n","5000"));
int mx = db_int(0, "SELECT max(rid) FROM blob");
int privOnly = PB("priv");
int phantomOnly = PB("phan");
int hashClr = PB("hclr");
int bRecent = PB("recent");
int bUnclst = PB("unclustered");
char *zRange;
char *zSha1Bg;
char *zSha3Bg;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
cgi_check_for_malice();
style_header("List Of Artifacts");
style_submenu_element("250 Largest", "bigbloblist");
if( bRecent==0 || n!=250 ){
style_submenu_element("Recent","bloblist?n=250&recent");
}
if( bUnclst==0 ){
style_submenu_element("Unclustered","bloblist?unclustered");
}
if( g.perm.Admin ){
style_submenu_element("Artifact Log", "rcvfromlist");
}
if( !phantomOnly ){
style_submenu_element("Phantoms", "bloblist?phan");
}
style_submenu_element("Clusters","clusterlist");
if( g.perm.Private || g.perm.Admin ){
if( !privOnly ){
style_submenu_element("Private", "bloblist?priv");
}
}else{
privOnly = 0;
}
if( g.perm.Write ){
style_submenu_element("Artifact Stats", "artifact_stats");
}
if( !privOnly && !phantomOnly && mx>n && P("s")==0 && !bRecent && !bUnclst ){
int i;
@ <p>Select a range of artifacts to view:</p>
@ <ul>
for(i=1; i<=mx; i+=n){
@ <li> %z(href("%R/bloblist?s=%d&n=%d",i,n))
@ %d(i)..%d(i+n-1<mx?i+n-1:mx)</a>
}
@ <li> %z(href("%R/bloblist?n=250&recent"))250 most recent</a>
@ <li> %z(href("%R/bloblist?unclustered"))All unclustered</a>
@ </ul>
style_finish_page();
return;
}
if( phantomOnly || privOnly || mx>n ){
style_submenu_element("Index", "bloblist");
}
if( privOnly ){
@ <h2>Private Artifacts</h2>
zRange = mprintf("IN private");
}else if( phantomOnly ){
@ <h2>Phantom Artifacts</h2>
zRange = mprintf("IN phantom");
}else if( bUnclst ){
@ <h2>Unclustered Artifacts</h2>
zRange = mprintf("IN unclustered");
}else if( bRecent ){
@ <h2>%d(n) Most Recent Artifacts</h2>
zRange = mprintf(">=(SELECT rid FROM blob"
" ORDER BY rid DESC LIMIT 1 OFFSET %d)",n);
}else{
zRange = mprintf("BETWEEN %d AND %d", s, s+n-1);
}
describe_artifacts(zRange);
fossil_free(zRange);
db_prepare(&q,
/* 0 1 2 3 4 5 6 */
"SELECT rid, uuid, summary, isPrivate, type='phantom', ref, rcvid, "
" datetime(rcvfrom.mtime)"
" FROM description LEFT JOIN rcvfrom USING(rcvid)"
" ORDER BY rid %s",
((bRecent||bUnclst)?"DESC":"ASC")/*safe-for-%s*/
);
if( skin_detail_boolean("white-foreground") ){
zSha1Bg = "#714417";
zSha3Bg = "#177117";
}else{
zSha1Bg = "#ebffb0";
zSha3Bg = "#b0ffb0";
}
@ <table cellpadding="2" cellspacing="0" border="1">
@ <tr><th>RID<th>Hash<th>Received<th>Description<th>Ref<th>Remarks
while( db_step(&q)==SQLITE_ROW ){
int rid = db_column_int(&q,0);
const char *zUuid = db_column_text(&q, 1);
const char *zDesc = db_column_text(&q, 2);
int isPriv = db_column_int(&q,3);
int isPhantom = db_column_int(&q,4);
const char *zRef = db_column_text(&q,5);
const char *zDate = db_column_text(&q,7);
if( isPriv && !isPhantom && !g.perm.Private && !g.perm.Admin ){
/* Don't show private artifacts to users without Private (x) permission */
continue;
}
if( hashClr ){
const char *zClr = db_column_bytes(&q,1)>40 ? zSha3Bg : zSha1Bg;
@ <tr style='background-color:%s(zClr);'><td align="right">%d(rid)</td>
}else{
@ <tr><td align="right">%d(rid)</td>
}
@ <td> %z(href("%R/info/%!S",zUuid))%S(zUuid)</a> </td>
if( g.perm.Admin ){
int rcvid = db_column_int(&q, 6);
@ <td><a href='%R/rcvfrom?rcvid=%d(rcvid)'>%h(zDate)</a>
}else{
@ <td>%h(zDate)
}
@ <td align="left">%h(zDesc)</td>
if( zRef && zRef[0] ){
@ <td>%z(href("%R/info/%!S",zRef))%S(zRef)</a>
}else{
@ <td>
}
|
| ︙ | ︙ | |||
2161 2162 2163 2164 2165 2166 2167 |
collision_report("SELECT (SELECT uuid FROM blob WHERE rid=objid)"
" FROM event WHERE event.type='ci'"
" ORDER BY 1");
@ <h1>Hash Prefix Collisions on All Artifacts</h1>
collision_report("SELECT uuid FROM blob ORDER BY 1");
style_finish_page();
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 |
collision_report("SELECT (SELECT uuid FROM blob WHERE rid=objid)"
" FROM event WHERE event.type='ci'"
" ORDER BY 1");
@ <h1>Hash Prefix Collisions on All Artifacts</h1>
collision_report("SELECT uuid FROM blob ORDER BY 1");
style_finish_page();
}
/*
** WEBPAGE: clusterlist
**
** Show information about all cluster artifacts in the database.
*/
void clusterlist_page(void){
Stmt q;
int cnt = 1;
sqlite3_int64 szTotal = 0;
sqlite3_int64 szCTotal = 0;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_header("All Cluster Artifacts");
style_submenu_element("All Artifactst", "bloblist");
if( g.perm.Admin ){
style_submenu_element("Artifact Log", "rcvfromlist");
}
style_submenu_element("Phantoms", "bloblist?phan");
if( g.perm.Write ){
style_submenu_element("Artifact Stats", "artifact_stats");
}
db_prepare(&q,
"SELECT blob.uuid, "
" blob.size, "
" octet_length(blob.content), "
" datetime(rcvfrom.mtime),"
" user.login,"
" rcvfrom.ipaddr"
" FROM tagxref JOIN blob ON tagxref.rid=blob.rid"
" LEFT JOIN rcvfrom ON blob.rcvid=rcvfrom.rcvid"
" LEFT JOIN user ON user.uid=rcvfrom.uid"
" WHERE tagxref.tagid=%d"
" ORDER BY rcvfrom.mtime, blob.uuid",
TAG_CLUSTER
);
@ <table cellpadding="2" cellspacing="0" border="1">
@ <tr><th>
@ <th>Hash
@ <th>Date Received
@ <th>Size
@ <th>Compressed Size
if( g.perm.Admin ){
@ <th>User<th>IP-Address
}
while( db_step(&q)==SQLITE_ROW ){
const char *zUuid = db_column_text(&q, 0);
sqlite3_int64 sz = db_column_int64(&q, 1);
sqlite3_int64 szC = db_column_int64(&q, 2);
const char *zDate = db_column_text(&q, 3);
const char *zUser = db_column_text(&q, 4);
const char *zIp = db_column_text(&q, 5);
szTotal += sz;
szCTotal += szC;
@ <tr><td align="right">%d(cnt++)
@ <td><a href="%R/info/%S(zUuid)">%S(zUuid)</a>
if( zDate ){
@ <td>%h(zDate)
}else{
@ <td>
}
@ <td align="right">%,lld(sz)
@ <td align="right">%,lld(szC)
if( g.perm.Admin ){
if( zUser ){
@ <td>%h(zUser)
}else{
@ <td>
}
if( zIp ){
@ <td>%h(zIp)
}else{
@ <td>
}
}
@ </tr>
}
@ </table>
db_finalize(&q);
@ <p>Total size of all clusters: %,lld(szTotal) bytes,
@ %,lld(szCTotal) bytes compressed</p>
style_finish_page();
}
|
Changes to src/patch.c.
| ︙ | ︙ | |||
79 80 81 82 83 84 85 |
*/
static void mkdeltaFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *zFile;
| | < < < < | | < < | > < | | | | 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 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 131 132 133 |
*/
static void mkdeltaFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *zFile;
Blob x, y, out;
int rid;
int nOut;
sqlite3_int64 sz;
rid = sqlite3_value_int(argv[0]);
if( !content_get(rid, &x) ){
sqlite3_result_error(context, "mkdelta(X,Y): no content for X", -1);
return;
}
zFile = (const char*)sqlite3_value_text(argv[1]);
if( zFile==0 ){
sqlite3_result_error(context, "mkdelta(X,Y): NULL Y argument", -1);
blob_reset(&x);
return;
}
sz = blob_read_from_file(&y, zFile, RepoFILE);
if( sz<0 ){
sqlite3_result_error(context, "mkdelta(X,Y): cannot read file Y", -1);
blob_reset(&x);
return;
}
blob_init(&out, 0, 0);
blob_resize(&out, sz+70);
if( blob_size(&x)==blob_size(&y)
&& memcmp(blob_buffer(&x), blob_buffer(&y), blob_size(&x))==0
){
blob_reset(&y);
blob_reset(&x);
sqlite3_result_blob64(context, "", 0, SQLITE_STATIC);
return;
}
nOut = delta_create(blob_buffer(&x),blob_size(&x),
blob_buffer(&y),blob_size(&y), blob_buffer(&out));
blob_resize(&out, nOut);
blob_reset(&x);
blob_reset(&y);
blob_compress(&out, &out);
sqlite3_result_blob64(context, blob_buffer(&out), blob_size(&out),
SQLITE_TRANSIENT);
blob_reset(&out);
}
/*
** Generate a binary patch file and store it into the file
** named zOut. Or if zOut is NULL, write it into out.
**
|
| ︙ | ︙ | |||
385 386 387 388 389 390 391 |
blob_init(&cmd, 0, 0);
if( unsaved_changes(0) ){
if( (mFlags & PATCH_FORCE)==0 ){
fossil_fatal("Cannot apply patch: there are unsaved changes "
"in the current check-out");
}else{
| | | 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
blob_init(&cmd, 0, 0);
if( unsaved_changes(0) ){
if( (mFlags & PATCH_FORCE)==0 ){
fossil_fatal("Cannot apply patch: there are unsaved changes "
"in the current check-out");
}else{
blob_appendf(&cmd, "%$ revert --noundo", g.nameOfExe);
if( mFlags & PATCH_DRYRUN ){
fossil_print("%s\n", blob_str(&cmd));
}else{
int rc = fossil_system(blob_str(&cmd));
if( rc ){
fossil_fatal("unable to revert preexisting changes: %s",
blob_str(&cmd));
|
| ︙ | ︙ | |||
427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 |
fossil_fatal("unable to update to the baseline check-out: %s",
blob_str(&cmd));
}
}
}
blob_reset(&cmd);
if( db_table_exists("patch","patchmerge") ){
db_prepare(&q,
"SELECT type, mhash, upper(type) FROM patch.patchmerge"
" WHERE type IN ('merge','cherrypick','backout','integrate')"
" AND mhash NOT GLOB '*[^a-fA-F0-9]*';"
);
while( db_step(&q)==SQLITE_ROW ){
const char *zType = db_column_text(&q,0);
blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
if( strcmp(zType,"merge")==0 ){
| > | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 |
fossil_fatal("unable to update to the baseline check-out: %s",
blob_str(&cmd));
}
}
}
blob_reset(&cmd);
if( db_table_exists("patch","patchmerge") ){
int nMerge = 0;
db_prepare(&q,
"SELECT type, mhash, upper(type) FROM patch.patchmerge"
" WHERE type IN ('merge','cherrypick','backout','integrate')"
" AND mhash NOT GLOB '*[^a-fA-F0-9]*';"
);
while( db_step(&q)==SQLITE_ROW ){
const char *zType = db_column_text(&q,0);
blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
if( strcmp(zType,"merge")==0 ){
blob_appendf(&cmd, " merge --noundo --nosync %s\n",
db_column_text(&q,1));
}else{
blob_appendf(&cmd, " merge --%s --noundo --nosync %s\n",
zType, db_column_text(&q,1));
}
nMerge++;
if( mFlags & PATCH_VERBOSE ){
fossil_print("%-10s %s\n", db_column_text(&q,2),
db_column_text(&q,0));
}
}
db_finalize(&q);
if( mFlags & PATCH_DRYRUN ){
fossil_print("%s", blob_str(&cmd));
}else{
int rc = fossil_unsafe_system(blob_str(&cmd));
if( rc ){
fossil_fatal("unable to do merges:\n%s",
blob_str(&cmd));
}
}
blob_reset(&cmd);
/* 2024-12-16 https://fossil-scm.org/home/forumpost/51a37054
** If one or more merge operations occurred in the patch and there are
** files that are marked as "chnged' in the local VFILE but which
** are not mentioned as having been modified in the patch, then
** revert those files.
*/
if( nMerge ){
int vid = db_lget_int("checkout", 0);
int nRevert = 0;
blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
blob_appendf(&cmd, " revert --noundo ");
db_prepare(&q,
"SELECT pathname FROM vfile WHERE vid=%d AND chnged "
"EXCEPT SELECT pathname FROM chng",
vid
);
while( db_step(&q)==SQLITE_ROW ){
blob_append_escaped_arg(&cmd, db_column_text(&q,0), 1);
nRevert++;
}
db_finalize(&q);
if( nRevert ){
if( mFlags & PATCH_DRYRUN ){
fossil_print("%s", blob_str(&cmd));
}else{
int rc = fossil_unsafe_system(blob_str(&cmd));
if( rc ){
fossil_fatal("unable to do reverts:\n%s",
blob_str(&cmd));
}
}
}
blob_reset(&cmd);
}
}
/* Deletions */
db_prepare(&q, "SELECT pathname FROM patch.chng"
" WHERE origname IS NULL AND delta IS NULL");
while( db_step(&q)==SQLITE_ROW ){
if( blob_size(&cmd)==0 ){
|
| ︙ | ︙ |
Changes to src/printf.c.
| ︙ | ︙ | |||
103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
#define etROOT 24 /* String value of g.zTop: %R */
#define etJSONSTR 25 /* String encoded as a JSON string literal: %j
Use %!j to include double-quotes around it. */
#define etSHELLESC 26 /* Escape a filename for use in a shell command: %$
See blob_append_escaped_arg() for details
"%$" -> adds "./" prefix if necessary.
"%!$" -> omits the "./" prefix. */
/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;
| > | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
#define etROOT 24 /* String value of g.zTop: %R */
#define etJSONSTR 25 /* String encoded as a JSON string literal: %j
Use %!j to include double-quotes around it. */
#define etSHELLESC 26 /* Escape a filename for use in a shell command: %$
See blob_append_escaped_arg() for details
"%$" -> adds "./" prefix if necessary.
"%!$" -> omits the "./" prefix. */
#define etHEX 27 /* Encode a string as hexadecimal */
/*
** An "etByte" is an 8-bit unsigned value.
*/
typedef unsigned char etByte;
|
| ︙ | ︙ | |||
140 141 142 143 144 145 146 | ** most frequently used conversion types first. ** ** NB: When modifying this table is it vital that you also update the fmtchr[] ** variable to match!!! */ static const char aDigits[] = "0123456789ABCDEF0123456789abcdef"; static const char aPrefix[] = "-x0\000X0"; | | | 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
** most frequently used conversion types first.
**
** NB: When modifying this table is it vital that you also update the fmtchr[]
** variable to match!!!
*/
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const char fmtchr[] = "dsgzqQbBWhRtTwFSjcouxXfeEGin%p/$H";
static const et_info fmtinfo[] = {
{ 'd', 10, 1, etRADIX, 0, 0 },
{ 's', 0, 4, etSTRING, 0, 0 },
{ 'g', 0, 1, etGENERIC, 30, 0 },
{ 'z', 0, 6, etDYNSTRING, 0, 0 },
{ 'q', 0, 4, etSQLESCAPE, 0, 0 },
{ 'Q', 0, 4, etSQLESCAPE2, 0, 0 },
|
| ︙ | ︙ | |||
174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
{ 'G', 0, 1, etGENERIC, 14, 0 },
{ 'i', 10, 1, etRADIX, 0, 0 },
{ 'n', 0, 0, etSIZE, 0, 0 },
{ '%', 0, 0, etPERCENT, 0, 0 },
{ 'p', 16, 0, etPOINTER, 0, 1 },
{ '/', 0, 0, etPATH, 0, 0 },
{ '$', 0, 0, etSHELLESC, 0, 0 },
{ etERROR, 0,0,0,0,0} /* Must be last */
};
#define etNINFO count(fmtinfo)
/*
** Verify that the fmtchr[] and fmtinfo[] arrays are in agreement.
**
| > | 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
{ 'G', 0, 1, etGENERIC, 14, 0 },
{ 'i', 10, 1, etRADIX, 0, 0 },
{ 'n', 0, 0, etSIZE, 0, 0 },
{ '%', 0, 0, etPERCENT, 0, 0 },
{ 'p', 16, 0, etPOINTER, 0, 1 },
{ '/', 0, 0, etPATH, 0, 0 },
{ '$', 0, 0, etSHELLESC, 0, 0 },
{ 'H', 0, 0, etHEX, 0, 0 },
{ etERROR, 0,0,0,0,0} /* Must be last */
};
#define etNINFO count(fmtinfo)
/*
** Verify that the fmtchr[] and fmtinfo[] arrays are in agreement.
**
|
| ︙ | ︙ | |||
841 842 843 844 845 846 847 848 849 850 851 852 853 854 |
break;
}
case etSHELLESC: {
char *zArg = va_arg(ap, char*);
blob_append_escaped_arg(pBlob, zArg, !flag_altform2);
length = width = 0;
break;
}
case etERROR:
buf[0] = '%';
buf[1] = c;
errorflag = 0;
idx = 1+(c!=0);
blob_append(pBlob,"%",idx);
| > > > > > > > > > > > | 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 |
break;
}
case etSHELLESC: {
char *zArg = va_arg(ap, char*);
blob_append_escaped_arg(pBlob, zArg, !flag_altform2);
length = width = 0;
break;
}
case etHEX: {
char *zArg = va_arg(ap, char*);
int szArg = (int)strlen(zArg);
int szBlob = blob_size(pBlob);
u8 *aBuf;
blob_resize(pBlob, szBlob+szArg*2+1);
aBuf = (u8*)&blob_buffer(pBlob)[szBlob];
encode16((const u8*)zArg, aBuf, szArg);
length = width = 0;
break;
}
case etERROR:
buf[0] = '%';
buf[1] = c;
errorflag = 0;
idx = 1+(c!=0);
blob_append(pBlob,"%",idx);
|
| ︙ | ︙ |
Changes to src/search.c.
| ︙ | ︙ | |||
16 17 18 19 20 21 22 | ******************************************************************************* ** ** This file contains code to implement a search functions ** against timeline comments, check-in content, wiki pages, tickets, ** and/or forum posts. ** ** The search can be either a per-query "grep"-like search that scans | | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ******************************************************************************* ** ** This file contains code to implement a search functions ** against timeline comments, check-in content, wiki pages, tickets, ** and/or forum posts. ** ** The search can be either a per-query "grep"-like search that scans ** the entire corpus. Or it can use the FTS5 search engine of SQLite. ** The choice is an administrator configuration option. ** ** The first option is referred to as "full-scan search". The second ** option is called "indexed search". ** ** The code in this file is ordered approximately as follows: ** |
| ︙ | ︙ | |||
568 569 570 571 572 573 574 | ** ** Usage: %fossil search [-a|-all] [-n|-limit #] [-W|-width #] pattern... ** ** Search for timeline entries matching all words provided on the ** command line. Whole-word matches scope more highly than partial ** matches. ** | | | 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 | ** ** Usage: %fossil search [-a|-all] [-n|-limit #] [-W|-width #] pattern... ** ** Search for timeline entries matching all words provided on the ** command line. Whole-word matches scope more highly than partial ** matches. ** ** Note: This command only searches the EVENT table. So it will only ** display check-in comments or other comments that appear on an ** unaugmented timeline. It does not search document text or forum ** messages. ** ** Outputs, by default, some top-N fraction of the results. The -all ** option can be used to output all matches, regardless of their search ** score. The -limit option can be used to limit the number of entries |
| ︙ | ︙ | |||
1036 1037 1038 1039 1040 1041 1042 |
static const char *zSnippetCall;
if( srchFlags==0 ) return;
sqlite3_create_function(g.db, "rank", 1, SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
search_rank_sqlfunc, 0, 0);
zPat = search_simplify_pattern(zPattern);
blob_init(&sql, 0, 0);
if( search_index_type(0)==4 ){
| | | 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 |
static const char *zSnippetCall;
if( srchFlags==0 ) return;
sqlite3_create_function(g.db, "rank", 1, SQLITE_UTF8|SQLITE_INNOCUOUS, 0,
search_rank_sqlfunc, 0, 0);
zPat = search_simplify_pattern(zPattern);
blob_init(&sql, 0, 0);
if( search_index_type(0)==4 ){
/* If this repo is still using the legacy FTS5 search index, then
** the snippet() function is slightly different */
zSnippetCall = "snippet(ftsidx,'<mark>','</mark>',' ... ',-1,35)";
}else{
/* This is the common case - Using newer FTS5 search index */
zSnippetCall = "snippet(ftsidx,-1,'<mark>','</mark>',' ... ',35)";
}
blob_appendf(&sql,
|
| ︙ | ︙ |
Changes to src/security_audit.c.
| ︙ | ︙ | |||
541 542 543 544 545 546 547 |
@ up by the webserver contains the name of an authenticated user.
@ Fossil's built-in authentication mechanism is bypassed.
@ Fix this by deactivating the "Allow REMOTE_USER authentication"
@ checkbox on the <a href="setup_access">Access Control</a> page.
}
if( db_get_boolean("http_authentication_ok", 0) ){
@ <li><p><b>Caution:</b>
| | | 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 |
@ up by the webserver contains the name of an authenticated user.
@ Fossil's built-in authentication mechanism is bypassed.
@ Fix this by deactivating the "Allow REMOTE_USER authentication"
@ checkbox on the <a href="setup_access">Access Control</a> page.
}
if( db_get_boolean("http_authentication_ok", 0) ){
@ <li><p><b>Caution:</b>
@ This repository trusts that the HTTP_AUTHENTICATION environment
@ variable set up by the webserver contains the name of an
@ authenticated user.
@ Fossil's built-in authentication mechanism is bypassed.
@ Fix this by deactivating the "Allow HTTP_AUTHENTICATION authentication"
@ checkbox on the <a href="setup_access">Access Control</a> page.
}
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
36 37 38 39 40 41 42 |
}
db_protect_pop();
}
}
/*
** Output a single entry for a menu generated using an HTML table.
| | | | | | 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 |
}
db_protect_pop();
}
}
/*
** Output a single entry for a menu generated using an HTML table.
** If zLink is neither NULL nor an empty string, then it is the page that
** the menu entry will hyperlink to. If zLink is NULL or "", then
** the menu entry has no hyperlink - it is disabled.
*/
void setup_menu_entry(
const char *zTitle,
const char *zLink,
const char *zDesc /* Caution! Rendered using %s. May contain raw HTML. */
){
@ <tr><td valign="top" align="right">
if( zLink && zLink[0] ){
@ <a href="%s(zLink)"><nobr>%h(zTitle)</nobr></a>
}else{
@ <nobr>%h(zTitle)</nobr>
}
@ </td><td width="5"></td><td valign="top">%s(zDesc)</td></tr>
}
/*
** WEBPAGE: setup
**
|
| ︙ | ︙ | |||
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
** Show a menu of available log renderings accessible to an administrator,
** together with a succinct explanation of each.
**
** This page is only accessible by administrators.
*/
void setup_logmenu_page(void){
Blob desc;
blob_init(&desc, 0, 0);
/* Administrator access only */
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_header("Log Menu");
@ <table border="0" cellspacing="3">
| > > > > > > > > > > > | | | | > | < | > > > > > > > > | > | > > | > | > > > | > > > > | > > > > > > > > | > | < > > | < < | > | < | > < | | < | | < | 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 233 234 235 236 237 238 239 240 241 242 243 244 245 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 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
** Show a menu of available log renderings accessible to an administrator,
** together with a succinct explanation of each.
**
** This page is only accessible by administrators.
*/
void setup_logmenu_page(void){
Blob desc;
int bErrLog; /* True if Error Log enabled */
blob_init(&desc, 0, 0);
/* Administrator access only */
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_header("Log Menu");
@ <table border="0" cellspacing="3">
if( db_get_boolean("admin-log",0)==0 ){
blob_appendf(&desc,
"The admin log records configuration changes to the repository.\n"
"<b>Disabled</b>: Turn on the "
" <a href='%R/setup_settings'>admin-log setting</a> to enable."
);
setup_menu_entry("Admin Log", 0, blob_str(&desc));
blob_reset(&desc);
}else{
setup_menu_entry("Admin Log", "admin_log",
"The admin log records configuration changes to the repository\n"
"in the \"admin_log\" table.\n"
);
}
setup_menu_entry("Artifact Log", "rcvfromlist",
"The artifact log records when new content is added in the\n"
"\"rcvfrom\" table.\n"
);
if( db_get_boolean("access-log",0) ){
setup_menu_entry("User Log", "user_log",
"Login attempts recorded in the \"accesslog\" table."
);
}else{
blob_appendf(&desc,
"Login attempts recorded in the \"accesslog\" table.\n"
"<b>Disabled</b>: Turn on the "
"<a href='%R/setup_settings'>access-log setting</a> to enable."
);
setup_menu_entry("User Log", 0, blob_str(&desc));
blob_reset(&desc);
}
blob_appendf(&desc,
"A separate text file to which warning and error\n"
"messages are appended. A single error log can and often is shared\n"
"across multiple repositories.\n"
);
if( g.zErrlog==0 || fossil_strcmp(g.zErrlog,"-")==0 ){
blob_appendf(&desc,"<b>Disabled</b>: "
"To enable the error log ");
if( fossil_strcmp(g.zCmdName, "cgi")==0 ){
blob_appendf(&desc,
"make an entry like \"errorlog: <i>FILENAME</i>\""
" in the CGI script at %h",
P("SCRIPT_FILENAME")
);
}else{
blob_appendf(&desc,
" add the \"--errorlog <i>FILENAME</i>\" option to the\n"
"\"%h %h\" command that launched the server.",
g.argv[0], g.zCmdName
);
}
bErrLog = 0;
}else{
blob_appendf(&desc,"In this repository, the error log is the file "
"named \"%s\".", g.zErrlog);
bErrLog = 1;
}
setup_menu_entry("Error Log", bErrLog ? "errorlog" : 0, blob_str(&desc));
blob_reset(&desc);
@ <tr><td><td><td>
@ ——
@ <i>The remaining links are subsets of the Error Log</i>
@ ——
@ </td>
setup_menu_entry("Panic Log", bErrLog ? "paniclog" : 0,
"Only the most important messages in the Error Log:\n"
"assertion faults, segmentation faults, and similar malfunctions.\n"
);
setup_menu_entry("Hack Log", bErrLog ? "hacklog" : 0,
"All code-418 hack attempts in the Error Log"
);
setup_menu_entry("Non-Hack Log", bErrLog ? "hacklog?not" : 0,
"All log messages that are not code-418 hack attempts"
);
@ </table>
style_finish_page();
}
/*
** Generate a checkbox for an attribute.
|
| ︙ | ︙ |
Changes to src/sitemap.c.
| ︙ | ︙ | |||
54 55 56 57 58 59 60 |
int srchFlags;
int inSublist = 0;
int i;
int isPopup = 0; /* This is an XMLHttpRequest() for /sitemap */
int e = atoi(PD("e","0"));
const char *zExtra;
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 54 55 56 57 58 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 |
int srchFlags;
int inSublist = 0;
int i;
int isPopup = 0; /* This is an XMLHttpRequest() for /sitemap */
int e = atoi(PD("e","0"));
const char *zExtra;
login_check_credentials();
if( P("popup")!=0 ){
/* The "popup" query parameter
** then disable anti-robot defenses */
isPopup = 1;
g.perm.Hyperlink = 1;
g.jsHref = 0;
}
srchFlags = search_restrict(SRCH_ALL);
if( !isPopup ){
style_header("Site Map");
style_adunit_config(ADUNIT_RIGHT_OK);
}
@ <ul id="sitemap" class="columns" style="column-width:20em">
if( (e&1)==0 ){
@ <li>%z(href("%R/home"))Home Page</a>
}
zExtra = db_get("sitemap-extra",0);
if( zExtra && (e&2)==0 ){
int rc;
char **azExtra = 0;
int *anExtra;
int nExtra = 0;
if( isPopup ) Th_FossilInit(0);
|
| ︙ | ︙ | |||
137 138 139 140 141 142 143 |
}
}
}
Th_Free(g.interp, azExtra);
}
if( (e&1)!=0 ) goto end_of_sitemap;
| < < < < < < < < < < < > > > | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
}
}
}
Th_Free(g.interp, azExtra);
}
if( (e&1)!=0 ) goto end_of_sitemap;
if( inSublist ){
@ </ul>
inSublist = 0;
}
@ </li>
if( cgi_is_loopback(g.zIpAddr) && db_open_local(0) ){
@ <li>%z(href("%R/ckout"))Checkout Status</a></li>
}
if( g.perm.Read ){
const char *zEditGlob = db_get("fileedit-glob","");
@ <li>%z(href("%R/tree"))File Browser</a>
@ <ul>
@ <li>%z(href("%R/tree?type=tree&ci=trunk"))Tree-view,
@ Trunk Check-in</a></li>
@ <li>%z(href("%R/tree?type=flat"))Flat-view</a></li>
|
| ︙ | ︙ |
Changes to src/statrep.c.
| ︙ | ︙ | |||
288 289 290 291 292 293 294 |
rowClass = ++nRowNumber % 2;
nEventTotal += nCount;
nEventsPerYear += nCount;
@<tr class='row%d(rowClass)'>
@ <td>
if(includeMonth){
cgi_printf("<a href='%R/timeline?"
| | | | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
rowClass = ++nRowNumber % 2;
nEventTotal += nCount;
nEventsPerYear += nCount;
@<tr class='row%d(rowClass)'>
@ <td>
if(includeMonth){
cgi_printf("<a href='%R/timeline?"
"ym=%t&y=%s",
zTimeframe,
statsReportTimelineYFlag );
/* Reminder: n=nCount is not actually correct for bymonth unless
that was the only user who caused events.
*/
if( zUserName ){
cgi_printf("&u=%t", zUserName);
}
|
| ︙ | ︙ | |||
729 730 731 732 733 734 735 |
const int nCount = db_column_int(&q,1);
int nSize = (nCount>0 && nMaxEvents>0)
? (int)(100 * nCount / nMaxEvents)
: 0;
if(!nSize) nSize = 1;
total += nCount;
cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
| | | | 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 |
const int nCount = db_column_int(&q,1);
int nSize = (nCount>0 && nMaxEvents>0)
? (int)(100 * nCount / nMaxEvents)
: 0;
if(!nSize) nSize = 1;
total += nCount;
cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
cgi_printf("<td><a href='%R/timeline?yw=%t%s&y=%s",
zYear, zWeek,
statsReportTimelineYFlag);
if( zUserName ){
cgi_printf("&u=%t",zUserName);
}
cgi_printf("'>%s</a></td>",zWeek);
cgi_printf("<td>%d</td>",nCount);
|
| ︙ | ︙ |
Changes to src/style.c.
| ︙ | ︙ | |||
819 820 821 822 823 824 825 826 827 828 829 830 831 832 |
headerHasBeenGenerated = 1;
sideboxUsed = 0;
if( g.perm.Debug && P("showqp") ){
@ <div class="debug">
cgi_print_all(0, 0, 0);
@ </div>
}
}
#if INTERFACE
/* Allowed parameters for style_adunit() */
#define ADUNIT_OFF 0x0001 /* Do not allow ads on this page */
#define ADUNIT_RIGHT_OK 0x0002 /* Right-side vertical ads ok here */
#endif
| > | 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 |
headerHasBeenGenerated = 1;
sideboxUsed = 0;
if( g.perm.Debug && P("showqp") ){
@ <div class="debug">
cgi_print_all(0, 0, 0);
@ </div>
}
fossil_free(zTitle);
}
#if INTERFACE
/* Allowed parameters for style_adunit() */
#define ADUNIT_OFF 0x0001 /* Do not allow ads on this page */
#define ADUNIT_RIGHT_OK 0x0002 /* Right-side vertical ads ok here */
#endif
|
| ︙ | ︙ | |||
1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 |
*/
Th_Store("baseurl", g.zBaseURL);
Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL);
Th_Store("home", g.zTop);
image_url_var("logo");
image_url_var("background");
Th_Render(blob_str(&css));
/* Tell CGI that the content returned by this page is considered cacheable */
g.isConst = 1;
}
/*
** All possible capabilities
| > | 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 |
*/
Th_Store("baseurl", g.zBaseURL);
Th_Store("secureurl", fossil_wants_https(1)? g.zHttpsURL: g.zBaseURL);
Th_Store("home", g.zTop);
image_url_var("logo");
image_url_var("background");
Th_Render(blob_str(&css));
blob_reset(&css);
/* Tell CGI that the content returned by this page is considered cacheable */
g.isConst = 1;
}
/*
** All possible capabilities
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
189 190 191 192 193 194 195 | ** 10. Short comment to user for repeated tickets and wiki */ void www_print_timeline( Stmt *pQuery, /* Query to implement the timeline */ int tmFlags, /* Flags controlling display behavior */ const char *zThisUser, /* Suppress links to this user */ const char *zThisTag, /* Suppress links to this tag */ | | | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
** 10. Short comment to user for repeated tickets and wiki
*/
void www_print_timeline(
Stmt *pQuery, /* Query to implement the timeline */
int tmFlags, /* Flags controlling display behavior */
const char *zThisUser, /* Suppress links to this user */
const char *zThisTag, /* Suppress links to this tag */
Matcher *pLeftBranch, /* Comparison function to use for zLeftBranch */
int selectedRid, /* Highlight the line with this RID value or zero */
int secondRid, /* Secondary highlight (or zero) */
void (*xExtra)(int) /* Routine to call on each line of display */
){
int mxWikiLen;
Blob comment;
int prevTagid = 0;
|
| ︙ | ︙ | |||
811 812 813 814 815 816 817 |
@ event%s(suppressCnt>1?"s":"") omitted.</span>
suppressCnt = 0;
}
if( pendingEndTr ){
@ </td></tr>
}
if( pGraph ){
| | | 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 |
@ event%s(suppressCnt>1?"s":"") omitted.</span>
suppressCnt = 0;
}
if( pendingEndTr ){
@ </td></tr>
}
if( pGraph ){
graph_finish(pGraph, pLeftBranch, tmFlags);
if( pGraph->nErr ){
graph_free(pGraph);
pGraph = 0;
}else{
@ <tr class="timelineBottom" id="btm-%d(iTableId)">\
@ <td></td><td></td><td></td></tr>
}
|
| ︙ | ︙ | |||
1288 1289 1290 1291 1292 1293 1294 |
*/
static void addFileGlobExclusion(
const char *zChng, /* The filename GLOB list */
Blob *pSql /* The SELECT statement under construction */
){
if( zChng==0 || zChng[0]==0 ) return;
blob_append_sql(pSql," AND event.objid IN ("
| | | > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | | < | > > > > > > > | | < | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 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 |
*/
static void addFileGlobExclusion(
const char *zChng, /* The filename GLOB list */
Blob *pSql /* The SELECT statement under construction */
){
if( zChng==0 || zChng[0]==0 ) return;
blob_append_sql(pSql," AND event.objid IN ("
"SELECT mlink.mid FROM mlink, filename\n"
" WHERE mlink.fnid=filename.fnid\n"
" AND %s)",
glob_expr("filename.name", mprintf("\"%s\"", zChng)));
}
static void addFileGlobDescription(
const char *zChng, /* The filename GLOB list */
Blob *pDescription /* Result description */
){
if( zChng==0 || zChng[0]==0 ) return;
blob_appendf(pDescription, " that include changes to files matching '%h'",
zChng);
}
/*
** Similar to fossil_expand_datetime()
**
** Add missing "-" characters into a date/time. Examples:
**
** 20190419 => 2019-04-19
** 201904 => 2019-04
*/
const char *timeline_expand_datetime(const char *zIn, int *pbZulu){
static char zEDate[16];
int n = (int)strlen(zIn);
int i, j;
/* These forms are recognized:
**
** (1) YYYYMMDD
** (2) YYYYMM
** (3) YYYYWW
*/
if( n && (zIn[n-1]=='Z' || zIn[n-1]=='z') ){
n--;
if( pbZulu ) *pbZulu = 1;
}else{
if( pbZulu ) *pbZulu = 0;
}
if( n!=8 && n!=6 ) return zIn;
/* Every character must be a digit */
for(i=0; i<n && fossil_isdigit(zIn[i]); i++){}
if( i!=n ) return zIn;
/* Expand the date */
for(i=j=0; i<n; i++){
if( j==4 || j==7 ) zEDate[j++] = '-';
zEDate[j++] = zIn[i];
}
zEDate[j] = 0;
/* It looks like this may be a date. Return it with punctuation added. */
return zEDate;
}
/*
** Check to see if the argument is a date-span for the ymd= query
** parameter. A valid date-span is of the form:
**
** 0123456789 123456 <-- index
** YYYYMMDD-YYYYMMDD
**
** with an optional "Z" timeline modifier at the end. Return true if
** the input is a valid date space and false if not.
*/
static int timeline_is_datespan(const char *zDay){
size_t n = strlen(zDay);
int i, d, m;
if( n<17 || n>18 ) return 0;
if( n==18 ){
if( zDay[17]!='Z' && zDay[17]!='z' ) return 0;
n--;
}
if( zDay[8]!='-' ) return 0;
for(i=0; i<17 && (fossil_isdigit(zDay[i]) || i==8); i++){}
if( i!=17 ) return 0;
i = atoi(zDay);
d = i%100;
if( d<1 || d>31 ) return 0;
m = (i/100)%100;
if( m<1 || m>12 ) return 0;
i = atoi(zDay+9);
d = i%100;
if( d<1 || d>31 ) return 0;
m = (i/100)%100;
if( m<1 || m>12 ) return 0;
return 1;
}
/*
** Find the first check-in encountered with a particular tag
** when moving either forwards are backwards in time from a
** particular starting point (iFrom). Return the rid of that
** first check-in. If there are no check-ins in the decendent
** or ancestor set of check-in iFrom that match the tag, then
|
| ︙ | ︙ | |||
1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 |
int ans = 0;
tagId = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zEnd);
if( tagId==0 ){
endId = symbolic_name_to_rid(zEnd, "ci");
if( endId==0 ) return 0;
}
if( bForward ){
if( tagId ){
db_prepare(&q,
"WITH RECURSIVE dx(id,mtime) AS ("
" SELECT %d, event.mtime FROM event WHERE objid=%d"
" UNION"
" SELECT plink.cid, plink.mtime"
| > | 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 |
int ans = 0;
tagId = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zEnd);
if( tagId==0 ){
endId = symbolic_name_to_rid(zEnd, "ci");
if( endId==0 ) return 0;
}
db_pause_dml_log();
if( bForward ){
if( tagId ){
db_prepare(&q,
"WITH RECURSIVE dx(id,mtime) AS ("
" SELECT %d, event.mtime FROM event WHERE objid=%d"
" UNION"
" SELECT plink.cid, plink.mtime"
|
| ︙ | ︙ | |||
1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 |
);
}
}
if( db_step(&q)==SQLITE_ROW ){
ans = db_column_int(&q, 0);
}
db_finalize(&q);
return ans;
}
/*
** COMMAND: test-endpoint
**
** Usage: fossil test-endpoint BASE TAG ?OPTIONS?
**
** Show the first check-in with TAG that is a descendent or ancestor
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 |
);
}
}
if( db_step(&q)==SQLITE_ROW ){
ans = db_column_int(&q, 0);
}
db_finalize(&q);
db_unpause_dml_log();
return ans;
}
/*
** Add to the (temp) table zTab, RID values for every check-in
** identifier found on the zExtra string. Check-in names can be separated
** by commas or by whitespace.
*/
static void add_extra_rids(const char *zTab, const char *zExtra){
int ii;
int rid;
int cnt;
Blob sql;
char *zX;
char *zToDel;
if( zExtra==0 ) return;
cnt = 0;
blob_init(&sql, 0, 0);
zX = zToDel = fossil_strdup(zExtra);
blob_append_sql(&sql, "INSERT OR IGNORE INTO \"%w\" VALUES", zTab);
while( zX[0] ){
char c;
if( zX[0]==',' || zX[0]==' ' ){ zX++; continue; }
for(ii=1; zX[ii] && zX[ii]!=',' && zX[ii]!=' '; ii++){}
c = zX[ii];
zX[ii] = 0;
rid = name_to_rid(zX);
if( rid>0 ){
if( (cnt%10)==4 ){
blob_append_sql(&sql,",\n ");
}else if( cnt>0 ){
blob_append_sql(&sql,",");
}
blob_append_sql(&sql, "(%d)", rid);
cnt++;
}
zX[ii] = c;
zX += ii;
}
if( cnt ) db_exec_sql(blob_sql_text(&sql));
blob_reset(&sql);
fossil_free(zToDel);
}
/*
** COMMAND: test-endpoint
**
** Usage: fossil test-endpoint BASE TAG ?OPTIONS?
**
** Show the first check-in with TAG that is a descendent or ancestor
|
| ︙ | ︙ | |||
1696 1697 1698 1699 1700 1701 1702 | /* ** WEBPAGE: timeline ** ** Query parameters: ** | | | | | | | 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 | /* ** WEBPAGE: timeline ** ** Query parameters: ** ** a=TIMEORTAG Show events after TIMEORTAG. ** b=TIMEORTAG Show events before TIMEORTAG. ** c=TIMEORTAG Show events that happen "circa" TIMEORTAG ** cf=FILEHASH Show events around the time of the first use of ** the file with FILEHASH. ** m=TIMEORTAG Highlight the event at TIMEORTAG, or the closest available ** event if TIMEORTAG is not part of the timeline. If ** the t= or r= is used, the m event is added to the timeline ** if it isn't there already. ** x=LIST Show check-ins in the comma- or space-separated LIST ** in addition to check-ins specified by other parameters. ** sel1=TIMEORTAG Highlight the check-in at TIMEORTAG if it is part of ** the timeline. Similar to m= except TIMEORTAG must ** match a check-in that is already in the timeline. ** sel2=TIMEORTAG Like sel1= but use the secondary highlight. ** n=COUNT Maximum number of events. "all" for no limit ** n1=COUNT Same as "n" but doesn't set the display-preference cookie ** Use "n1=COUNT" for a one-time display change |
| ︙ | ︙ | |||
1730 1731 1732 1733 1734 1735 1736 | ** bt=CHECKIN "Back To". Show ancenstors going back to CHECKIN ** p=CX ... from CX back to time of CHECKIN ** from=CX ... shortest path from CX back to CHECKIN ** ft=CHECKIN "Forward To": Show decendents forward to CHECKIN ** d=CX ... from CX up to the time of CHECKIN ** from=CX ... shortest path from CX up to CHECKIN ** t=TAG Show only check-ins with the given TAG | | | | > > | | > | | | > > > | | | | | | | | > > | | 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 | ** bt=CHECKIN "Back To". Show ancenstors going back to CHECKIN ** p=CX ... from CX back to time of CHECKIN ** from=CX ... shortest path from CX back to CHECKIN ** ft=CHECKIN "Forward To": Show decendents forward to CHECKIN ** d=CX ... from CX up to the time of CHECKIN ** from=CX ... shortest path from CX up to CHECKIN ** t=TAG Show only check-ins with the given TAG ** r=TAG Same as 't=TAG&rel'. Mnemonic: "Related" ** tl=TAGLIST Same as 't=TAGLIST&ms=brlist'. Mnemonic: "Tag List" ** rl=TAGLIST Same as 'r=TAGLIST&ms=brlist'. Mnemonic: "Related List" ** ml=TAGLIST Same as 'tl=TAGLIST&mionly'. Mnemonic: "Merge-in List" ** sl=TAGLIST "Sort List". Draw TAGLIST branches ordered left to right. ** rel Show related check-ins as well as those matching t=TAG ** mionly Show related parents but not related children. ** nowiki Do not show wiki associated with branch or tag ** ms=MATCHSTYLE Set tag name match algorithm. One of "exact", "glob", ** "like", or "regexp". ** u=USER Only show items associated with USER ** y=TYPE 'ci', 'w', 't', 'n', 'e', 'f', or 'all'. ** ss=VIEWSTYLE c: "Compact", v: "Verbose", m: "Modern", j: "Columnar", * x: "Classic". ** advm Use the "Advanced" or "Busy" menu design. ** ng No Graph. ** ncp Omit cherrypick merges ** nd Do not highlight the focus check-in ** nsm Omit the submenu ** nc Omit all graph colors other than highlights ** v Show details of files changed ** vfx Show complete text of forum messages ** f=CHECKIN Family (immediate parents and children) of CHECKIN ** from=CHECKIN Path through common ancestor from... ** to=CHECKIN ... to this ** to2=CHECKIN ... backup name if to= doesn't resolve ** shortest ... show only the shortest path ** rel ... also show related checkins ** bt=PRIOR ... path from CHECKIN back to PRIOR ** ft=LATER ... path from CHECKIN forward to LATER ** me=CHECKIN Most direct path from... ** you=CHECKIN ... to this ** rel ... also show related checkins ** uf=FILE_HASH Show only check-ins that contain the given file version ** All qualifying check-ins are shown unless there is ** also an n= or n1= query parameter. ** chng=GLOBLIST Show only check-ins that involve changes to a file whose ** name matches one of the comma-separate GLOBLIST ** brbg Background color determined by branch name ** ubg Background color determined by user ** deltabg Background color red for delta manifests or green ** for baseline manifests ** namechng Show only check-ins that have filename changes ** forks Show only forks and their children ** cherrypicks Show all cherrypicks ** ym=YYYYMM Show only events for the given year/month ** yw=YYYYWW Show only events for the given week of the given year ** yw=YYYYMMDD Show events for the week that includes the given day ** ymd=YYYYMMDD Show only events on the given day. The use "ymd=now" ** to see all changes for the current week. Add "z" at end ** to divide days at UTC instead of localtime days. ** Use ymd=YYYYMMDD-YYYYMMDD (with optional "z") for a range. ** year=YYYY Show only events on the given year. The use "year=0" ** to see all changes for the current year. ** days=N Show events over the previous N days ** datefmt=N Override the date format: 0=HH:MM, 1=HH:MM:SS, ** 2=YYYY-MM-DD HH:MM:SS, 3=YYMMDD HH:MM, and 4 means "off". ** bisect Show the check-ins that are in the current bisect ** oldestfirst Show events oldest first. ** showid Show RIDs ** showsql Show the SQL used to generate the report ** ** p= and d= can appear individually or together. If either p= or d= ** appear, then u=, y=, a=, and b= are ignored. ** ** If both a= and b= appear then both upper and lower bounds are honored. ** ** When multiple time-related filters are used, e.g. ym, yw, and ymd, |
| ︙ | ︙ | |||
1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 |
int secondaryRid = 0; /* Show secondary highlight */
int disableY = 0; /* Disable type selector on submenu */
int advancedMenu = 0; /* Use the advanced menu design */
char *zPlural; /* Ending for plural forms */
int showCherrypicks = 1; /* True to show cherrypick merges */
int haveParameterN; /* True if n= query parameter present */
int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
login_check_credentials();
url_initialize(&url, "timeline");
cgi_query_parameters_to_url(&url);
(void)P_NoBot("ss")
/* "ss" is processed via the udc but at least one spider likes to
** try to SQL inject via this argument, so let's catch that. */;
/* Set number of rows to display */
z = P("n");
| > > > > > > | 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 |
int secondaryRid = 0; /* Show secondary highlight */
int disableY = 0; /* Disable type selector on submenu */
int advancedMenu = 0; /* Use the advanced menu design */
char *zPlural; /* Ending for plural forms */
int showCherrypicks = 1; /* True to show cherrypick merges */
int haveParameterN; /* True if n= query parameter present */
int from_to_mode = 0; /* 0: from,to. 1: from,ft 2: from,bt */
int showSql = PB("showsql"); /* True to show the SQL */
Blob allSql; /* Copy of all SQL text */
login_check_credentials();
url_initialize(&url, "timeline");
cgi_query_parameters_to_url(&url);
blob_init(&allSql, 0, 0);
/* The "mionly" query parameter is like "rel", but shows merge-ins only */
if( P("mionly")!=0 ) related = 2;
(void)P_NoBot("ss")
/* "ss" is processed via the udc but at least one spider likes to
** try to SQL inject via this argument, so let's catch that. */;
/* Set number of rows to display */
z = P("n");
|
| ︙ | ︙ | |||
1982 1983 1984 1985 1986 1987 1988 1989 |
);
}
/* Check for tl=TAGLIST and rl=TAGLIST which are abbreviations for
** t=TAGLIST&ms=brlist and r=TAGLIST&ms=brlist repectively. */
if( zBrName==0 && zTagName==0 ){
const char *z;
if( (z = P("tl"))!=0 ){
| > | < < | | | > > > > > > > > > > > | > | | > < < | < < < < < < < | | 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 |
);
}
/* Check for tl=TAGLIST and rl=TAGLIST which are abbreviations for
** t=TAGLIST&ms=brlist and r=TAGLIST&ms=brlist repectively. */
if( zBrName==0 && zTagName==0 ){
const char *z;
const char *zPattern = 0;
if( (z = P("tl"))!=0 ){
zPattern = zTagName = z;
}else if( (z = P("rl"))!=0 ){
zPattern = zBrName = z;
if( related==0 ) related = 1;
}else if( (z = P("ml"))!=0 ){
zPattern = zBrName = z;
if( related==0 ) related = 2;
}
if( zPattern!=0 && zMatchStyle==0 ){
/* If there was no ms= query parameter, set the match style to
** "glob" if the pattern appears to contain GLOB character, or
** "brlist" if it does not. */
if( strpbrk(zPattern,"*[?") ){
zMatchStyle = "glob";
}else{
zMatchStyle = "brlist";
}
}
}
/* Convert r=TAG to t=TAG&rel in order to populate the UI style widgets. */
if( zBrName ){
cgi_delete_query_parameter("r");
cgi_set_query_parameter("t", zBrName); (void)P("t");
cgi_set_query_parameter("rel", "1");
zTagName = zBrName;
if( related==0 ) related = 1;
zType = "ci";
}
/* Ignore empty tag query strings. */
if( zTagName && !*zTagName ){
zTagName = 0;
}
/* Finish preliminary processing of tag match queries. */
matchStyle = match_style(zMatchStyle, MS_EXACT);
if( zTagName ){
zType = "ci";
if( matchStyle==MS_EXACT ){
/* For exact maching, inhibit links to the selected tag. */
zThisTag = zTagName;
Th_Store("current_checkin", zTagName);
}
/* Display a checkbox to enable/disable display of related check-ins. */
if( advancedMenu ){
style_submenu_checkbox("rel", "Related", 0, 0);
}
/* Construct the tag match expression. */
zTagSql = match_tag_sqlexpr(matchStyle, zTagName, &zMatchDesc, &zError);
}
if( zMark && zMark[0]==0 ){
if( zAfter ) zMark = zAfter;
if( zBefore ) zMark = zBefore;
if( zCirca ) zMark = zCirca;
}
|
| ︙ | ︙ | |||
2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 |
if( PB("deltabg") ){
tmFlags |= TIMELINE_DELTA;
}
if( PB("nc") ){
tmFlags &= ~(TIMELINE_DELTA|TIMELINE_BRCOLOR|TIMELINE_UCOLOR);
tmFlags |= TIMELINE_NOCOLOR;
}
if( zUses!=0 ){
int ufid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUses);
if( ufid ){
zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid);
db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)");
compute_uses_file("usesfile", ufid, 0);
zType = "ci";
disableY = 1;
if( !haveParameterN ) nEntry = 0;
}else{
zUses = 0;
}
}
if( renameOnly ){
db_multi_exec(
"CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO rnfile"
| > | | | | | | | | | | | | | | | | 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 |
if( PB("deltabg") ){
tmFlags |= TIMELINE_DELTA;
}
if( PB("nc") ){
tmFlags &= ~(TIMELINE_DELTA|TIMELINE_BRCOLOR|TIMELINE_UCOLOR);
tmFlags |= TIMELINE_NOCOLOR;
}
if( showSql ) db_append_dml_to_blob(&allSql);
if( zUses!=0 ){
int ufid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUses);
if( ufid ){
zUses = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", ufid);
db_multi_exec("CREATE TEMP TABLE usesfile(rid INTEGER PRIMARY KEY)");
compute_uses_file("usesfile", ufid, 0);
zType = "ci";
disableY = 1;
if( !haveParameterN ) nEntry = 0;
}else{
zUses = 0;
}
}
if( renameOnly ){
db_multi_exec(
"CREATE TEMP TABLE rnfile(rid INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO rnfile"
" SELECT mid FROM mlink WHERE pfnid>0 AND pfnid!=fnid;"
);
disableY = 1;
}
if( forkOnly ){
db_multi_exec(
"CREATE TEMP TABLE rnfork(rid INTEGER PRIMARY KEY);\n"
"INSERT OR IGNORE INTO rnfork(rid)\n"
" SELECT pid FROM plink\n"
" WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
" GROUP BY pid\n"
" HAVING count(*)>1;\n"
"INSERT OR IGNORE INTO rnfork(rid)\n"
" SELECT cid FROM plink\n"
" WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
" GROUP BY cid\n"
" HAVING count(*)>1;\n",
TAG_BRANCH, TAG_BRANCH, TAG_BRANCH, TAG_BRANCH
);
db_multi_exec(
"INSERT OR IGNORE INTO rnfork(rid)\n"
" SELECT cid FROM plink\n"
" WHERE pid IN rnfork\n"
" AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
" UNION\n"
" SELECT pid FROM plink\n"
" WHERE cid IN rnfork\n"
" AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)==\n"
" (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n",
TAG_BRANCH, TAG_BRANCH, TAG_BRANCH, TAG_BRANCH
);
tmFlags |= TIMELINE_UNHIDE;
zType = "ci";
disableY = 1;
}
if( bisectLocal && cgi_is_loopback(g.zIpAddr) && db_open_local(0) ){
|
| ︙ | ︙ | |||
2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 |
/* If from= and to= are present, display all nodes on a path connecting
** the two */
PathNode *p = 0;
const char *zFrom = 0;
const char *zTo = 0;
Blob ins;
int nNodeOnPath = 0;
if( from_rid && to_rid ){
if( from_to_mode==0 ){
p = path_shortest(from_rid, to_rid, noMerge, 0, 0);
}else if( from_to_mode==1 ){
p = path_shortest(from_rid, to_rid, 0, 1, 0);
}else{
p = path_shortest(to_rid, from_rid, 0, 1, 0);
}
zFrom = P("from");
zTo = zTo2 ? zTo2 : P("to");
}else{
| > > > > > > | > > > > > > > | | > > > | > > > > > > | > | | | | | | | | > > > > > > > > > > > > > | | | | > | 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 |
/* If from= and to= are present, display all nodes on a path connecting
** the two */
PathNode *p = 0;
const char *zFrom = 0;
const char *zTo = 0;
Blob ins;
int nNodeOnPath = 0;
int commonAncs = 0; /* Common ancestors of me_rid and you_rid. */
int earlierRid = 0, laterRid = 0;
if( from_rid && to_rid ){
if( from_to_mode==0 ){
p = path_shortest(from_rid, to_rid, noMerge, 0, 0);
}else if( from_to_mode==1 ){
p = path_shortest(from_rid, to_rid, 0, 1, 0);
earlierRid = commonAncs = from_rid;
laterRid = to_rid;
}else{
p = path_shortest(to_rid, from_rid, 0, 1, 0);
earlierRid = commonAncs = to_rid;
laterRid = from_rid;
}
zFrom = P("from");
zTo = zTo2 ? zTo2 : P("to");
}else{
commonAncs = path_common_ancestor(me_rid, you_rid);
if( commonAncs!=0 ){
p = path_first();
}
if( commonAncs==you_rid ){
zFrom = P("you");
zTo = P("me");
earlierRid = you_rid;
laterRid = me_rid;
}else{
zFrom = P("me");
zTo = P("you");
earlierRid = me_rid;
laterRid = you_rid;
}
}
blob_init(&ins, 0, 0);
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS pathnode(x INTEGER PRIMARY KEY);"
);
if( p ){
int cnt = 4;
blob_init(&ins, 0, 0);
blob_append_sql(&ins, "INSERT INTO pathnode(x) VALUES(%d)", p->rid);
p = p->u.pTo;
while( p ){
if( cnt==8 ){
blob_append_sql(&ins, ",\n (%d)", p->rid);
cnt = 0;
}else{
cnt++;
blob_append_sql(&ins, ",(%d)", p->rid);
}
p = p->u.pTo;
}
}
path_reset();
db_multi_exec("%s", blob_str(&ins)/*safe-for-%s*/);
blob_reset(&ins);
if( related ){
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS related(x INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO related(x)"
" SELECT pid FROM plink WHERE cid IN pathnode AND NOT isprim;"
);
if( related==1 ){
db_multi_exec(
"INSERT OR IGNORE INTO related(x)"
" SELECT cid FROM plink WHERE pid IN pathnode;"
);
}
if( showCherrypicks ){
db_multi_exec(
"INSERT OR IGNORE INTO related(x)"
" SELECT parentid FROM cherrypick WHERE childid IN pathnode;"
);
if( related==1 ){
db_multi_exec(
"INSERT OR IGNORE INTO related(x)"
" SELECT childid FROM cherrypick WHERE parentid IN pathnode;"
);
}
}
if( earlierRid && laterRid && commonAncs==earlierRid ){
/* On a query with me=XXX, you=YYY, and rel, omit all nodes that
** are not ancestors of either XXX or YYY, as those nodes tend to
** be extraneous */
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
);
compute_ancestors(laterRid, 0, 0, earlierRid);
db_multi_exec(
"DELETE FROM related WHERE x NOT IN ok;"
);
}
db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related");
}
add_extra_rids("pathnode",P("x"));
blob_append_sql(&sql, " AND event.objid IN pathnode");
if( zChng && zChng[0] ){
db_multi_exec(
"DELETE FROM pathnode\n"
" WHERE NOT EXISTS(SELECT 1 FROM mlink, filename\n"
" WHERE mlink.mid=x\n"
" AND mlink.fnid=filename.fnid\n"
" AND %s)",
glob_expr("filename.name", zChng)
);
}
tmFlags |= TIMELINE_XMERGE | TIMELINE_FILLGAPS;
db_multi_exec("%s", blob_sql_text(&sql));
if( advancedMenu ){
style_submenu_checkbox("v", "Files", (zType[0]!='a' && zType[0]!='c'),0);
|
| ︙ | ︙ | |||
2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 |
if( p_rid && d_rid ){
if( p_rid!=d_rid ) p_rid = d_rid;
if( !haveParameterN ) nEntry = 10;
}
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
);
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
p_rid ? p_rid : d_rid);
zCiName = zDPName;
if( zCiName==0 ) zCiName = zUuid;
blob_append_sql(&sql, " AND event.objid IN ok");
nd = 0;
if( d_rid ){
| > < > > > | | < | | | | | | | | < < < < | 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 |
if( p_rid && d_rid ){
if( p_rid!=d_rid ) p_rid = d_rid;
if( !haveParameterN ) nEntry = 10;
}
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
);
add_extra_rids("ok", P("x"));
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d",
p_rid ? p_rid : d_rid);
zCiName = zDPName;
if( zCiName==0 ) zCiName = zUuid;
blob_append_sql(&sql, " AND event.objid IN ok");
nd = 0;
if( d_rid ){
double rStopTime = 9e99;
zFwdTo = P("ft");
if( zFwdTo ){
double rStartDate = db_double(0.0,
"SELECT mtime FROM event WHERE objid=%d", d_rid);
ridFwdTo = first_checkin_with_tag_after_date(zFwdTo, rStartDate);
if( ridFwdTo==0 ){
ridFwdTo = name_to_typed_rid(zBackTo,"ci");
}
if( ridFwdTo ){
if( !haveParameterN ) nEntry = 0;
rStopTime = db_double(9e99,
"SELECT mtime FROM event WHERE objid=%d", ridFwdTo);
}
}
if( rStopTime<9e99 ){
rStopTime += 5.8e-6; /* Round up by 1/2 second */
}
db_multi_exec(
"WITH RECURSIVE dx(rid,mtime) AS (\n"
" SELECT %d, 0\n"
" UNION\n"
" SELECT plink.cid, plink.mtime FROM dx, plink\n"
" WHERE plink.pid=dx.rid\n"
" AND plink.mtime<=%.*g\n"
" ORDER BY 2\n"
")\n"
"INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
d_rid, rStopTime<8e99 ? 17 : 2, rStopTime, nEntry<=0 ? -1 : nEntry+1
);
nd = db_int(0, "SELECT count(*)-1 FROM ok");
if( nd>=0 ) db_multi_exec("%s", blob_sql_text(&sql));
if( nd>0 || p_rid==0 ){
blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
}
if( useDividers && !selectedRid ) selectedRid = d_rid;
db_multi_exec("DELETE FROM ok");
|
| ︙ | ︙ | |||
2481 2482 2483 2484 2485 2486 2487 |
blob_zero(&cond);
tmFlags |= TIMELINE_FILLGAPS;
if( zChng && *zChng ){
addFileGlobExclusion(zChng, &cond);
tmFlags |= TIMELINE_XMERGE;
}
if( zUses ){
| | | | | | > > | < | < | < | > | > > < | < < > | > | > > < | > | > > | > > > > | | | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < > | | > | > > > > | | < | > | > > | > > > > > > > > > > | < > | > | > > < | < > | > | > > < | > | > > | > > > | 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 |
blob_zero(&cond);
tmFlags |= TIMELINE_FILLGAPS;
if( zChng && *zChng ){
addFileGlobExclusion(zChng, &cond);
tmFlags |= TIMELINE_XMERGE;
}
if( zUses ){
blob_append_sql(&cond, " AND event.objid IN usesfile\n");
}
if( renameOnly ){
blob_append_sql(&cond, " AND event.objid IN rnfile\n");
}
if( forkOnly ){
blob_append_sql(&cond, " AND event.objid IN rnfork\n");
}
if( cpOnly && showCherrypicks ){
db_multi_exec(
"CREATE TEMP TABLE IF NOT EXISTS cpnodes(rid INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO cpnodes SELECT childid FROM cherrypick;"
"INSERT OR IGNORE INTO cpnodes SELECT parentid FROM cherrypick;"
);
blob_append_sql(&cond, " AND event.objid IN cpnodes\n");
}
if( bisectLocal || zBisect!=0 ){
blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog)\n");
}
if( zYearMonth ){
char *zNext;
int bZulu = 0;
const char *zTZMod;
zYearMonth = timeline_expand_datetime(zYearMonth, &bZulu);
zYearMonth = mprintf("%.7s", zYearMonth);
if( db_int(0,"SELECT julianday('%q-01') IS NULL", zYearMonth) ){
zYearMonth = db_text(0, "SELECT strftime('%%Y-%%m','now');");
}
zTZMod = (bZulu==0 && fossil_ui_localtime()) ? "utc" : "+00:00";
if( db_int(0,
"SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
" WHERE blob.rid=event.objid"
" AND mtime>=julianday('%q-01',%Q)%s)",
zYearMonth, zTZMod, blob_sql_text(&cond))
){
zNext = db_text(0, "SELECT strftime('%%Y%%m%q','%q-01','+1 month');",
&"Z"[!bZulu], zYearMonth);
zNewerButton = fossil_strdup(url_render(&url, "ym", zNext, 0, 0));
zNewerButtonLabel = "Following month";
fossil_free(zNext);
}
if( db_int(0,
"SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
" WHERE blob.rid=event.objid"
" AND mtime<julianday('%q-01',%Q)%s)",
zYearMonth, zTZMod, blob_sql_text(&cond))
){
zNext = db_text(0, "SELECT strftime('%%Y%%m%q','%q-01','-1 month');",
&"Z"[!bZulu], zYearMonth);
zOlderButton = fossil_strdup(url_render(&url, "ym", zNext, 0, 0));
zOlderButtonLabel = "Previous month";
fossil_free(zNext);
}
blob_append_sql(&cond,
" AND event.mtime>=julianday('%q-01',%Q)"
" AND event.mtime<julianday('%q-01',%Q,'+1 month')\n",
zYearMonth, zTZMod, zYearMonth, zTZMod);
nEntry = -1;
/* Adjust the zYearMonth for the title */
zYearMonth = mprintf("%z-01%s", zYearMonth, &"Z"[!bZulu]);
}
else if( zYearWeek ){
char *z, *zNext;
int bZulu = 0;
const char *zTZMod;
zYearWeek = timeline_expand_datetime(zYearWeek, &bZulu);
z = db_text(0, "SELECT strftime('%%Y-%%W',%Q)", zYearWeek);
if( z && z[0] ){
zYearWeekStart = db_text(0, "SELECT date(%Q,'-6 days','weekday 1')",
zYearWeek);
zYearWeek = z;
}else{
if( strlen(zYearWeek)==7 ){
zYearWeekStart = db_text(0,
"SELECT date('%.4q-01-01','%+d days','weekday 1')",
zYearWeek, atoi(zYearWeek+5)*7-6);
}else{
zYearWeekStart = 0;
}
if( zYearWeekStart==0 || zYearWeekStart[0]==0 ){
zYearWeekStart = db_text(0,
"SELECT date('now','-6 days','weekday 1');");
zYearWeek = db_text(0,
"SELECT strftime('%%Y-%%W','now','-6 days','weekday 1')");
}
}
zTZMod = (bZulu==0 && fossil_ui_localtime()) ? "utc" : "+00:00";
if( db_int(0,
"SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
" WHERE blob.rid=event.objid"
" AND mtime>=julianday(%Q,%Q)%s)",
zYearWeekStart, zTZMod, blob_sql_text(&cond))
){
zNext = db_text(0, "SELECT strftime('%%Y%%W%q',%Q,'+7 day');",
&"Z"[!bZulu], zYearWeekStart);
zNewerButton = fossil_strdup(url_render(&url, "yw", zNext, 0, 0));
zNewerButtonLabel = "Following week";
fossil_free(zNext);
}
if( db_int(0,
"SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
" WHERE blob.rid=event.objid"
" AND mtime<julianday(%Q,%Q)%s)",
zYearWeekStart, zTZMod, blob_sql_text(&cond))
){
zNext = db_text(0, "SELECT strftime('%%Y%%W%q',%Q,'-7 days');",
&"Z"[!bZulu], zYearWeekStart);
zOlderButton = fossil_strdup(url_render(&url, "yw", zNext, 0, 0));
zOlderButtonLabel = "Previous week";
fossil_free(zNext);
}
blob_append_sql(&cond,
" AND event.mtime>=julianday(%Q,%Q)"
" AND event.mtime<julianday(%Q,%Q,'+7 days')\n",
zYearWeekStart, zTZMod, zYearWeekStart, zTZMod);
nEntry = -1;
if( fossil_ui_localtime() && bZulu ){
zYearWeekStart = mprintf("%zZ", zYearWeekStart);
}
}
else if( zDay && timeline_is_datespan(zDay) ){
char *zNext;
char *zStart, *zEnd;
int nDay;
int bZulu = 0;
const char *zTZMod;
zEnd = db_text(0, "SELECT date(%Q)",
timeline_expand_datetime(zDay+9, &bZulu));
zStart = db_text(0, "SELECT date('%.4q-%.2q-%.2q')",
zDay, zDay+4, zDay+6);
nDay = db_int(0, "SELECT julianday(%Q)-julianday(%Q)", zEnd, zStart);
if( nDay==0 ){
zDay = &zDay[9];
goto single_ymd;
}
if( nDay<0 ){
char *zTemp = zEnd;
zEnd = zStart;
zStart = zTemp;
nDay = 1 - nDay;
}else{
nDay += 1;
}
zTZMod = (bZulu==0 && fossil_ui_localtime()) ? "utc" : "+00:00";
if( nDay>0 && db_int(0,
"SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
" WHERE blob.rid=event.objid"
" AND mtime>=julianday(%Q,'1 day',%Q)%s)",
zEnd, zTZMod, blob_sql_text(&cond))
){
zNext = db_text(0,
"SELECT strftime('%%Y%%m%%d-',%Q,'%d days')||"
"strftime('%%Y%%m%%d%q',%Q,'%d day');",
zStart, nDay, &"Z"[!bZulu], zEnd, nDay);
zNewerButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
zNewerButtonLabel = mprintf("Following %d days", nDay);
fossil_free(zNext);
}
if( nDay>1 && db_int(0,
"SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
" WHERE blob.rid=event.objid"
" AND mtime<julianday(%Q,'-1 day',%Q)%s)",
zStart, zTZMod, blob_sql_text(&cond))
){
zNext = db_text(0,
"SELECT strftime('%%Y%%m%%d-',%Q,'%d days')||"
"strftime('%%Y%%m%%d%q',%Q,'%d day');",
zStart, -nDay, &"Z"[!bZulu], zEnd, -nDay);
zOlderButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
zOlderButtonLabel = mprintf("Previous %d days", nDay);
fossil_free(zNext);
}
blob_append_sql(&cond,
" AND event.mtime>=julianday(%Q,%Q)"
" AND event.mtime<julianday(%Q,%Q,'+1 day')\n",
zStart, zTZMod, zEnd, zTZMod);
nEntry = -1;
if( fossil_ui_localtime() && bZulu ){
zDay = mprintf("%d days between %zZ and %zZ", nDay, zStart, zEnd);
}else{
zDay = mprintf("%d days between %z and %z", nDay, zStart, zEnd);
}
}
else if( zDay ){
char *zNext;
int bZulu = 0;
const char *zTZMod;
single_ymd:
bZulu = 0;
zDay = timeline_expand_datetime(zDay, &bZulu);
zDay = db_text(0, "SELECT date(%Q)", zDay);
if( zDay==0 || zDay[0]==0 ){
zDay = db_text(0, "SELECT date('now')");
}
zTZMod = (bZulu==0 && fossil_ui_localtime()) ? "utc" : "+00:00";
if( db_int(0,
"SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
" WHERE blob.rid=event.objid"
" AND mtime>=julianday(%Q,'+1 day',%Q)%s)",
zDay, zTZMod, blob_sql_text(&cond))
){
zNext = db_text(0,"SELECT strftime('%%Y%%m%%d%q',%Q,'+1 day');",
&"Z"[!bZulu], zDay);
zNewerButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
zNewerButtonLabel = "Following day";
fossil_free(zNext);
}
if( db_int(0,
"SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
" WHERE blob.rid=event.objid"
" AND mtime<julianday(%Q,'-1 day',%Q)%s)",
zDay, zTZMod, blob_sql_text(&cond))
){
zNext = db_text(0,"SELECT strftime('%%Y%%m%%d%q',%Q,'-1 day');",
&"Z"[!bZulu], zDay);
zOlderButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
zOlderButtonLabel = "Previous day";
fossil_free(zNext);
}
blob_append_sql(&cond,
" AND event.mtime>=julianday(%Q,%Q)"
" AND event.mtime<julianday(%Q,%Q,'+1 day')\n",
zDay, zTZMod, zDay, zTZMod);
nEntry = -1;
if( fossil_ui_localtime() && bZulu ){
zDay = mprintf("%zZ", zDay); /* Add Z suffix to day for the title */
}
}
else if( zNDays ){
nDays = atoi(zNDays);
if( nDays<1 ) nDays = 1;
blob_append_sql(&cond, " AND event.mtime>=julianday('now','-%d days') ",
nDays);
nEntry = -1;
|
| ︙ | ︙ | |||
2661 2662 2663 2664 2665 2666 2667 |
blob_append_sql(&cond, " AND %Q=strftime('%%Y',event.mtime) ",
zYear);
nEntry = -1;
}
if( zTagSql ){
db_multi_exec(
"CREATE TEMP TABLE selected_nodes(rid INTEGER PRIMARY KEY);"
| | | > | < < < < < < < < < < < < | < < < < | | | | | | | | | | | | | | | > | > | | 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 |
blob_append_sql(&cond, " AND %Q=strftime('%%Y',event.mtime) ",
zYear);
nEntry = -1;
}
if( zTagSql ){
db_multi_exec(
"CREATE TEMP TABLE selected_nodes(rid INTEGER PRIMARY KEY);"
"INSERT OR IGNORE INTO selected_nodes\n"
" SELECT tagxref.rid FROM tagxref NATURAL JOIN tag\n"
" WHERE tagtype>0\n"
" AND %s", zTagSql/*safe-for-%s*/
);
if( zMark ){
/* If the t=release option is used with m=UUID, then also
** include the UUID check-in in the display list */
int ridMark = name_to_rid(zMark);
db_multi_exec(
"INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridMark);
}
add_extra_rids("selected_nodes",P("x"));
if( related==0 ){
blob_append_sql(&cond, " AND blob.rid IN selected_nodes");
}else{
db_multi_exec(
"CREATE TEMP TABLE related_nodes(rid INTEGER PRIMARY KEY);"
"INSERT INTO related_nodes SELECT rid FROM selected_nodes;"
);
blob_append_sql(&cond, " AND blob.rid IN related_nodes");
/* The next two blob_appendf() calls add SQL that causes check-ins that
** are not part of the branch which are parents or children of the
** branch to be included in the report. These related check-ins are
** useful in helping to visualize what has happened on a quiescent
** branch that is infrequently merged with a much more activate branch.
*/
db_multi_exec(
"INSERT OR IGNORE INTO related_nodes\n"
" SELECT pid FROM selected_nodes CROSS JOIN plink\n"
" WHERE selected_nodes.rid=plink.cid;"
);
if( related==1 ){
db_multi_exec(
"INSERT OR IGNORE INTO related_nodes\n"
" SELECT cid FROM selected_nodes CROSS JOIN plink\n"
" WHERE selected_nodes.rid=plink.pid;"
);
if( showCherrypicks ){
db_multi_exec(
"INSERT OR IGNORE INTO related_nodes\n"
" SELECT childid FROM selected_nodes CROSS JOIN cherrypick\n"
" WHERE selected_nodes.rid=cherrypick.parentid;"
);
}
}
if( showCherrypicks ){
db_multi_exec(
"INSERT OR IGNORE INTO related_nodes\n"
" SELECT parentid FROM selected_nodes CROSS JOIN cherrypick\n"
" WHERE selected_nodes.rid=cherrypick.childid;"
);
}
if( (tmFlags & TIMELINE_UNHIDE)==0 ){
db_multi_exec(
"DELETE FROM related_nodes\n"
" WHERE rid IN (SELECT related_nodes.rid\n"
" FROM related_nodes, tagxref\n"
" WHERE tagid=%d AND tagtype>0\n"
" AND tagxref.rid=related_nodes.rid)",
TAG_HIDDEN
);
}
}
}
if( (zType[0]=='w' && !g.perm.RdWiki)
|| (zType[0]=='t' && !g.perm.RdTkt)
|
| ︙ | ︙ | |||
2827 2828 2829 2830 2831 2832 2833 |
rBefore = symbolic_name_to_mtime(zBefore, &zBefore);
rAfter = symbolic_name_to_mtime(zAfter, &zAfter);
rCirca = symbolic_name_to_mtime(zCirca, &zCirca);
blob_append_sql(&sql, "%s", blob_sql_text(&cond));
if( rAfter>0.0 ){
if( rBefore>0.0 ){
blob_append_sql(&sql,
| | | | | < < < | | | 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 |
rBefore = symbolic_name_to_mtime(zBefore, &zBefore);
rAfter = symbolic_name_to_mtime(zAfter, &zAfter);
rCirca = symbolic_name_to_mtime(zCirca, &zCirca);
blob_append_sql(&sql, "%s", blob_sql_text(&cond));
if( rAfter>0.0 ){
if( rBefore>0.0 ){
blob_append_sql(&sql,
" AND event.mtime>=%.17g AND event.mtime<=%.17g\n"
" ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
nEntry = -1;
}else{
blob_append_sql(&sql,
" AND event.mtime>=%.17g\n ORDER BY event.mtime ASC",
rAfter-ONE_SECOND);
}
zCirca = 0;
url_add_parameter(&url, "c", 0);
}else if( rBefore>0.0 ){
blob_append_sql(&sql,
" AND event.mtime<=%.17g\n ORDER BY event.mtime DESC",
rBefore+ONE_SECOND);
zCirca = 0;
url_add_parameter(&url, "c", 0);
}else if( rCirca>0.0 ){
Blob sql2;
blob_init(&sql2, blob_sql_text(&sql), -1);
blob_append_sql(&sql2,
" AND event.mtime>=%f\n ORDER BY event.mtime ASC", rCirca);
if( nEntry>0 ){
blob_append_sql(&sql2," LIMIT %d", (nEntry+1)/2);
}
db_multi_exec("%s", blob_sql_text(&sql2));
if( nEntry>0 ){
nEntry -= db_int(0,"select count(*) from timeline");
if( nEntry<=0 ) nEntry = 1;
}
blob_reset(&sql2);
blob_append_sql(&sql,
" AND event.mtime<=%f\n ORDER BY event.mtime DESC",
rCirca
);
if( zMark==0 ) zMark = zCirca;
}else{
blob_append_sql(&sql, " ORDER BY event.mtime DESC");
}
if( nEntry>0 ) blob_append_sql(&sql, " LIMIT %d", nEntry);
db_multi_exec("%s", blob_sql_text(&sql));
n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
zPlural = n==1 ? "" : "s";
if( zYearMonth ){
blob_appendf(&desc, "%d %s%s for the month beginning %h",
n, zEType, zPlural, zYearMonth);
}else if( zYearWeek ){
blob_appendf(&desc, "%d %s%s for week %h beginning on %h",
n, zEType, zPlural, zYearWeek, zYearWeekStart);
}else if( zDay ){
blob_appendf(&desc, "%d %s%s occurring on %h", n, zEType, zPlural, zDay);
}else if( zNDays ){
|
| ︙ | ︙ | |||
3008 3009 3010 3011 3012 3013 3014 |
if( advancedMenu ){
style_submenu_entry("t", "Tag Filter:", -8, 0);
style_submenu_multichoice("ms", count(azMatchStyles)/2,azMatchStyles,0);
}
}
blob_zero(&cond);
}
| | > | > | 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 |
if( advancedMenu ){
style_submenu_entry("t", "Tag Filter:", -8, 0);
style_submenu_multichoice("ms", count(azMatchStyles)/2,azMatchStyles,0);
}
}
blob_zero(&cond);
}
if( showSql ){
db_append_dml_to_blob(0);
@ <pre>%h(blob_str(&allSql))</pre>
blob_reset(&allSql);
}
if( search_restrict(SRCH_CKIN)!=0 ){
style_submenu_element("Search", "%R/search?y=c");
}
if( advancedMenu ){
style_submenu_element("Basic", "%s",
url_render(&url, "advm", "0", "udc", "1"));
|
| ︙ | ︙ | |||
3067 3068 3069 3070 3071 3072 3073 |
}
if( zNewerButton ){
@ %z(chref("button","%s",zNewerButton))%h(zNewerButtonLabel)\
@ ↑</a>
}
cgi_check_for_malice();
| > > > > > > > > > > > > > > | | > > > > | 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 |
}
if( zNewerButton ){
@ %z(chref("button","%s",zNewerButton))%h(zNewerButtonLabel)\
@ ↑</a>
}
cgi_check_for_malice();
{
Matcher *pLeftBranch;
const char *zPattern = P("sl");
if( zPattern!=0 ){
MatchStyle ms;
if( zMatchStyle!=0 ){
ms = matchStyle;
}else{
ms = strpbrk(zPattern,"*[?")!=0 ? MS_GLOB : MS_BRLIST;
}
pLeftBranch = match_create(ms,zPattern);
}else{
pLeftBranch = match_create(matchStyle, zBrName?zBrName:zTagName);
}
www_print_timeline(&q, tmFlags, zThisUser, zThisTag, pLeftBranch,
selectedRid, secondaryRid, 0);
match_free(pLeftBranch);
}
db_finalize(&q);
if( zOlderButton ){
@ %z(chref("button","%s",zOlderButton))%h(zOlderButtonLabel)\
@ ↓</a>
}
document_emit_js(/*handles pikchrs rendered above*/);
blob_reset(&sql);
blob_reset(&desc);
style_finish_page();
}
/*
** Translate a timeline entry into the printable format by
** converting every %-substitutions as follows:
**
|
| ︙ | ︙ | |||
3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 |
void thisdayinhistory_page(void){
static int aYearsAgo[] = { 1, 2, 3, 4, 5, 10, 15, 20, 30, 40, 50, 75, 100 };
const char *zToday;
char *zStartOfProject;
int i;
Stmt q;
char *z;
login_check_credentials();
if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum) ){
login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
return;
}
style_set_current_feature("timeline");
style_header("Today In History");
zToday = (char*)P("today");
if( zToday ){
| > | | 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 |
void thisdayinhistory_page(void){
static int aYearsAgo[] = { 1, 2, 3, 4, 5, 10, 15, 20, 30, 40, 50, 75, 100 };
const char *zToday;
char *zStartOfProject;
int i;
Stmt q;
char *z;
int bZulu = 0;
login_check_credentials();
if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum) ){
login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
return;
}
style_set_current_feature("timeline");
style_header("Today In History");
zToday = (char*)P("today");
if( zToday ){
zToday = timeline_expand_datetime(zToday, &bZulu);
if( !fossil_isdate(zToday) ) zToday = 0;
}
if( zToday==0 ){
zToday = db_text(0, "SELECT date('now',toLocal())");
}
@ <h1>This Day In History For %h(zToday)</h1>
z = db_text(0, "SELECT date(%Q,'-1 day')", zToday);
|
| ︙ | ︙ |
Changes to src/update.c.
| ︙ | ︙ | |||
512 513 514 515 516 517 518 |
zNext = db_changes() ? file_dirname(zDir) : 0;
fossil_free(zDir);
zDir = zNext;
}
}
}
}else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
| < < < < > > > | 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 |
zNext = db_changes() ? file_dirname(zDir) : 0;
fossil_free(zDir);
zDir = zNext;
}
}
}
}else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
if( nameChng ){
fossil_print("MERGE %s -> %s\n", zName, zNewName);
}else{
fossil_print("MERGE %s\n", zName);
}
if( islinkv || islinkt ){
fossil_print("***** Cannot merge symlink %s\n", zNewName);
zOp = "CONFLICT";
nConflict++;
}else{
/* Merge the changes in the current tree into the target version */
Blob r, t, v;
int rc;
unsigned mergeFlags = dryRunFlag ? MERGE_DRYRUN : 0;
if(keepMergeFlag!=0) mergeFlags |= MERGE_KEEP_FILES;
if( !dryRunFlag && !internalUpdate ) undo_save(zName);
content_get(ridt, &t);
content_get(ridv, &v);
rc = merge_3way(&v, zFullPath, &t, &r, mergeFlags);
if( rc>=0 ){
|
| ︙ | ︙ | |||
569 570 571 572 573 574 575 |
}
fossil_print("\n");
nConflict++;
zOp = "ERROR";
zErrMsg = "cannot merge binary file";
nc = 1;
}
| < < | | | > > | 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 |
}
fossil_print("\n");
nConflict++;
zOp = "ERROR";
zErrMsg = "cannot merge binary file";
nc = 1;
}
blob_reset(&v);
blob_reset(&t);
blob_reset(&r);
}
if( nameChng && !dryRunFlag ) file_delete(zFullPath);
}else{
nUpdate--;
if( chnged ){
if( verboseFlag ) fossil_print("EDITED %s\n", zName);
}else{
db_bind_int(&mtimeXfer, ":idv", idv);
db_bind_int(&mtimeXfer, ":idt", idt);
|
| ︙ | ︙ | |||
852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 |
**
** Revert all files if no file name is provided.
**
** If a file is reverted accidentally, it can be restored using
** the "fossil undo" command.
**
** Options:
** -r|--revision VERSION Revert given FILE(s) back to given
** VERSION
**
** See also: [[redo]], [[undo]], [[checkout]], [[update]]
*/
void revert_cmd(void){
Manifest *pCoManifest; /* Manifest of current check-out */
Manifest *pRvManifest; /* Manifest of selected revert version */
ManifestFile *pCoFile; /* File within current check-out manifest */
ManifestFile *pRvFile; /* File within revert version manifest */
const char *zFile; /* Filename relative to check-out root */
const char *zRevision; /* Selected revert version, NULL if current */
Blob record = BLOB_INITIALIZER; /* Contents of each reverted file */
int i;
Stmt q;
int revertAll = 0;
int revisionOptNotSupported = 0;
undo_capture_command_line();
zRevision = find_option("revision", "r", 1);
verify_all_options();
if( g.argc<2 ){
usage("?OPTIONS? [FILE] ...");
}
if( zRevision && g.argc<3 ){
fossil_fatal("directories or the entire tree can only be reverted"
" back to current version");
}
db_must_be_within_tree();
/* Get manifests of revert version and (if different) current check-out. */
pRvManifest = historical_manifest(zRevision);
pCoManifest = zRevision ? historical_manifest(0) : 0;
db_begin_transaction();
| > > > > | > > > | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 |
**
** Revert all files if no file name is provided.
**
** If a file is reverted accidentally, it can be restored using
** the "fossil undo" command.
**
** Options:
** --noundo Do not record changes in the undo/redo log.
** -r|--revision VERSION Revert given FILE(s) back to given
** VERSION
**
** See also: [[redo]], [[undo]], [[checkout]], [[update]]
*/
void revert_cmd(void){
Manifest *pCoManifest; /* Manifest of current check-out */
Manifest *pRvManifest; /* Manifest of selected revert version */
ManifestFile *pCoFile; /* File within current check-out manifest */
ManifestFile *pRvFile; /* File within revert version manifest */
const char *zFile; /* Filename relative to check-out root */
const char *zRevision; /* Selected revert version, NULL if current */
Blob record = BLOB_INITIALIZER; /* Contents of each reverted file */
int useUndo = 1; /* True to record changes in UNDO */
int i;
Stmt q;
int revertAll = 0;
int revisionOptNotSupported = 0;
undo_capture_command_line();
zRevision = find_option("revision", "r", 1);
useUndo = find_option("noundo", 0, 0)==0;
verify_all_options();
if( g.argc<2 ){
usage("?OPTIONS? [FILE] ...");
}
if( zRevision && g.argc<3 ){
fossil_fatal("directories or the entire tree can only be reverted"
" back to current version");
}
db_must_be_within_tree();
/* Get manifests of revert version and (if different) current check-out. */
pRvManifest = historical_manifest(zRevision);
pCoManifest = zRevision ? historical_manifest(0) : 0;
db_begin_transaction();
if( useUndo ){
undo_begin();
}else{
undo_reset();
}
db_multi_exec("CREATE TEMP TABLE torevert(name UNIQUE);");
if( g.argc>2 ){
for(i=2; i<g.argc; i++){
Blob fname;
zFile = mprintf("%/", g.argv[i]);
blob_zero(&fname);
|
| ︙ | ︙ | |||
985 986 987 988 989 990 991 |
zFull = mprintf("%/%/", g.zLocalRoot, zFile);
pRvFile = pRvManifest? manifest_file_find(pRvManifest, zFile) : 0;
if( !pRvFile ){
if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q OR origname=%Q",
zFile, zFile)==0 ){
fossil_print("UNMANAGE %s\n", zFile);
}else{
| | | 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 |
zFull = mprintf("%/%/", g.zLocalRoot, zFile);
pRvFile = pRvManifest? manifest_file_find(pRvManifest, zFile) : 0;
if( !pRvFile ){
if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q OR origname=%Q",
zFile, zFile)==0 ){
fossil_print("UNMANAGE %s\n", zFile);
}else{
if( useUndo ) undo_save(zFile);
file_delete(zFull);
fossil_print("DELETE %s\n", zFile);
}
db_multi_exec(
"UPDATE OR REPLACE vfile"
" SET pathname=origname, origname=NULL"
" WHERE pathname=%Q AND origname!=pathname;"
|
| ︙ | ︙ | |||
1012 1013 1014 1015 1016 1017 1018 |
rvChnged = manifest_file_mperm(pRvFile)!=rvPerm
|| fossil_strcmp(pRvFile->zUuid, pCoFile->zUuid)!=0;
}
/* Get contents of reverted-to file. */
content_get(fast_uuid_to_rid(pRvFile->zUuid), &record);
| | | 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 |
rvChnged = manifest_file_mperm(pRvFile)!=rvPerm
|| fossil_strcmp(pRvFile->zUuid, pCoFile->zUuid)!=0;
}
/* Get contents of reverted-to file. */
content_get(fast_uuid_to_rid(pRvFile->zUuid), &record);
if( useUndo ) undo_save(zFile);
if( file_size(zFull, RepoFILE)>=0
&& (rvPerm==PERM_LNK || file_islink(0))
){
file_delete(zFull);
}
if( rvPerm==PERM_LNK ){
symlink_create(blob_str(&record), zFull);
|
| ︙ | ︙ | |||
1038 1039 1040 1041 1042 1043 1044 |
mtime, rvChnged, rvPerm==PERM_EXE, rvPerm==PERM_LNK, zFile, zFile
);
}
blob_reset(&record);
free(zFull);
}
db_finalize(&q);
| | | 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 |
mtime, rvChnged, rvPerm==PERM_EXE, rvPerm==PERM_LNK, zFile, zFile
);
}
blob_reset(&record);
free(zFull);
}
db_finalize(&q);
if( useUndo) undo_finish();
db_end_transaction(0);
/* Deallocate parsed manifest structures. */
manifest_destroy(pRvManifest);
manifest_destroy(pCoManifest);
}
|
Changes to src/util.c.
| ︙ | ︙ | |||
941 942 943 944 945 946 947 948 949 950 951 952 953 954 |
zBrowser = "echo";
for(i=0; i<count(azBrowserProg); i++){
if( binaryOnPath(azBrowserProg[i]) ){
zBrowser = azBrowserProg[i];
break;
}
}
}
#endif
return zBrowser;
}
/*
** On non-Windows systems, calls nice(2) with the given level. Errors
| > | 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 |
zBrowser = "echo";
for(i=0; i<count(azBrowserProg); i++){
if( binaryOnPath(azBrowserProg[i]) ){
zBrowser = azBrowserProg[i];
break;
}
}
zBrowser = mprintf("%s 2>/dev/null", zBrowser);
}
#endif
return zBrowser;
}
/*
** On non-Windows systems, calls nice(2) with the given level. Errors
|
| ︙ | ︙ |
Changes to src/winhttp.c.
| ︙ | ︙ | |||
411 412 413 414 415 416 417 418 419 |
}
/*
** The repository name is only needed if there was no open check-out. This
** is designed to allow the open check-out for the interactive user to work
** with the local Fossil server started via the "ui" command.
*/
zIp = SocketAddr_toString(&p->addr);
if( (p->flags & HTTP_SERVER_HAD_CHECKOUT)==0 ){
| > > > > > > > > > | < < < < < < < < < < < | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
}
/*
** The repository name is only needed if there was no open check-out. This
** is designed to allow the open check-out for the interactive user to work
** with the local Fossil server started via the "ui" command.
*/
aux = fossil_fopen(zCmdFName, "wb");
if( aux==0 ) goto end_request;
fprintf(aux, "%s--in %s\n", get_utf8_bom(0), zRequestFName);
zIp = SocketAddr_toString(&p->addr);
fprintf(aux, "--out %s\n--ipaddr %s\n", zReplyFName, zIp);
fossil_free(zIp);
fprintf(aux, "--as %s\n", g.zCmdName);
if( g.zErrlog && g.zErrlog[0] ){
fprintf(aux,"--errorlog %s\n", g.zErrlog);
}
if( (p->flags & HTTP_SERVER_HAD_CHECKOUT)==0 ){
fprintf(aux,"%s",g.zRepositoryName);
}
sqlite3_snprintf(sizeof(zCmd), zCmd,
"\"%s\" http -args \"%s\"%s%s",
g.nameOfExe, zCmdFName,
g.httpUseSSL ? "" : " --nossl", p->zOptions
);
in = fossil_fopen(zReplyFName, "w+b");
|
| ︙ | ︙ |
Changes to src/xfer.c.
| ︙ | ︙ | |||
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 |
pXfer->resync = db_column_int(&q, 1)-1;
}
}
db_finalize(&q);
if( cnt==0 ) pXfer->resync = 0;
return cnt;
}
/*
** Send an igot message for every artifact.
*/
static void send_all(Xfer *pXfer){
Stmt q;
db_prepare(&q,
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 |
pXfer->resync = db_column_int(&q, 1)-1;
}
}
db_finalize(&q);
if( cnt==0 ) pXfer->resync = 0;
return cnt;
}
/*
** Send an igot message for every cluster artifact that is not a phantom,
** is not shunned, is not private, and that is not in the UNCLUSTERED table.
** Return the number of cards sent.
*/
static int send_all_clusters(Xfer *pXfer){
Stmt q;
int cnt = 0;
const char *zExtra;
if( db_table_exists("temp","onremote") ){
zExtra = " AND NOT EXISTS(SELECT 1 FROM onremote WHERE rid=blob.rid)";
}else{
zExtra = "";
}
db_prepare(&q,
"SELECT uuid"
" FROM tagxref JOIN blob ON tagxref.rid=blob.rid AND tagxref.tagid=%d"
" WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
" AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
" AND NOT EXISTS(SELECT 1 FROM unclustered WHERE rid=blob.rid)"
" AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)%s",
TAG_CLUSTER, zExtra /*safe-for-%s*/
);
while( db_step(&q)==SQLITE_ROW ){
if( cnt==0 ) blob_appendf(pXfer->pOut, "# sending-clusters\n");
blob_appendf(pXfer->pOut, "igot %s\n", db_column_text(&q, 0));
cnt++;
}
db_finalize(&q);
if( cnt ) blob_appendf(pXfer->pOut, "# end-of-clusters\n");
return cnt;
}
/*
** Send an igot message for every artifact.
*/
static void send_all(Xfer *pXfer){
Stmt q;
db_prepare(&q,
|
| ︙ | ︙ | |||
1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 |
/* pragma req-links
**
** The client sends this message to the server to ask the server
** to tell it about alternative repositories in the reply.
*/
if( blob_eq(&xfer.aToken[1], "req-links") ){
bSendLinks = 1;
}
}else
/* Unknown message
*/
{
| > > > > > > > > > | 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 |
/* pragma req-links
**
** The client sends this message to the server to ask the server
** to tell it about alternative repositories in the reply.
*/
if( blob_eq(&xfer.aToken[1], "req-links") ){
bSendLinks = 1;
}else
/* pragma req-clusters
**
** This pragma requests that the server send igot cards for every
** cluster artifact that it knows about.
*/
if( blob_eq(&xfer.aToken[1], "req-clusters") ){
send_all_clusters(&xfer);
}
}else
/* Unknown message
*/
{
|
| ︙ | ︙ | |||
1979 1980 1981 1982 1983 1984 1985 |
){
int go = 1; /* Loop until zero */
int nCardSent = 0; /* Number of cards sent */
int nCardRcvd = 0; /* Number of cards received */
int nCycle = 0; /* Number of round trips to the server */
int size; /* Size of a config value or uvfile */
int origConfigRcvMask; /* Original value of configRcvMask */
| | | 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 |
){
int go = 1; /* Loop until zero */
int nCardSent = 0; /* Number of cards sent */
int nCardRcvd = 0; /* Number of cards received */
int nCycle = 0; /* Number of round trips to the server */
int size; /* Size of a config value or uvfile */
int origConfigRcvMask; /* Original value of configRcvMask */
int nFileRecv = 0; /* Number of files received */
int mxPhantomReq = 200; /* Max number of phantoms to request per comm */
const char *zCookie; /* Server cookie */
i64 nUncSent, nUncRcvd; /* Bytes sent and received (before compression) */
i64 nSent, nRcvd; /* Bytes sent and received (after compression) */
int cloneSeqno = 1; /* Sequence number for clones */
Blob send; /* Text we are sending to the server */
Blob recv; /* Reply we got back from the server */
|
| ︙ | ︙ | |||
2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 | const char *zOpType = 0;/* Push, Pull, Sync, Clone */ double rSkew = 0.0; /* Maximum time skew */ int uvHashSent = 0; /* The "pragma uv-hash" message has been sent */ int uvDoPush = 0; /* Generate uvfile messages to send to server */ int uvPullOnly = 0; /* 1: pull-only. 2: pull-only warning issued */ int nUvGimmeSent = 0; /* Number of uvgimme cards sent on this cycle */ int nUvFileRcvd = 0; /* Number of uvfile cards received on this cycle */ sqlite3_int64 mtime; /* Modification time on a UV file */ int autopushFailed = 0; /* Autopush following commit failed if true */ const char *zCkinLock; /* Name of check-in to lock. NULL for none */ const char *zClientId; /* A unique identifier for this check-out */ unsigned int mHttpFlags;/* Flags for the http_exchange() subsystem */ const int bOutIsTty = fossil_isatty(fossil_fileno(stdout)); | > | 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 | const char *zOpType = 0;/* Push, Pull, Sync, Clone */ double rSkew = 0.0; /* Maximum time skew */ int uvHashSent = 0; /* The "pragma uv-hash" message has been sent */ int uvDoPush = 0; /* Generate uvfile messages to send to server */ int uvPullOnly = 0; /* 1: pull-only. 2: pull-only warning issued */ int nUvGimmeSent = 0; /* Number of uvgimme cards sent on this cycle */ int nUvFileRcvd = 0; /* Number of uvfile cards received on this cycle */ int nGimmeRcvd = 0; /* Number of gimme cards recevied on the prev cycle */ sqlite3_int64 mtime; /* Modification time on a UV file */ int autopushFailed = 0; /* Autopush following commit failed if true */ const char *zCkinLock; /* Name of check-in to lock. NULL for none */ const char *zClientId; /* A unique identifier for this check-out */ unsigned int mHttpFlags;/* Flags for the http_exchange() subsystem */ const int bOutIsTty = fossil_isatty(fossil_fileno(stdout)); |
| ︙ | ︙ | |||
2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 |
/* Client sends gimme cards for phantoms
*/
if( (syncFlags & SYNC_PULL)!=0
|| ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1)
){
request_phantoms(&xfer, mxPhantomReq);
}
if( syncFlags & SYNC_PUSH ){
send_unsent(&xfer);
nCardSent += send_unclustered(&xfer);
if( syncFlags & SYNC_PRIVATE ) send_private(&xfer);
}
/* Client sends configuration parameter requests. On a clone, delay sending
** this until the second cycle since the login card might fail on
** the first cycle.
*/
if( configRcvMask && ((syncFlags & SYNC_CLONE)==0 || nCycle>0) ){
| > > > > > > | 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 |
/* Client sends gimme cards for phantoms
*/
if( (syncFlags & SYNC_PULL)!=0
|| ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1)
){
request_phantoms(&xfer, mxPhantomReq);
if( xfer.nGimmeSent>0 && nCycle==2 && (syncFlags & SYNC_PULL)!=0 ){
blob_appendf(&send, "pragma req-clusters\n");
}
}
if( syncFlags & SYNC_PUSH ){
send_unsent(&xfer);
nCardSent += send_unclustered(&xfer);
if( syncFlags & SYNC_PRIVATE ) send_private(&xfer);
if( nGimmeRcvd>0 && nCycle==2 ){
send_all_clusters(&xfer);
}
}
/* Client sends configuration parameter requests. On a clone, delay sending
** this until the second cycle since the login card might fail on
** the first cycle.
*/
if( configRcvMask && ((syncFlags & SYNC_CLONE)==0 || nCycle>0) ){
|
| ︙ | ︙ | |||
2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 |
if( syncFlags & SYNC_PUSH ){
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
nCardSent++;
}
go = 0;
nUvGimmeSent = 0;
nUvFileRcvd = 0;
nPriorArtifact = nArtifactRcvd;
/* Process the reply that came back from the server */
while( blob_line(&recv, &xfer.line) ){
if( blob_buffer(&xfer.line)[0]=='#' ){
const char *zLine = blob_buffer(&xfer.line);
if( memcmp(zLine, "# timestamp ", 12)==0 ){
| > | 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 |
if( syncFlags & SYNC_PUSH ){
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
nCardSent++;
}
go = 0;
nUvGimmeSent = 0;
nUvFileRcvd = 0;
nGimmeRcvd = 0;
nPriorArtifact = nArtifactRcvd;
/* Process the reply that came back from the server */
while( blob_line(&recv, &xfer.line) ){
if( blob_buffer(&xfer.line)[0]=='#' ){
const char *zLine = blob_buffer(&xfer.line);
if( memcmp(zLine, "# timestamp ", 12)==0 ){
|
| ︙ | ︙ | |||
2447 2448 2449 2450 2451 2452 2453 |
if( blob_eq(&xfer.aToken[0], "gimme")
&& xfer.nToken==2
&& blob_is_hname(&xfer.aToken[1])
){
remote_unk(&xfer.aToken[1]);
if( syncFlags & SYNC_PUSH ){
int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
| > | > > | 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 |
if( blob_eq(&xfer.aToken[0], "gimme")
&& xfer.nToken==2
&& blob_is_hname(&xfer.aToken[1])
){
remote_unk(&xfer.aToken[1]);
if( syncFlags & SYNC_PUSH ){
int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
if( rid ){
send_file(&xfer, rid, &xfer.aToken[1], 0);
nGimmeRcvd++;
}
}
}else
/* igot HASH ?PRIVATEFLAG?
**
** Server announces that it has a particular file. If this is
** not a file that we have and we are pulling, then create a
|
| ︙ | ︙ |
Changes to test/merge1.test.
| ︙ | ︙ | |||
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
333 - This is a test of the merging algohm - 3333
444 - If all goes well, we will be pleased - 4444
555 - we think it well and other stuff too - 5555
}
write_file_indented t23 {
<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<< (line 1)
111 - This is line ONE of the demo program - 1111
||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||| (line 1)
111 - This is line one of the demo program - 1111
======= MERGED IN content follows =============================== (line 1)
111 - This is line one OF the demo program - 1111
>>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
222 - The second line program line in code - 2222
333 - This is a test of the merging algohm - 3333
444 - If all goes well, we will be pleased - 4444
555 - we think it well and other stuff too - 5555
}
write_file_indented t32 {
<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<< (line 1)
111 - This is line one OF the demo program - 1111
||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||| (line 1)
111 - This is line one of the demo program - 1111
======= MERGED IN content follows =============================== (line 1)
111 - This is line ONE of the demo program - 1111
>>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
222 - The second line program line in code - 2222
333 - This is a test of the merging algohm - 3333
| > > > > | 73 74 75 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 |
333 - This is a test of the merging algohm - 3333
444 - If all goes well, we will be pleased - 4444
555 - we think it well and other stuff too - 5555
}
write_file_indented t23 {
<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<< (line 1)
111 - This is line ONE of the demo program - 1111
####### SUGGESTED CONFLICT RESOLUTION follows ###################
111 - This is line ONE OF the demo program - 1111
||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||| (line 1)
111 - This is line one of the demo program - 1111
======= MERGED IN content follows =============================== (line 1)
111 - This is line one OF the demo program - 1111
>>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
222 - The second line program line in code - 2222
333 - This is a test of the merging algohm - 3333
444 - If all goes well, we will be pleased - 4444
555 - we think it well and other stuff too - 5555
}
write_file_indented t32 {
<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<< (line 1)
111 - This is line one OF the demo program - 1111
####### SUGGESTED CONFLICT RESOLUTION follows ###################
111 - This is line ONE OF the demo program - 1111
||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||| (line 1)
111 - This is line one of the demo program - 1111
======= MERGED IN content follows =============================== (line 1)
111 - This is line ONE of the demo program - 1111
>>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
222 - The second line program line in code - 2222
333 - This is a test of the merging algohm - 3333
|
| ︙ | ︙ | |||
157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
222 - The second line program line in code - 2222
333 - This is a test of the merging algohm - 3333
444 - If all goes well, we will be pleased - 4444
555 - we think it well and other stuff too - 5555
}
write_file_indented t32 {
<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<< (line 1)
||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||| (line 1)
111 - This is line one of the demo program - 1111
======= MERGED IN content follows =============================== (line 1)
000 - Zero lines added to the beginning of - 0000
111 - This is line one of the demo program - 1111
>>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
222 - The second line program line in code - 2222
| > > > | 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
222 - The second line program line in code - 2222
333 - This is a test of the merging algohm - 3333
444 - If all goes well, we will be pleased - 4444
555 - we think it well and other stuff too - 5555
}
write_file_indented t32 {
<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<< (line 1)
####### SUGGESTED CONFLICT RESOLUTION follows ###################
000 - Zero lines added to the beginning of - 0000
111 - This is line one of the demo program - 1111
||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||| (line 1)
111 - This is line one of the demo program - 1111
======= MERGED IN content follows =============================== (line 1)
000 - Zero lines added to the beginning of - 0000
111 - This is line one of the demo program - 1111
>>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
222 - The second line program line in code - 2222
|
| ︙ | ︙ | |||
303 304 305 306 307 308 309 310 311 312 313 314 315 316 | efgh 2 ijkl 2 mnop 2 qrst uvwx yzAB 2 CDEF 2 GHIJ 2 ||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||| (line 2) efgh ijkl mnop qrst uvwx | > > > > > > > > > | 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | efgh 2 ijkl 2 mnop 2 qrst uvwx yzAB 2 CDEF 2 GHIJ 2 ####### SUGGESTED CONFLICT RESOLUTION follows ################### efgh 2 ijkl 2 mnop 3 qrst 3 uvwx 3 yzAB 3 CDEF 2 GHIJ 2 ||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||| (line 2) efgh ijkl mnop qrst uvwx |
| ︙ | ︙ | |||
370 371 372 373 374 375 376 377 378 379 380 381 382 383 | <<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<< (line 2) efgh 2 ijkl 2 mnop qrst uvwx yzAB 2 CDEF 2 GHIJ 2 ||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||| (line 2) efgh ijkl mnop qrst | > > > > > > > > > | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | <<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<< (line 2) efgh 2 ijkl 2 mnop qrst uvwx yzAB 2 CDEF 2 GHIJ 2 ####### SUGGESTED CONFLICT RESOLUTION follows ################### efgh 2 ijkl 2 mnop 3 qrst 3 uvwx 3 yzAB 3 CDEF 2 GHIJ 2 ||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||| (line 2) efgh ijkl mnop qrst |
| ︙ | ︙ |
Changes to test/merge3.test.
| ︙ | ︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
write_file t2 [join [string trim $v1] \n]\n
write_file t3 [join [string trim $v2] \n]\n
fossil 3-way-merge t1 t2 t3 t4 {*}$fossil_args
set x [read_file t4]
regsub -all \
{<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <+ \(line \d+\)} \
$x {MINE:} x
regsub -all \
{\|\|\|\|\|\|\| COMMON ANCESTOR content follows \|+ \(line \d+\)} \
$x {COM:} x
regsub -all \
{======= MERGED IN content follows =+ \(line \d+\)} \
$x {YOURS:} x
regsub -all \
| > > > | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
write_file t2 [join [string trim $v1] \n]\n
write_file t3 [join [string trim $v2] \n]\n
fossil 3-way-merge t1 t2 t3 t4 {*}$fossil_args
set x [read_file t4]
regsub -all \
{<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <+ \(line \d+\)} \
$x {MINE:} x
regsub -all \
{####### SUGGESTED CONFLICT RESOLUTION follows #+} \
$x {BOT:} x
regsub -all \
{\|\|\|\|\|\|\| COMMON ANCESTOR content follows \|+ \(line \d+\)} \
$x {COM:} x
regsub -all \
{======= MERGED IN content follows =+ \(line \d+\)} \
$x {YOURS:} x
regsub -all \
|
| ︙ | ︙ | |||
71 72 73 74 75 76 77 |
merge-test 3 {
1 2 3 4 5 6 7 8 9
} {
1 2 3b 4b 5b 6 7 8 9
} {
1 2 3 4 5c 6 7 8 9
} {
| | | | | | | | 74 75 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 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 131 132 133 |
merge-test 3 {
1 2 3 4 5 6 7 8 9
} {
1 2 3b 4b 5b 6 7 8 9
} {
1 2 3 4 5c 6 7 8 9
} {
1 2 MINE: 3b 4b 5b BOT: 3b 4b 5c COM: 3 4 5 YOURS: 3 4 5c END 6 7 8 9
} -expectError
merge-test 4 {
1 2 3 4 5 6 7 8 9
} {
1 2 3b 4b 5b 6b 7 8 9
} {
1 2 3 4 5c 6 7 8 9
} {
1 2 MINE: 3b 4b 5b 6b BOT: 3b 4b 5b 5c 6 COM: 3 4 5 6 YOURS: 3 4 5c 6 END 7 8 9
} -expectError
merge-test 5 {
1 2 3 4 5 6 7 8 9
} {
1 2 3b 4b 5b 6b 7 8 9
} {
1 2 3 4 5c 6c 7c 8 9
} {
1 2 MINE: 3b 4b 5b 6b 7 BOT: 3b 4b 5b 5c 6c 7c COM: 3 4 5 6 7 YOURS: 3 4 5c 6c 7c END 8 9
} -expectError
merge-test 6 {
1 2 3 4 5 6 7 8 9
} {
1 2 3b 4b 5b 6b 7 8b 9
} {
1 2 3 4 5c 6c 7c 8 9
} {
1 2 MINE: 3b 4b 5b 6b 7 BOT: 3b 4b 5b 5c 6c 7c COM: 3 4 5 6 7 YOURS: 3 4 5c 6c 7c END 8b 9
} -expectError
merge-test 7 {
1 2 3 4 5 6 7 8 9
} {
1 2 3b 4b 5b 6b 7 8b 9
} {
1 2 3 4 5c 6c 7c 8c 9
} {
1 2 MINE: 3b 4b 5b 6b 7 8b BOT: 3b 4b 5b 5c 6c 7c 8c COM: 3 4 5 6 7 8 YOURS: 3 4 5c 6c 7c 8c END 9
} -expectError
merge-test 8 {
1 2 3 4 5 6 7 8 9
} {
1 2 3b 4b 5b 6b 7 8b 9b
} {
1 2 3 4 5c 6c 7c 8c 9
} {
1 2 MINE: 3b 4b 5b 6b 7 8b 9b BOT: 3b 4b 5b 5c 6c 7c 8c 9b COM: 3 4 5 6 7 8 9 YOURS: 3 4 5c 6c 7c 8c 9 END
} -expectError
merge-test 9 {
1 2 3 4 5 6 7 8 9
} {
1 2 3b 4b 5 6 7 8b 9b
} {
1 2 3 4 5c 6c 7c 8 9
|
| ︙ | ︙ | |||
144 145 146 147 148 149 150 |
merge-test 11 {
1 2 3 4 5 6 7 8 9
} {
1 2 3b 4b 5 6 7 8b 9b
} {
1 2 3b 4c 5 6c 7c 8 9
} {
| | | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
merge-test 11 {
1 2 3 4 5 6 7 8 9
} {
1 2 3b 4b 5 6 7 8b 9b
} {
1 2 3b 4c 5 6c 7c 8 9
} {
1 2 MINE: 3b 4b BOT: 3b 4c COM: 3 4 YOURS: 3b 4c END 5 6c 7c 8b 9b
} -expectError
merge-test 12 {
1 2 3 4 5 6 7 8 9
} {
1 2 3b4b 5 6 7 8b 9b
} {
1 2 3b4b 5 6c 7c 8 9
|
| ︙ | ︙ | |||
199 200 201 202 203 204 205 |
merge-test 24 {
1 2 3 4 5 6 7 8 9
} {
1 6 7 8 9
} {
1 2 3 4 9
} {
| | | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
merge-test 24 {
1 2 3 4 5 6 7 8 9
} {
1 6 7 8 9
} {
1 2 3 4 9
} {
1 MINE: 6 7 8 BOT: 2 3 4 COM: 2 3 4 5 6 7 8 YOURS: 2 3 4 END 9
} -expectError
merge-test 25 {
1 2 3 4 5 6 7 8 9
} {
1 7 8 9
} {
1 2 3 9
} {
1 MINE: 7 8 BOT: 2 3 COM: 2 3 4 5 6 7 8 YOURS: 2 3 END 9
} -expectError
merge-test 30 {
1 2 3 4 5 6 7 8 9
} {
1 2 3 4 5 6 7 9
} {
|
| ︙ | ︙ | |||
254 255 256 257 258 259 260 |
merge-test 34 {
1 2 3 4 5 6 7 8 9
} {
1 2 3 4 9
} {
1 6 7 8 9
} {
| | | | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
merge-test 34 {
1 2 3 4 5 6 7 8 9
} {
1 2 3 4 9
} {
1 6 7 8 9
} {
1 MINE: 2 3 4 BOT: 6 7 8 COM: 2 3 4 5 6 7 8 YOURS: 6 7 8 END 9
} -expectError
merge-test 35 {
1 2 3 4 5 6 7 8 9
} {
1 2 3 9
} {
1 7 8 9
} {
1 MINE: 2 3 BOT: 7 8 COM: 2 3 4 5 6 7 8 YOURS: 7 8 END 9
} -expectError
merge-test 40 {
2 3 4 5 6 7 8
} {
3 4 5 6 7 8
} {
|
| ︙ | ︙ | |||
309 310 311 312 313 314 315 |
merge-test 44 {
2 3 4 5 6 7 8
} {
6 7 8
} {
2 3 4
} {
| | | | 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 |
merge-test 44 {
2 3 4 5 6 7 8
} {
6 7 8
} {
2 3 4
} {
MINE: 6 7 8 BOT: 2 3 4 COM: 2 3 4 5 6 7 8 YOURS: 2 3 4 END
} -expectError
merge-test 45 {
2 3 4 5 6 7 8
} {
7 8
} {
2 3
} {
MINE: 7 8 BOT: 2 3 COM: 2 3 4 5 6 7 8 YOURS: 2 3 END
} -expectError
merge-test 50 {
2 3 4 5 6 7 8
} {
2 3 4 5 6 7
} {
|
| ︙ | ︙ | |||
363 364 365 366 367 368 369 |
merge-test 54 {
2 3 4 5 6 7 8
} {
2 3 4
} {
6 7 8
} {
| | | | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 |
merge-test 54 {
2 3 4 5 6 7 8
} {
2 3 4
} {
6 7 8
} {
MINE: 2 3 4 BOT: 6 7 8 COM: 2 3 4 5 6 7 8 YOURS: 6 7 8 END
} -expectError
merge-test 55 {
2 3 4 5 6 7 8
} {
2 3
} {
7 8
} {
MINE: 2 3 BOT: 7 8 COM: 2 3 4 5 6 7 8 YOURS: 7 8 END
} -expectError
merge-test 60 {
1 2 3 4 5 6 7 8 9
} {
1 2b 3 4 5 6 7 8 9
} {
|
| ︙ | ︙ | |||
418 419 420 421 422 423 424 |
merge-test 64 {
1 2 3 4 5 6 7 8 9
} {
1 2b 3b 4b 5b 6 7 8 9
} {
1 2 3 4 9
} {
| | | | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 |
merge-test 64 {
1 2 3 4 5 6 7 8 9
} {
1 2b 3b 4b 5b 6 7 8 9
} {
1 2 3 4 9
} {
1 MINE: 2b 3b 4b 5b 6 7 8 BOT: 2b 3b 4b 4 COM: 2 3 4 5 6 7 8 YOURS: 2 3 4 END 9
} -expectError
merge-test 65 {
1 2 3 4 5 6 7 8 9
} {
1 2b 3b 4b 5b 6b 7 8 9
} {
1 2 3 9
} {
1 MINE: 2b 3b 4b 5b 6b 7 8 BOT: 2 3 COM: 2 3 4 5 6 7 8 YOURS: 2 3 END 9
} -expectError
merge-test 70 {
1 2 3 4 5 6 7 8 9
} {
1 2 3 4 5 6 7 9
} {
|
| ︙ | ︙ | |||
473 474 475 476 477 478 479 |
merge-test 74 {
1 2 3 4 5 6 7 8 9
} {
1 2 3 4 9
} {
1 2b 3b 4b 5b 6 7 8 9
} {
| | | | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 |
merge-test 74 {
1 2 3 4 5 6 7 8 9
} {
1 2 3 4 9
} {
1 2b 3b 4b 5b 6 7 8 9
} {
1 MINE: 2 3 4 BOT: 2b 3b 4b 5b 6 7 8 COM: 2 3 4 5 6 7 8 YOURS: 2b 3b 4b 5b 6 7 8 END 9
} -expectError
merge-test 75 {
1 2 3 4 5 6 7 8 9
} {
1 2 3 9
} {
1 2b 3b 4b 5b 6b 7 8 9
} {
1 MINE: 2 3 BOT: 2b 3b 4b 5b 6b 7 8 COM: 2 3 4 5 6 7 8 YOURS: 2b 3b 4b 5b 6b 7 8 END 9
} -expectError
merge-test 80 {
2 3 4 5 6 7 8
} {
2b 3 4 5 6 7 8
} {
|
| ︙ | ︙ | |||
528 529 530 531 532 533 534 |
merge-test 84 {
2 3 4 5 6 7 8
} {
2b 3b 4b 5b 6 7 8
} {
2 3 4
} {
| | | | 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 |
merge-test 84 {
2 3 4 5 6 7 8
} {
2b 3b 4b 5b 6 7 8
} {
2 3 4
} {
MINE: 2b 3b 4b 5b 6 7 8 BOT: 2b 3b 4b 4 COM: 2 3 4 5 6 7 8 YOURS: 2 3 4 END
} -expectError
merge-test 85 {
2 3 4 5 6 7 8
} {
2b 3b 4b 5b 6b 7 8
} {
2 3
} {
MINE: 2b 3b 4b 5b 6b 7 8 BOT: 2 3 COM: 2 3 4 5 6 7 8 YOURS: 2 3 END
} -expectError
merge-test 90 {
2 3 4 5 6 7 8
} {
2 3 4 5 6 7
} {
|
| ︙ | ︙ | |||
583 584 585 586 587 588 589 |
merge-test 94 {
2 3 4 5 6 7 8
} {
2 3 4
} {
2b 3b 4b 5b 6 7 8
} {
| | | | 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 |
merge-test 94 {
2 3 4 5 6 7 8
} {
2 3 4
} {
2b 3b 4b 5b 6 7 8
} {
MINE: 2 3 4 BOT: 2b 3b 4b 5b 6 7 8 COM: 2 3 4 5 6 7 8 YOURS: 2b 3b 4b 5b 6 7 8 END
} -expectError
merge-test 95 {
2 3 4 5 6 7 8
} {
2 3
} {
2b 3b 4b 5b 6b 7 8
} {
MINE: 2 3 BOT: 2b 3b 4b 5b 6b 7 8 COM: 2 3 4 5 6 7 8 YOURS: 2b 3b 4b 5b 6b 7 8 END
} -expectError
merge-test 100 {
1 2 3 4 5 6 7 8 9
} {
1 2b 3 4 5 7 8 9 a b c d e
} {
|
| ︙ | ︙ | |||
629 630 631 632 633 634 635 |
merge-test 103 {
1 2 3 4 5 6 7 8 9
} {
1 2 3 4 5 7 8 9b
} {
1 2 3 4 5 7 8 9b a b c d e
} {
| | | | 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 |
merge-test 103 {
1 2 3 4 5 6 7 8 9
} {
1 2 3 4 5 7 8 9b
} {
1 2 3 4 5 7 8 9b a b c d e
} {
1 2 3 4 5 7 8 MINE: 9b BOT: 9b a b c d e COM: 9 YOURS: 9b a b c d e END
} -expectError
merge-test 104 {
1 2 3 4 5 6 7 8 9
} {
1 2 3 4 5 7 8 9b a b c d e
} {
1 2 3 4 5 7 8 9b
} {
1 2 3 4 5 7 8 MINE: 9b a b c d e BOT: 9b COM: 9 YOURS: 9b END
} -expectError
###############################################################################
test_cleanup
|
Changes to test/merge4.test.
| ︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
write_file t1 [join [string trim $basis] \n]\n
write_file t2 [join [string trim $v1] \n]\n
write_file t3 [join [string trim $v2] \n]\n
fossil 3-way-merge t1 t2 t3 t4 {*}$fossil_args
fossil 3-way-merge t1 t3 t2 t5 {*}$fossil_args
set x [read_file t4]
regsub -all {<<<<<<< BEGIN MERGE CONFLICT.*<< \(line \d+\)} $x {>} x
regsub -all {\|\|\|\|\|\|\|.*======= \(line \d+\)} $x {=} x
regsub -all {>>>>>>> END MERGE CONFLICT.*>>>>} $x {<} x
set x [split [string trim $x] \n]
set y [read_file t5]
regsub -all {<<<<<<< BEGIN MERGE CONFLICT.*<< \(line \d+\)} $y {>} y
regsub -all {\|\|\|\|\|\|\|.*======= \(line \d+\)} $y {=} y
regsub -all {>>>>>>> END MERGE CONFLICT.*>>>>} $y {<} y
set y [split [string trim $y] \n]
set result1 [string trim $result1]
if {$x!=$result1} {
protOut " Expected \[$result1\]"
protOut " Got \[$x\]"
| > > | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
write_file t1 [join [string trim $basis] \n]\n
write_file t2 [join [string trim $v1] \n]\n
write_file t3 [join [string trim $v2] \n]\n
fossil 3-way-merge t1 t2 t3 t4 {*}$fossil_args
fossil 3-way-merge t1 t3 t2 t5 {*}$fossil_args
set x [read_file t4]
regsub -all {<<<<<<< BEGIN MERGE CONFLICT.*<< \(line \d+\)} $x {>} x
regsub -all {####### SUGGESTED CONFLICT RESOLUTION.*##} $x {#} x
regsub -all {\|\|\|\|\|\|\|.*======= \(line \d+\)} $x {=} x
regsub -all {>>>>>>> END MERGE CONFLICT.*>>>>} $x {<} x
set x [split [string trim $x] \n]
set y [read_file t5]
regsub -all {<<<<<<< BEGIN MERGE CONFLICT.*<< \(line \d+\)} $y {>} y
regsub -all {####### SUGGESTED CONFLICT RESOLUTION.*##} $y {#} y
regsub -all {\|\|\|\|\|\|\|.*======= \(line \d+\)} $y {=} y
regsub -all {>>>>>>> END MERGE CONFLICT.*>>>>} $y {<} y
set y [split [string trim $y] \n]
set result1 [string trim $result1]
if {$x!=$result1} {
protOut " Expected \[$result1\]"
protOut " Got \[$x\]"
|
| ︙ | ︙ | |||
56 57 58 59 60 61 62 |
merge-test 1000 {
1 2 3 4 5 6 7 8 9
} {
1 2b 3b 4b 5 6b 7b 8b 9
} {
1 2 3 4c 5c 6c 7 8 9
} {
| | | | | | 58 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 96 |
merge-test 1000 {
1 2 3 4 5 6 7 8 9
} {
1 2b 3b 4b 5 6b 7b 8b 9
} {
1 2 3 4c 5c 6c 7 8 9
} {
1 > 2b 3b 4b 5 6b 7b 8b # 2b 3b 4c 5c 6c 7b 8b = 2 3 4c 5c 6c 7 8 < 9
} {
1 > 2 3 4c 5c 6c 7 8 # 2b 3b 4b 5c 6b 7b 8b = 2b 3b 4b 5 6b 7b 8b < 9
} -expectError
merge-test 1001 {
1 2 3 4 5 6 7 8 9
} {
1 2b 3b 4 5 6 7b 8b 9
} {
1 2 3 4c 5c 6c 7 8 9
} {
1 2b 3b 4c 5c 6c 7b 8b 9
} {
1 2b 3b 4c 5c 6c 7b 8b 9
}
merge-test 1002 {
2 3 4 5 6 7 8
} {
2b 3b 4b 5 6b 7b 8b
} {
2 3 4c 5c 6c 7 8
} {
> 2b 3b 4b 5 6b 7b 8b # 2b 3b 4c 5c 6c 7b 8b = 2 3 4c 5c 6c 7 8 <
} {
> 2 3 4c 5c 6c 7 8 # 2b 3b 4b 5c 6b 7b 8b = 2b 3b 4b 5 6b 7b 8b <
} -expectError
merge-test 1003 {
2 3 4 5 6 7 8
} {
2b 3b 4 5 6 7b 8b
} {
2 3 4c 5c 6c 7 8
|
| ︙ | ︙ |
Changes to test/tester.tcl.
| ︙ | ︙ | |||
330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
email-url \
empty-dirs \
encoding-glob \
exec-rel-paths \
fileedit-glob \
forbid-delta-manifests \
forum-close-policy \
gdiff-command \
gmerge-command \
hash-digits \
hooks \
http-port \
https-login \
ignore-glob \
| > | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 |
email-url \
empty-dirs \
encoding-glob \
exec-rel-paths \
fileedit-glob \
forbid-delta-manifests \
forum-close-policy \
forum-title \
gdiff-command \
gmerge-command \
hash-digits \
hooks \
http-port \
https-login \
ignore-glob \
|
| ︙ | ︙ | |||
370 371 372 373 374 375 376 377 378 379 380 381 382 383 |
ssh-command \
ssl-ca-location \
ssl-identity \
tclsh \
th1-setup \
th1-uri-regexp \
ticket-default-report \
user-color-map \
uv-sync \
web-browser]
fossil test-th-eval "hasfeature legacyMvRm"
if {[normalize_result] eq "1"} {
| > | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 |
ssh-command \
ssl-ca-location \
ssl-identity \
tclsh \
th1-setup \
th1-uri-regexp \
ticket-default-report \
timeline-utc \
user-color-map \
uv-sync \
web-browser]
fossil test-th-eval "hasfeature legacyMvRm"
if {[normalize_result] eq "1"} {
|
| ︙ | ︙ |
Changes to test/update.test.
| ︙ | ︙ | |||
55 56 57 58 59 60 61 |
# Make sure we are not in an open repository and initialize new repository
test_setup
###############################################################################
fossil update --verbose
test update-already-up-to-date {
| | | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# Make sure we are not in an open repository and initialize new repository
test_setup
###############################################################################
fossil update --verbose
test update-already-up-to-date {
[regexp {^-{79}\ncheckout: .*\nchanges: +None. Already up-to-date.$} $RESULT]
}
# Remaining tests are carried out in the order update_cmd() performs checks.
#
# Common approach for tests below:
# 1. Set the testname
# 2. Set the file name, done by calling update_setup
|
| ︙ | ︙ |
Changes to tools/emcc.sh.in.
|
| | > | | > > | > | | | | | | | | > > > | < | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 |
#!/bin/sh
# ^^^^^^^ Please try to keep this script Bourne-compatible.
########################################################################
# WARNING: emcc.sh is generated from emcc.sh.in by the configure
# process. Do not edit emcc.sh directly, as it may be deleted or
# overwritten by the configure script.
#
# A wrapper around the emcc compiler which uses configure-time state
# to locate the Emscripten SDK and import the SDK's environment
# script, if needed.
########################################################################
# EMSDK_HOME comes from the configure --with-emsdk=/dir flag.
# EMSDK_ENV_SH is ${thatDir}/emsdk_env.sh and is also set by the
# configure process.
EMSDK_HOME="@EMSDK_HOME@"
EMSDK_ENV_SH="@EMSDK_ENV_SH@"
emcc="@BIN_EMCC@"
if [ x = "x${emcc}" ]; then
emcc=`which emcc 2>/dev/null`
fi
if [ x = "x${emcc}" ]; then
# If emcc is not found in the path, try to find it via an emsdk
# installation. The SDK variant is the official installation style
# supported by the Emscripten project, but emcc is also available
# via package managers on some OSes.
if [ x = "x${EMSDK_HOME}" ]; then
echo "EMSDK_HOME is not set. Pass --with-emsdk=/path/to/emsdk" \
"to the configure script." 1>&2
exit 1
fi
if [ x = "x${EMSDK_ENV_SH}" ]; then
if [ -f "${EMSDK_HOME}/emsdk_env.sh" ]; then
EMSDK_ENV_SH="${EMSDK_HOME}/emsdk_env.sh"
else
echo "EMSDK_ENV_SH is not set. Expecting configure script to set it." 1>&2
exit 2
fi
fi
if [ ! -f "${EMSDK_ENV_SH}" ]; then
echo "emsdk_env script not found: $EMSDK_ENV_SH" 1>&2
exit 3
fi
# $EMSDK is part of the state set by emsdk_env.sh.
if [ x = "x${EMSDK}" ]; then
EMSDK_QUIET=1
export EMSDK_QUIET
# ^^^ Squelches informational output from ${EMSDK_ENV_SH}.
source "${EMSDK_ENV_SH}" || {
rc=$?
echo "Error sourcing ${EMSDK_ENV_SH}"
exit $rc
}
fi
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 tools/makemake.tcl.
| ︙ | ︙ | |||
130 131 132 133 134 135 136 137 138 139 140 141 142 143 | loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name patch path | > | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | loadctrl login lookslike main manifest markdown markdown_html match md5 merge merge3 moderate name patch path |
| ︙ | ︙ | |||
237 238 239 240 241 242 243 244 245 | -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 | > | | | 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP } #lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1 |
| ︙ | ︙ | |||
377 378 379 380 381 382 383 384 385 386 387 388 389 390 | codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1 $(OBJDIR)/codecheck1 $(TRANS_SRC) $(OBJDIR): -mkdir $(OBJDIR) $(OBJDIR)/translate: $(SRCDIR_tools)/translate.c $(XBCC) -o $(OBJDIR)/translate $(SRCDIR_tools)/translate.c $(OBJDIR)/makeheaders: $(SRCDIR_tools)/makeheaders.c $(XBCC) -o $(OBJDIR)/makeheaders $(SRCDIR_tools)/makeheaders.c $(OBJDIR)/mkindex: $(SRCDIR_tools)/mkindex.c $(XBCC) -o $(OBJDIR)/mkindex $(SRCDIR_tools)/mkindex.c | > | 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 | codecheck: $(TRANS_SRC) $(OBJDIR)/codecheck1 $(OBJDIR)/codecheck1 $(TRANS_SRC) $(OBJDIR): -mkdir $(OBJDIR) $(OBJDIR)/translate: $(SRCDIR_tools)/translate.c -mkdir -p $(OBJDIR) $(XBCC) -o $(OBJDIR)/translate $(SRCDIR_tools)/translate.c $(OBJDIR)/makeheaders: $(SRCDIR_tools)/makeheaders.c $(XBCC) -o $(OBJDIR)/makeheaders $(SRCDIR_tools)/makeheaders.c $(OBJDIR)/mkindex: $(SRCDIR_tools)/mkindex.c $(XBCC) -o $(OBJDIR)/mkindex $(SRCDIR_tools)/mkindex.c |
| ︙ | ︙ |
Changes to tools/translate.c.
| ︙ | ︙ | |||
76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
*/
static int inStr = 0;
/*
** Name of files being processed
*/
static const char *zInFile = "(stdin)";
/*
** Terminate an active cgi_printf() or free string
*/
static void end_block(FILE *out){
if( inPrint ){
zArg[nArg] = 0;
| > > > > > > > > > > > | 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 |
*/
static int inStr = 0;
/*
** Name of files being processed
*/
static const char *zInFile = "(stdin)";
/*
** The `fossil_isspace()' function copied from the Fossil source code.
** Some MSVC runtime library versions of `isspace()' break with an `assert()' if
** the input is smaller than -1 or greater than 255 in debug builds, due to sign
** extension when promoting `signed char' to `int' for non-ASCII characters. Use
** an `isspace()' replacement instead of explicit type casts to `unsigned char'.
*/
int fossil_isspace(char c){
return c==' ' || (c<='\r' && c>='\t');
}
/*
** Terminate an active cgi_printf() or free string
*/
static void end_block(FILE *out){
if( inPrint ){
zArg[nArg] = 0;
|
| ︙ | ︙ | |||
104 105 106 107 108 109 110 |
int lineNo = 0; /* Line number */
char zLine[2000]; /* A single line of input */
char zOut[4000]; /* The input line translated into appropriate output */
c1 = c2 = '-';
while( fgets(zLine, sizeof(zLine), in) ){
lineNo++;
| | | | | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
int lineNo = 0; /* Line number */
char zLine[2000]; /* A single line of input */
char zOut[4000]; /* The input line translated into appropriate output */
c1 = c2 = '-';
while( fgets(zLine, sizeof(zLine), in) ){
lineNo++;
for(i=0; zLine[i] && fossil_isspace(zLine[i]); i++){}
if( zLine[i]!='@' ){
if( inPrint || inStr ) end_block(out);
fprintf(out,"%s",zLine);
/* 0123456789 12345 */
if( strncmp(zLine, "/* @-comment: ", 14)==0 ){
c1 = zLine[14];
c2 = zLine[15];
}
i += strlen(&zLine[i]);
while( i>0 && fossil_isspace(zLine[i-1]) ){ i--; }
lastWasEq = i>0 && zLine[i-1]=='=';
lastWasComma = i>0 && zLine[i-1]==',';
}else if( lastWasEq || lastWasComma){
/* If the last non-whitespace character before the first @ was
** an "="(var init/set) or a ","(const definition in list) then
** generate a string literal. But skip comments
** consisting of all text between c1 and c2 (default "--")
** and end of line.
*/
int indent, omitline;
char *zNewline = "\\n";
i++;
if( fossil_isspace(zLine[i]) ){ i++; }
indent = i - 2;
if( indent<0 ) indent = 0;
omitline = 0;
for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
if( zLine[i]==c1 && (c2==' ' || zLine[i+1]==c2) ){
omitline = 1; break;
}
if( zLine[i]=='\\' && (zLine[i+1]==0 || zLine[i+1]=='\r'
|| zLine[i+1]=='\n') ){
zLine[i] = 0;
zNewline = "";
/* fprintf(stderr, "%s:%d: omit newline\n", zInFile, lineNo); */
break;
}
if( zLine[i]=='\\' || zLine[i]=='"' ){ zOut[j++] = '\\'; }
zOut[j++] = zLine[i];
}
if( zNewline[0] ) while( j>0 && fossil_isspace(zOut[j-1]) ){ j--; }
zOut[j] = 0;
if( j<=0 && omitline ){
fprintf(out,"\n");
}else{
fprintf(out,"%*s\"%s%s\"\n",indent, "", zOut, zNewline);
}
}else{
|
| ︙ | ︙ | |||
169 170 171 172 173 174 175 |
*/
const char *zNewline = "\\n";
int indent;
int nC;
int nParam;
char c;
i++;
| | | 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
*/
const char *zNewline = "\\n";
int indent;
int nC;
int nParam;
char c;
i++;
if( fossil_isspace(zLine[i]) ){ i++; }
indent = i;
for(j=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){
if( zLine[i]=='\\' && (!zLine[i+1] || zLine[i+1]=='\r'
|| zLine[i+1]=='\n') ){
zNewline = "";
break;
}
|
| ︙ | ︙ |
Changes to win/Makefile.dmc.
| ︙ | ︙ | |||
24 25 26 27 28 29 30 | SSL = CFLAGS = -o BCC = $(DMDIR)\bin\dmc $(CFLAGS) TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi | | | | | | | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 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 | SSL = CFLAGS = -o BCC = $(DMDIR)\bin\dmc $(CFLAGS) TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen PIKCHR_OPTIONS = -DPIKCHR_TOKEN_LIMIT=10000 SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c chat_.c checkin_.c checkout_.c clearsign_.c clone_.c color_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c interwiki_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c match_.c md5_.c merge_.c merge3_.c moderate_.c name_.c patch_.c path_.c piechart_.c pikchrshow_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c zip_.c OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\chat$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\color$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\interwiki$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\match$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\patch$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pikchrshow$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O RC=$(DMDIR)\bin\rcc RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ APPNAME = $(OBJDIR)\fossil$(E) all: $(APPNAME) $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link cd $(OBJDIR) codecheck1$E $(SRC) $(DMDIR)\bin\link @link $(OBJDIR)\fossil.res: $B\win\fossil.rc $(RC) $(RCFLAGS) -o$@ $** $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res +echo add ajax alerts allrepo attach backlink backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi chat checkin checkout clearsign clone color comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file fileedit finfo foci forum fshell fusefs fuzz glob graph gzip hname hook http http_socket http_ssl http_transport import info interwiki json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html match md5 merge merge3 moderate name patch path piechart pikchrshow pivot popen pqueue printf publish purge rebuild regexp repolist report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar terminal th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile wiki wikiformat winfile winhttp xfer xfersetup zip shell sqlite3 th th_lang > $@ +echo fossil >> $@ +echo fossil >> $@ +echo $(LIBS) >> $@ +echo. >> $@ +echo fossil >> $@ translate$E: $(SRCDIR_tools)\translate.c |
| ︙ | ︙ | |||
633 634 635 636 637 638 639 640 641 642 643 644 645 646 | +translate$E $** > $@ $(OBJDIR)\markdown_html$O : markdown_html_.c markdown_html.h $(TCC) -o$@ -c markdown_html_.c markdown_html_.c : $(SRCDIR)\markdown_html.c +translate$E $** > $@ $(OBJDIR)\md5$O : md5_.c md5.h $(TCC) -o$@ -c md5_.c md5_.c : $(SRCDIR)\md5.c +translate$E $** > $@ | > > > > > > | 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 | +translate$E $** > $@ $(OBJDIR)\markdown_html$O : markdown_html_.c markdown_html.h $(TCC) -o$@ -c markdown_html_.c markdown_html_.c : $(SRCDIR)\markdown_html.c +translate$E $** > $@ $(OBJDIR)\match$O : match_.c match.h $(TCC) -o$@ -c match_.c match_.c : $(SRCDIR)\match.c +translate$E $** > $@ $(OBJDIR)\md5$O : md5_.c md5.h $(TCC) -o$@ -c md5_.c md5_.c : $(SRCDIR)\md5.c +translate$E $** > $@ |
| ︙ | ︙ | |||
1007 1008 1009 1010 1011 1012 1013 | $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h VERSION.h | | | 1013 1014 1015 1016 1017 1018 1019 1020 1021 | $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h VERSION.h +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h chat_.c:chat.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h color_.c:color.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h interwiki_.c:interwiki.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h match_.c:match.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h patch_.c:patch.h path_.c:path.h piechart_.c:piechart.h pikchrshow_.c:pikchrshow.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR_extsrc)\pikchr.c:pikchr.h $(SRCDIR_extsrc)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR_extsrc)\cson_amalgamation.h @copy /Y nul: headers |
Changes to win/Makefile.mingw.
| ︙ | ︙ | |||
483 484 485 486 487 488 489 490 491 492 493 494 495 496 | $(SRCDIR)/loadctrl.c \ $(SRCDIR)/login.c \ $(SRCDIR)/lookslike.c \ $(SRCDIR)/main.c \ $(SRCDIR)/manifest.c \ $(SRCDIR)/markdown.c \ $(SRCDIR)/markdown_html.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/moderate.c \ $(SRCDIR)/name.c \ $(SRCDIR)/patch.c \ $(SRCDIR)/path.c \ | > | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 | $(SRCDIR)/loadctrl.c \ $(SRCDIR)/login.c \ $(SRCDIR)/lookslike.c \ $(SRCDIR)/main.c \ $(SRCDIR)/manifest.c \ $(SRCDIR)/markdown.c \ $(SRCDIR)/markdown_html.c \ $(SRCDIR)/match.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/moderate.c \ $(SRCDIR)/name.c \ $(SRCDIR)/patch.c \ $(SRCDIR)/path.c \ |
| ︙ | ︙ | |||
748 749 750 751 752 753 754 755 756 757 758 759 760 761 | $(OBJDIR)/loadctrl_.c \ $(OBJDIR)/login_.c \ $(OBJDIR)/lookslike_.c \ $(OBJDIR)/main_.c \ $(OBJDIR)/manifest_.c \ $(OBJDIR)/markdown_.c \ $(OBJDIR)/markdown_html_.c \ $(OBJDIR)/md5_.c \ $(OBJDIR)/merge_.c \ $(OBJDIR)/merge3_.c \ $(OBJDIR)/moderate_.c \ $(OBJDIR)/name_.c \ $(OBJDIR)/patch_.c \ $(OBJDIR)/path_.c \ | > | 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 | $(OBJDIR)/loadctrl_.c \ $(OBJDIR)/login_.c \ $(OBJDIR)/lookslike_.c \ $(OBJDIR)/main_.c \ $(OBJDIR)/manifest_.c \ $(OBJDIR)/markdown_.c \ $(OBJDIR)/markdown_html_.c \ $(OBJDIR)/match_.c \ $(OBJDIR)/md5_.c \ $(OBJDIR)/merge_.c \ $(OBJDIR)/merge3_.c \ $(OBJDIR)/moderate_.c \ $(OBJDIR)/name_.c \ $(OBJDIR)/patch_.c \ $(OBJDIR)/path_.c \ |
| ︙ | ︙ | |||
897 898 899 900 901 902 903 904 905 906 907 908 909 910 | $(OBJDIR)/loadctrl.o \ $(OBJDIR)/login.o \ $(OBJDIR)/lookslike.o \ $(OBJDIR)/main.o \ $(OBJDIR)/manifest.o \ $(OBJDIR)/markdown.o \ $(OBJDIR)/markdown_html.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/moderate.o \ $(OBJDIR)/name.o \ $(OBJDIR)/patch.o \ $(OBJDIR)/path.o \ | > | 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 | $(OBJDIR)/loadctrl.o \ $(OBJDIR)/login.o \ $(OBJDIR)/lookslike.o \ $(OBJDIR)/main.o \ $(OBJDIR)/manifest.o \ $(OBJDIR)/markdown.o \ $(OBJDIR)/markdown_html.o \ $(OBJDIR)/match.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/moderate.o \ $(OBJDIR)/name.o \ $(OBJDIR)/patch.o \ $(OBJDIR)/path.o \ |
| ︙ | ︙ | |||
1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 | $(OBJDIR)/loadctrl_.c:$(OBJDIR)/loadctrl.h \ $(OBJDIR)/login_.c:$(OBJDIR)/login.h \ $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h \ $(OBJDIR)/main_.c:$(OBJDIR)/main.h \ $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \ $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \ $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \ $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \ $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h \ $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h \ $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \ $(OBJDIR)/name_.c:$(OBJDIR)/name.h \ $(OBJDIR)/patch_.c:$(OBJDIR)/patch.h \ $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ | > | 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 | $(OBJDIR)/loadctrl_.c:$(OBJDIR)/loadctrl.h \ $(OBJDIR)/login_.c:$(OBJDIR)/login.h \ $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h \ $(OBJDIR)/main_.c:$(OBJDIR)/main.h \ $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \ $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \ $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \ $(OBJDIR)/match_.c:$(OBJDIR)/match.h \ $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \ $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h \ $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h \ $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \ $(OBJDIR)/name_.c:$(OBJDIR)/name.h \ $(OBJDIR)/patch_.c:$(OBJDIR)/patch.h \ $(OBJDIR)/path_.c:$(OBJDIR)/path.h \ |
| ︙ | ︙ | |||
2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 | $(OBJDIR)/markdown_html_.c: $(SRCDIR)/markdown_html.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/markdown_html.c >$@ $(OBJDIR)/markdown_html.o: $(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/markdown_html.o -c $(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h: $(OBJDIR)/headers $(OBJDIR)/md5_.c: $(SRCDIR)/md5.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/md5.c >$@ $(OBJDIR)/md5.o: $(OBJDIR)/md5_.c $(OBJDIR)/md5.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/md5.o -c $(OBJDIR)/md5_.c | > > > > > > > > | 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 | $(OBJDIR)/markdown_html_.c: $(SRCDIR)/markdown_html.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/markdown_html.c >$@ $(OBJDIR)/markdown_html.o: $(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/markdown_html.o -c $(OBJDIR)/markdown_html_.c $(OBJDIR)/markdown_html.h: $(OBJDIR)/headers $(OBJDIR)/match_.c: $(SRCDIR)/match.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/match.c >$@ $(OBJDIR)/match.o: $(OBJDIR)/match_.c $(OBJDIR)/match.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/match.o -c $(OBJDIR)/match_.c $(OBJDIR)/match.h: $(OBJDIR)/headers $(OBJDIR)/md5_.c: $(SRCDIR)/md5.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/md5.c >$@ $(OBJDIR)/md5.o: $(OBJDIR)/md5_.c $(OBJDIR)/md5.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/md5.o -c $(OBJDIR)/md5_.c |
| ︙ | ︙ | |||
2514 2515 2516 2517 2518 2519 2520 2521 2522 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
| > | | | 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-DSQLITE_WIN32_NO_ANSI \
$(MINGW_OPTIONS) \
|
| ︙ | ︙ | |||
2542 2543 2544 2545 2546 2547 2548 2549 2550 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
| > | | | 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 |
-DSQLITE_OMIT_DEPRECATED \
-DSQLITE_OMIT_PROGRESS_CALLBACK \
-DSQLITE_OMIT_SHARED_CACHE \
-DSQLITE_OMIT_LOAD_EXTENSION \
-DSQLITE_MAX_EXPR_DEPTH=0 \
-DSQLITE_ENABLE_LOCKING_STYLE=0 \
-DSQLITE_DEFAULT_FILE_FORMAT=4 \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \
-DSQLITE_ENABLE_FTS4 \
-DSQLITE_ENABLE_FTS5 \
-DSQLITE_ENABLE_MATH_FUNCTIONS \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_HAVE_ZLIB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_TRUSTED_SCHEMA=0 \
-DHAVE_USLEEP \
-Dmain=sqlite3_shell \
-DSQLITE_SHELL_IS_UTF8=1 \
|
| ︙ | ︙ |
Changes to win/Makefile.msc.
| ︙ | ︙ | |||
309 310 311 312 313 314 315 316 317 |
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_OMIT_PROGRESS_CALLBACK \
/DSQLITE_OMIT_SHARED_CACHE \
/DSQLITE_OMIT_LOAD_EXTENSION \
/DSQLITE_MAX_EXPR_DEPTH=0 \
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
| > | | | 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_OMIT_PROGRESS_CALLBACK \
/DSQLITE_OMIT_SHARED_CACHE \
/DSQLITE_OMIT_LOAD_EXTENSION \
/DSQLITE_MAX_EXPR_DEPTH=0 \
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_DBSTAT_VTAB \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
/DSQLITE_ENABLE_FTS5 \
/DSQLITE_ENABLE_MATH_FUNCTIONS \
/DSQLITE_ENABLE_STMTVTAB \
/DSQLITE_HAVE_ZLIB \
/DSQLITE_ENABLE_DBPAGE_VTAB \
/DSQLITE_TRUSTED_SCHEMA=0 \
/DHAVE_USLEEP \
/DSQLITE_WIN32_NO_ANSI
|
| ︙ | ︙ | |||
334 335 336 337 338 339 340 341 342 |
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_OMIT_PROGRESS_CALLBACK \
/DSQLITE_OMIT_SHARED_CACHE \
/DSQLITE_OMIT_LOAD_EXTENSION \
/DSQLITE_MAX_EXPR_DEPTH=0 \
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
| > | | | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
/DSQLITE_OMIT_DEPRECATED \
/DSQLITE_OMIT_PROGRESS_CALLBACK \
/DSQLITE_OMIT_SHARED_CACHE \
/DSQLITE_OMIT_LOAD_EXTENSION \
/DSQLITE_MAX_EXPR_DEPTH=0 \
/DSQLITE_ENABLE_LOCKING_STYLE=0 \
/DSQLITE_DEFAULT_FILE_FORMAT=4 \
/DSQLITE_ENABLE_DBSTAT_VTAB \
/DSQLITE_ENABLE_EXPLAIN_COMMENTS \
/DSQLITE_ENABLE_FTS4 \
/DSQLITE_ENABLE_FTS5 \
/DSQLITE_ENABLE_MATH_FUNCTIONS \
/DSQLITE_ENABLE_STMTVTAB \
/DSQLITE_HAVE_ZLIB \
/DSQLITE_ENABLE_DBPAGE_VTAB \
/DSQLITE_TRUSTED_SCHEMA=0 \
/DHAVE_USLEEP \
/Dmain=sqlite3_shell \
/DSQLITE_SHELL_IS_UTF8=1 \
|
| ︙ | ︙ | |||
441 442 443 444 445 446 447 448 449 450 451 452 453 454 |
"$(OX)\loadctrl_.c" \
"$(OX)\login_.c" \
"$(OX)\lookslike_.c" \
"$(OX)\main_.c" \
"$(OX)\manifest_.c" \
"$(OX)\markdown_.c" \
"$(OX)\markdown_html_.c" \
"$(OX)\md5_.c" \
"$(OX)\merge_.c" \
"$(OX)\merge3_.c" \
"$(OX)\moderate_.c" \
"$(OX)\name_.c" \
"$(OX)\patch_.c" \
"$(OX)\path_.c" \
| > | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 |
"$(OX)\loadctrl_.c" \
"$(OX)\login_.c" \
"$(OX)\lookslike_.c" \
"$(OX)\main_.c" \
"$(OX)\manifest_.c" \
"$(OX)\markdown_.c" \
"$(OX)\markdown_html_.c" \
"$(OX)\match_.c" \
"$(OX)\md5_.c" \
"$(OX)\merge_.c" \
"$(OX)\merge3_.c" \
"$(OX)\moderate_.c" \
"$(OX)\name_.c" \
"$(OX)\patch_.c" \
"$(OX)\path_.c" \
|
| ︙ | ︙ | |||
706 707 708 709 710 711 712 713 714 715 716 717 718 719 |
"$(OX)\loadctrl$O" \
"$(OX)\login$O" \
"$(OX)\lookslike$O" \
"$(OX)\main$O" \
"$(OX)\manifest$O" \
"$(OX)\markdown$O" \
"$(OX)\markdown_html$O" \
"$(OX)\md5$O" \
"$(OX)\merge$O" \
"$(OX)\merge3$O" \
"$(OX)\moderate$O" \
"$(OX)\name$O" \
"$(OX)\patch$O" \
"$(OX)\path$O" \
| > | 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 |
"$(OX)\loadctrl$O" \
"$(OX)\login$O" \
"$(OX)\lookslike$O" \
"$(OX)\main$O" \
"$(OX)\manifest$O" \
"$(OX)\markdown$O" \
"$(OX)\markdown_html$O" \
"$(OX)\match$O" \
"$(OX)\md5$O" \
"$(OX)\merge$O" \
"$(OX)\merge3$O" \
"$(OX)\moderate$O" \
"$(OX)\name$O" \
"$(OX)\patch$O" \
"$(OX)\path$O" \
|
| ︙ | ︙ | |||
955 956 957 958 959 960 961 962 963 964 965 966 967 968 | echo "$(OX)\loadctrl.obj" >> $@ echo "$(OX)\login.obj" >> $@ echo "$(OX)\lookslike.obj" >> $@ echo "$(OX)\main.obj" >> $@ echo "$(OX)\manifest.obj" >> $@ echo "$(OX)\markdown.obj" >> $@ echo "$(OX)\markdown_html.obj" >> $@ echo "$(OX)\md5.obj" >> $@ echo "$(OX)\merge.obj" >> $@ echo "$(OX)\merge3.obj" >> $@ echo "$(OX)\moderate.obj" >> $@ echo "$(OX)\name.obj" >> $@ echo "$(OX)\patch.obj" >> $@ echo "$(OX)\path.obj" >> $@ | > | 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 | echo "$(OX)\loadctrl.obj" >> $@ echo "$(OX)\login.obj" >> $@ echo "$(OX)\lookslike.obj" >> $@ echo "$(OX)\main.obj" >> $@ echo "$(OX)\manifest.obj" >> $@ echo "$(OX)\markdown.obj" >> $@ echo "$(OX)\markdown_html.obj" >> $@ echo "$(OX)\match.obj" >> $@ echo "$(OX)\md5.obj" >> $@ echo "$(OX)\merge.obj" >> $@ echo "$(OX)\merge3.obj" >> $@ echo "$(OX)\moderate.obj" >> $@ echo "$(OX)\name.obj" >> $@ echo "$(OX)\patch.obj" >> $@ echo "$(OX)\path.obj" >> $@ |
| ︙ | ︙ | |||
1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 | "$(OBJDIR)\translate$E" $** > $@ "$(OX)\markdown_html$O" : "$(OX)\markdown_html_.c" "$(OX)\markdown_html.h" $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\markdown_html_.c" "$(OX)\markdown_html_.c" : "$(SRCDIR)\markdown_html.c" "$(OBJDIR)\translate$E" $** > $@ "$(OX)\md5$O" : "$(OX)\md5_.c" "$(OX)\md5.h" $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\md5_.c" "$(OX)\md5_.c" : "$(SRCDIR)\md5.c" "$(OBJDIR)\translate$E" $** > $@ | > > > > > > | 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 | "$(OBJDIR)\translate$E" $** > $@ "$(OX)\markdown_html$O" : "$(OX)\markdown_html_.c" "$(OX)\markdown_html.h" $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\markdown_html_.c" "$(OX)\markdown_html_.c" : "$(SRCDIR)\markdown_html.c" "$(OBJDIR)\translate$E" $** > $@ "$(OX)\match$O" : "$(OX)\match_.c" "$(OX)\match.h" $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\match_.c" "$(OX)\match_.c" : "$(SRCDIR)\match.c" "$(OBJDIR)\translate$E" $** > $@ "$(OX)\md5$O" : "$(OX)\md5_.c" "$(OX)\md5.h" $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\md5_.c" "$(OX)\md5_.c" : "$(SRCDIR)\md5.c" "$(OBJDIR)\translate$E" $** > $@ |
| ︙ | ︙ | |||
2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 | "$(OX)\loadctrl_.c":"$(OX)\loadctrl.h" \ "$(OX)\login_.c":"$(OX)\login.h" \ "$(OX)\lookslike_.c":"$(OX)\lookslike.h" \ "$(OX)\main_.c":"$(OX)\main.h" \ "$(OX)\manifest_.c":"$(OX)\manifest.h" \ "$(OX)\markdown_.c":"$(OX)\markdown.h" \ "$(OX)\markdown_html_.c":"$(OX)\markdown_html.h" \ "$(OX)\md5_.c":"$(OX)\md5.h" \ "$(OX)\merge_.c":"$(OX)\merge.h" \ "$(OX)\merge3_.c":"$(OX)\merge3.h" \ "$(OX)\moderate_.c":"$(OX)\moderate.h" \ "$(OX)\name_.c":"$(OX)\name.h" \ "$(OX)\patch_.c":"$(OX)\patch.h" \ "$(OX)\path_.c":"$(OX)\path.h" \ | > | 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 | "$(OX)\loadctrl_.c":"$(OX)\loadctrl.h" \ "$(OX)\login_.c":"$(OX)\login.h" \ "$(OX)\lookslike_.c":"$(OX)\lookslike.h" \ "$(OX)\main_.c":"$(OX)\main.h" \ "$(OX)\manifest_.c":"$(OX)\manifest.h" \ "$(OX)\markdown_.c":"$(OX)\markdown.h" \ "$(OX)\markdown_html_.c":"$(OX)\markdown_html.h" \ "$(OX)\match_.c":"$(OX)\match.h" \ "$(OX)\md5_.c":"$(OX)\md5.h" \ "$(OX)\merge_.c":"$(OX)\merge.h" \ "$(OX)\merge3_.c":"$(OX)\merge3.h" \ "$(OX)\moderate_.c":"$(OX)\moderate.h" \ "$(OX)\name_.c":"$(OX)\name.h" \ "$(OX)\patch_.c":"$(OX)\patch.h" \ "$(OX)\path_.c":"$(OX)\path.h" \ |
| ︙ | ︙ |
Changes to www/alerts.md.
| ︙ | ︙ | |||
32 33 34 35 36 37 38 | system. To follow this guide, you will need a Fossil UI browser window open to the [Admin → Notification](/setup_notification) Fossil UI screen on the Fossil server that will be sending these email alerts, logged in as a user with [**Admin** capability](./caps/ref.html#a). It is not possible to work on a clone of the server's repository and push the configuration changes up to that repo as an Admin user, [on purpose](#backup). | < < < < < | | > | | 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 | system. To follow this guide, you will need a Fossil UI browser window open to the [Admin → Notification](/setup_notification) Fossil UI screen on the Fossil server that will be sending these email alerts, logged in as a user with [**Admin** capability](./caps/ref.html#a). It is not possible to work on a clone of the server's repository and push the configuration changes up to that repo as an Admin user, [on purpose](#backup). <a id="cd"></a> You will also need a CLI window open with its working directory changed to a checkout directory of the Fossil repository you are setting up to send email. If you don't `cd` to such a checkout directory first, you'll need to add `-R /path/to/repo.fossil` to each `fossil` command below to tell Fossil which repository you mean it to apply the command to. There are other prerequisites for email service, but since they vary depending on the configuration you choose, we'll cover these inline below. <a id="quick"></a> ## Quick Email Service Setup If you've already got a working OpenSMTPD, Postfix, Exim, Sendmail, or similar server on the machine running your Fossil instance(s), and you aren't using Fossil's [chroot jail feature](./chroot.md) to wall Fossil off from the rest of the machine, it's fairly simple to set up email alerts. (Otherwise, skip [ahead](#advanced) to the sections on advanced email service setup.) This is our "quick setup" option even though setting up an SMTP mail server is not trivial, because there are many other reasons to have such |
| ︙ | ︙ |
Changes to www/build.wiki.
| ︙ | ︙ | |||
145 146 147 148 149 150 151 | want to make minor edits to Makefile.classic to configure the build for your system.</li> <li><i>MinGW / MinGW-w64</i> → The best-supported path is to build via the MinGW specific Makefile under a POSIX build of GNU make: "<b>make -f win/Makefile.mingw</b>".</li> | < < < < < < < < < < < < < < < < < | > | > > > > > > | > > > > | > | > > > | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | want to make minor edits to Makefile.classic to configure the build for your system.</li> <li><i>MinGW / MinGW-w64</i> → The best-supported path is to build via the MinGW specific Makefile under a POSIX build of GNU make: "<b>make -f win/Makefile.mingw</b>".</li> To enable the native [./th1.md#tclEval | Tcl integration feature], use a command line like the following (all on one line): <pre>make -f win/Makefile.mingw FOSSIL_ENABLE_TCL=1 FOSSIL_ENABLE_TCL_STUBS=1 FOSSIL_ENABLE_TCL_PRIVATE_STUBS=1</pre> <li><i>MSYS2 / Cygwin</i> → This is something of a hybrid between options "a" and "c" above: it configures and builds <code>fossil.exe</code> much as on Linux, but you get a native Windows executable out at the end. The primary downside is that this type of executable can become confused when attempting to interoperate with fully native Windows EXEs by making assumptions that only hold true when all elements are running under the Cygwin/MSYS environment. The MSVC and MinGW options do not have this limitation. Even so, there is value to Linux/Unix natives in having this hybrid while off in Windows-land. The simpler of the two paths is MSYS2, since it lets you install the necessary prerequisites in a single command after installing the base environment: <pre>pacman -sS gcc make openssl-devel zlib-devel</pre> The equivalent in Cygwin's <code>setup.exe</code> requires stepping through the GUI package chooser, and then if you miss one of the prereqs, going all the way back through it again until you get it right. <li><i>MSVC</i> → Use the MSVC makefile.</li> <em>NB:</em> Run the following <code>nmake</code> commands from a "x64 Native Tools Command Prompt"; <code>buildmsvc.bat</code> is able to automatically load the build tools (x64 by default, pass "x86" as the first argument to use the x86 tools), so it can be called from a normal command prompt. |
| ︙ | ︙ |
Changes to www/changes.wiki.
1 2 3 4 | <title>Change Log</title> <h2 id='v2_26'>Changes for version 2.26 (pending)</h2> | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 |
<title>Change Log</title>
<h2 id='v2_26'>Changes for version 2.26 (pending)</h2>
* Enhanced the --from option on "[/help?cmd=diff|fossil diff]" so that
it optionally accepts a directory name as its argument, and uses files
under that directory as the baseline for the diff.
* Added the [/help?cmd=/ckout|/ckout web page] to provide information
about pending changes in a working check-out
* The [/help?cmd=ui|fossil ui] command defaults to using the
[/help?cmd=/ckout|/ckout page] as its start page. Or, if the
"--from PATH" option is present, the default start page becomes
"/ckout?exbase=PATH".
* Added the [/help?cmd=merge-info|fossil merge-info] command and especially
the --tk option to that command, to provide analysis of the most recent
merge or update operation.
* Added the ability to sign check-ins with SSH keys.
* Issue a warning if a user tries to commit on a check-in where the
branch has been changed.
* When a merge conflict occurs, a new section is added to the conflict
text that shows Fossil's suggested resolution to the conflict.
* Add the "Hide diffs/Show diffs" toggle to web-UI diff pages that show
diffs of multiple files.
* Enhancements to the [/help?cmd=/timeline|/timeline page]:
<ol type="a">
<li> Added the "ml=" ("Merge-in List") query parameter that works
like "rl=" ("Related List") but adds "mionly" style related
check-ins instead of the full "rel" style.
<li> For "tl=", "rl=", and "ml=", the order of the branches in the
graph now tries to match the order of the branches named in
the list.
<li> The "ms=" ("Match Style") query parameter is honored for
"tl=", "rl=", and "ml=".
<li> New query parameter "sl=BRANCHLIST" ("Sort List") strives to
put branches in the specified order in the graph. This
overrides any "tl=" or similar ordering.
<li> In the various "from=","to=" query formats, if the one of the
end points is an ancestor of the other, then the "rel" modifier
omits check-ins that are not ancestors of the newer endpoint.
<li> For "tl=" and similar query parameters, if the pattern contains
GLOB characters, then the matching style ("ms=") is set to GLOB
automatically and the "ms=" query parameter can be omitted.
<li> Enhance the "ymd" query parameter so that when used like
"ymd=YYYYMMDD-YYYYMMDD" it shows all events in the range of
dates specified.
<li> Accept the "Z" (Zulu-time) suffix on date arguments for the
"ymd" and "yw" query parameters.
</ol>
* Add the "--if-changes" option to the [/help?cmd=commit|fossil commit]
command that causes the command to become a quiet no-op if there are
no pending changes.
* Added the [/help?cmd=/clusterlist|/clusterlist page] for analysis
and debugging
* Fix a bug in [/help?cmd=patch|fossil patch create] that causes
[/help?cmd=revert|fossil revert] operations that happened on individual
files after a [/help?cmd=merge|fossil merge] to be omitted from the
patch.
<h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
* The "[/help?cmd=ui|fossil ui /]" command now works even for repositories
that have non-ASCII filenames
* Add the [/help?cmd=tree|fossil tree] command.
* On case-insensitive filesystems, store files using the filesystem's
|
| ︙ | ︙ |
Changes to www/chroot.md.
1 2 3 4 5 | # The Server Chroot Jail If you run Fossil as root in any mode that [serves data on the network][srv], and you're running it on Unix or a compatible OS, Fossil will drop itself into a [`chroot(2)` jail][cj] shortly after starting | | | | < | | | > | | > | > | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# The Server Chroot Jail
If you run Fossil as root in any mode that [serves data on the
network][srv], and you're running it on Unix or a compatible OS, Fossil
will drop itself into a [`chroot(2)` jail][cj] shortly after starting
up. The usual reason for launching Fossil
as root to allow it to bind to TCP port 80 for HTTP
service, since normal users are restricted to ports 1024 and higher.
Fossil uses the owner of the Fossil repository file as its new user
ID when it drops root privileges.
When Fossil enters a chroot jail, it needs to have all of its dependencies
inside the chroot jail in order to continue work. There are several
resources that need to be inside the chroot jail with Fossil in order for
Fossil to work correctly:
* the repository file(s)
* `/dev/null` — create it with `mknod(8)` inside the jail directory
([Linux example][mnl], [OpenBSD example][obsd])
* `/dev/urandom` — ditto
* `/proc` — you might need to mount this virtual filesystem inside the
jail on Linux systems that make use of [Fossil’s server load
shedding feature][fls]
* any shared libraries your `fossil` binary is linked to, unless you
[configured Fossil with `--static`][bld] to avoid it
Fossil does all of this as one of many layers of defense against
hacks and exploits. You can prevent Fossil from entering the chroot
jail using the <tt>--nojail</tt> option to the
[fossil server command](/help?cmd=server)
but you cannot make Fossil hold onto root privileges. Fossil always drops
root privilege before accepting inputs, for security.
[bld]: https://fossil-scm.org/home/doc/trunk/www/build.wiki
[cj]: https://en.wikipedia.org/wiki/Chroot
[fls]: ./loadmgmt.md
[mnl]: https://fossil-scm.org/forum/forumpost/90caff30cb
[srv]: ./server/
[obsd]: ./server/openbsd/fastcgi.md#chroot
|
Changes to www/fossil-is-not-relational.md.
| ︙ | ︙ | |||
92 93 94 95 96 97 98 | Notably, the artifact file format <u>does not</u>... - Specify any specific storage mechanism for the SCM's raw bytes, which includes both artifacts themselves and client-side file content. The file format refers to all such content solely by its unique hash value. | | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | Notably, the artifact file format <u>does not</u>... - Specify any specific storage mechanism for the SCM's raw bytes, which includes both artifacts themselves and client-side file content. The file format refers to all such content solely by its unique hash value. - Specify any optimizations such as storing file-level changes as deltas between two versions of that content. Such aspects are all considered to be implementation details of higher-level applications (be they in the main fossil binary or a hypothetical 3rd-party application), and have no effect on the underlying artifact data model. That said, in Fossil: |
| ︙ | ︙ |
Changes to www/hooks.md.
| ︙ | ︙ | |||
114 115 116 117 118 119 120 |
a write-transaction on the repository when the before-commit
hook is running, so the repository needs to be in WAL mode if the
script needs to access the repository.
* The %A substitution is the name of a "commit description file" that
shows the details of the commit in progress. To see what a
"commit description file" looks like, set a before-commit hook
| | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
a write-transaction on the repository when the before-commit
hook is running, so the repository needs to be in WAL mode if the
script needs to access the repository.
* The %A substitution is the name of a "commit description file" that
shows the details of the commit in progress. To see what a
"commit description file" looks like, set a before-commit hook
with a command of "cat %A" and then run a sample commit with
the --dry-run option.
* If any before-commit hook returns a non-zero exit code, then
the commit is abandoned. All
before-commit hooks must exit(0) in order for the commit to
proceed.
|
| ︙ | ︙ |
Changes to www/inout.wiki.
| ︙ | ︙ | |||
38 39 40 41 42 43 44 | <h3>Converting Repositories on Windows</h3> The above commands work best on proper POSIX systems like Linux, macOS, and the BSDs, where everything <tt>git</tt> sends is consumed by <tt>fossil</tt> as soon as it can manage, with both programs working concurrently. | | > | | < | > | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | <h3>Converting Repositories on Windows</h3> The above commands work best on proper POSIX systems like Linux, macOS, and the BSDs, where everything <tt>git</tt> sends is consumed by <tt>fossil</tt> as soon as it can manage, with both programs working concurrently. Historically, PowerShell indiscriminately sent objects — as opposed to raw bytes — through its pipes, and buffered standard input for external processes. This made it choke on the conversion when the in-flight repository size exceeded available memory. Starting with version 7.4 (2023-11-16), PowerShell supports byte stream piping between native commands and file redirection. If you are stuck with an older version, one workaround is to fall back to <tt>cmd.exe</tt> — which doesn't seem to be affected by this problem. Nevertheless, we instead recommend using Microsoft's own [https://learn.microsoft.com/en-us/windows/wsl/ | Windows Subsystem for Linux] or either of the two popular "Git for Windows" distributions based on MSYS2. They handle pipes the POSIX way, avoiding any dependency on the amount of data involved. <h2>Fossil → Git</h2> |
| ︙ | ︙ |
Changes to www/mirrorlimitations.md.
| ︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 53 54 55 56 57 | check-in of each branch. Depending on the check-in graph topology, this is sufficient to infer the branch for many historical check-ins as well. However, complex histories with lots of cross-merging can lead to ambiguities. Fossil keeps track of historical branch names unambiguously, but the extra details about branch names that Fossil keeps at hand cannot be exported to Git. ## (4) Non-unique Tags Git requires tags to be unique: each tag must refer to exactly one check-in. Fossil does not have this restriction, and so it is common in Fossil to tag multiple check-ins with the same name. For example, it is common in Fossil to tag each check-in creating a release both | > > > > > > > > > > > > > > > > > > > | 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 73 74 75 76 | check-in of each branch. Depending on the check-in graph topology, this is sufficient to infer the branch for many historical check-ins as well. However, complex histories with lots of cross-merging can lead to ambiguities. Fossil keeps track of historical branch names unambiguously, but the extra details about branch names that Fossil keeps at hand cannot be exported to Git. An example of the kinds of ambiguities that arise when branch names are not tracked is a "diamond-merge" history. In a diamond-merge, a long-running development branch merges enhancements from trunk from time to time and also periodically merges the development changes back to trunk at moments when the branch is stable. An example of diamond-merge in the Fossil source tree itself can be seen at on the [bv-corrections01 branch](/timeline?r=bv-corrections01). The distinction between checkins on the branch and checkins on trunk would be lost in Git, which does not track branches for individual checkins, and so you cannot (easily) tell which checkins are part of the branch and which are part of trunk in a diamond-merge history on Git. For that reason, diamond-merge histories are considered an anti-pattern in Git and the usual recommendation for Git users is to employ [rebase](./rebaseharm.md) to clean the history up. The point here is that if your project has a diamond-merge history that shows up cleanly in Fossil, it will export to Git and still be technically correct, but the history display might be a jumbled mess that is difficult for humans to comprehend. ## (4) Non-unique Tags Git requires tags to be unique: each tag must refer to exactly one check-in. Fossil does not have this restriction, and so it is common in Fossil to tag multiple check-ins with the same name. For example, it is common in Fossil to tag each check-in creating a release both |
| ︙ | ︙ |
Changes to www/permutedindex.html.
| ︙ | ︙ | |||
103 104 105 106 107 108 109 110 111 112 113 114 115 116 | <li><a href="pop.wiki">Principles Of Operation</a></li> <li><a href="qandc.wiki">Questions And Criticisms</a></li> <li><a href="quotes.wiki">Quotes: What People Are Saying About Fossil, Git, and DVCSes in General</a></li> <li><a href="rebaseharm.md">Rebase Considered Harmful</a></li> <li><a href="reviews.wiki">Reviews</a></li> <li><a href="chroot.md">Server Chroot Jail</a></li> <li><a href="shunning.wiki">Shunning: Deleting Content From Fossil</a></li> <li><a href="../../../sitemap">Site Map</a></li> <li><a href="style.wiki">Source Code Style Guidelines</a></li> <li><a href="tech_overview.wiki">SQLite Databases Used By Fossil</a></li> <li><a href="ssl-server.md">SSL/TLS Server Mode</a></li> <li><a href="backoffice.md">The "Backoffice" mechanism of Fossil</a></li> <li><a href="patchcmd.md">The "fossil patch" Command</a></li> <li><a href="blame.wiki">The Annotate/Blame Algorithm Of Fossil</a></li> | > | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | <li><a href="pop.wiki">Principles Of Operation</a></li> <li><a href="qandc.wiki">Questions And Criticisms</a></li> <li><a href="quotes.wiki">Quotes: What People Are Saying About Fossil, Git, and DVCSes in General</a></li> <li><a href="rebaseharm.md">Rebase Considered Harmful</a></li> <li><a href="reviews.wiki">Reviews</a></li> <li><a href="chroot.md">Server Chroot Jail</a></li> <li><a href="shunning.wiki">Shunning: Deleting Content From Fossil</a></li> <li><a href="signing.md">Signing Check-ins</a></li> <li><a href="../../../sitemap">Site Map</a></li> <li><a href="style.wiki">Source Code Style Guidelines</a></li> <li><a href="tech_overview.wiki">SQLite Databases Used By Fossil</a></li> <li><a href="ssl-server.md">SSL/TLS Server Mode</a></li> <li><a href="backoffice.md">The "Backoffice" mechanism of Fossil</a></li> <li><a href="patchcmd.md">The "fossil patch" Command</a></li> <li><a href="blame.wiki">The Annotate/Blame Algorithm Of Fossil</a></li> |
| ︙ | ︙ |
Changes to www/selfhost.wiki.
1 2 | <title>Fossil Self-Hosting Repositories</title> | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <title>Fossil Self-Hosting Repositories</title> Fossil has self-hosted since 2007-07-21. As of 2025-02-11 there are three publicly accessible repositories for the Fossil source code: 1. [https://fossil-scm.org/] 2. [https://www2.fossil-scm.org/] 3. [https://www3.fossil-scm.org/] The canonical repository is (1). Repositories (2) and (3) automatically stay in synchronization with (1) via a <a href="http://en.wikipedia.org/wiki/Cron">cron job</a> that invokes "fossil sync" at regular intervals. Repository (2) also publishes a [https://github.com/drhsqlite/fossil-mirror|GitHub mirror of Fossil] as a demonstration of [./mirrortogithub.md|how that can be done]. Note that the two secondary repositories are more than just read-only mirrors. All three servers support full read/write capabilities. Changes (such as new tickets or wiki or check-ins) can be implemented on any of the three servers and those changes automatically propagate to the other two servers. Server (1) runs as a [./aboutcgi.wiki|CGI script] on a <a href="http://www.linode.com/">Linode</a> located in Dallas, TX - on the same virtual machine that hosts <a href="http://www.sqlite.org/">SQLite</a> and over a dozen other smaller projects. This demonstrates that Fossil can run on a low-power host processor. Multiple fossil-based projects can easily be hosted on the same machine, even if that machine is itself one of several dozen virtual machines on a single physical box. The CGI script that runs the canonical Fossil |
| ︙ | ︙ | |||
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | repository: /home/hwaci/fossil/fossil.fossil </pre> In recent years, virtual private servers have become a more flexible and less expensive hosting option compared to shared hosting accounts. So on 2017-07-25, server (3) was moved onto a $5/month "droplet" [https://en.wikipedia.org/wiki/Virtual_private_server|VPS] from [https://www.digitalocean.com|Digital Ocean] located in San Francisco. Server (3) is synchronized with the canonical server (1) by running a command similar to the following via cron: <pre> /usr/local/bin/fossil all sync -u </pre> Server (2) is a | > | | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | repository: /home/hwaci/fossil/fossil.fossil </pre> In recent years, virtual private servers have become a more flexible and less expensive hosting option compared to shared hosting accounts. So on 2017-07-25, server (3) was moved onto a $5/month "droplet" [https://en.wikipedia.org/wiki/Virtual_private_server|VPS] (update: $6/month now) from [https://www.digitalocean.com|Digital Ocean] located in San Francisco. Server (3) is synchronized with the canonical server (1) by running a command similar to the following via cron: <pre> /usr/local/bin/fossil all sync -u </pre> Server (2) is a <a href="http://www.linode.com/">Linode</a> located in Newark, NJ and set up just like the canonical server (1) with the addition of a cron job for synchronization. The same cron job also runs the [/help?cmd=git|fossil git export] command after each sync in order to [./mirrortogithub.md#ex1|mirror all changes to GitHub]. |
Added www/signing.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 73 74 75 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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# Signing Check-ins
Fossil can sign check-in manifests. A basic concept in public-key
cryptography, signing can bring some advantages such as authentication and
non-repudiation. In practice, a serious obstacle is the public key
infrastructure – that is, the problem of reliably verifying that a given
public key belongs to its supposed owner (also known as _"signing is easy,
verifying is hard"_).
Fossil neither creates nor verifies signatures by itself, instead relying on
external tools that have to be installed side-by-side. Historically, the tool
most employed for this task was [GnuPG](https://gnupg.org); recently, there has
been an increase in the usage of [OpenSSH](https://openssh.com) (the minimum
required version is 8.1, released on 2019-10-09).
## Signing a check-in
The `clearsign` setting must be on; this will cause every check-in to be signed
(unless you provide the `--nosign` flag to `fossil commit`). To this end,
Fossil calls the command given by the `pgp-command` setting.
Fossil needs a non-detached signature that includes the rest of the usual
manifest. For GnuPG, this is no problem, but as of 2025 (version 9.9p1) OpenSSH
can create **and verify** only detached signatures; Fossil itself must
attach this signature to the manifest prior to committing. This makes the
verification more complex, as additional steps are needed to extract the
signature and feed it into OpenSSH.
### GnuPG
The `pgp-command` setting defaults to
`gpg --clearsign -o`.
(A possible interesting option to `gpg --clearsign` is `-u`, to specify the
user to be used for signing.)
### OpenSSH
A reasonable value for `pgp-command` is
```
ssh-keygen -q -Y sign -n fossilscm -f ~/.ssh/id_ed25519
```
for Linux, and
```
ssh-keygen -q -Y sign -n fossilscm -f %USERPROFILE%/.ssh/id_ed25519
```
for Windows, changing as appropriate `-f` to the path of the private key to be
used.
The value for `-n` (the _namespace_) can be changed at will, but care has to be
taken to use the same value when verifying the signature.
## Verifying a signature
Fossil does not provide an internal method for verifying signatures and
relies – like it does for signing – on external tools.
### GnuPG
Assuming you used the
default GPG command for signing, one can verify the signature using
```
fossil artifact <CHECK-IN> | gpg --verify
```
### OpenSSH
The user and the key that was used to create the signature must be listed
together in the `ALLOWED_SIGNERS` file (see
[documentation](https://man.openbsd.org/ssh-keygen#ALLOWED_SIGNERS)).
Note that in that file, the "@DOMAIN" bit for the principal is only a
recommendation; you can (or even _should_) simply use your Fossil user name.
As mentioned, for lack of an OpenSSH built-in non-detached signature mechanism,
the burden of extracting the relevant part of the signed check-in is on the
user.
The following recipes are provided only as examples and can be easily extended
to fully-fledged scripts.
#### For Linux:
```bash
fsig=$(mktemp /tmp/__fsig.XXXXXX) && \
fusr=$(fossil artifact tip \
| awk -v m="${fsig}" -v s="${fsig}.sig" \
'/^-----BEGIN SSH SIGNED/{of=m;next} \
/^-----BEGIN SSH SIGNATURE/{of=s} \
/^U /{usr=$2} \
/./{if(!of){exit 42};print >> of} END{print usr}') && \
ssh-keygen -Y verify -f ~/.ssh/allowed_signers -I ${fusr} -n fossilscm \
-s "${fsig}.sig" < "${fsig}" || echo "No SSH signed check-in" && \
rm -f "${fsig}.sig" "${fsig}" && \
unset -v fsig fusr
```
#### For Windows (cmd):
The following incantation makes use of `awk` and `dos2unix`, standard Unix
tools but requiring separate installation on Windows (for example,using
[BusyBox](https://frippery.org/busybox/#downloads)). The usage of `awk` can be
replaced with the Windows basic tool `findstr`, leading to a longer recipe.
```bat
fossil artifact <CHECK-IN> | awk -v m="__fsig" -v s="__fsig.sig" ^
"/^-----BEGIN SSH SIGNED/{of=m;next} /^-----BEGIN SSH SIGNATURE/{of=s} /./{if(!of){exit 42};print >> of}"
if %errorlevel% equ 42 (echo No SSH signed check-in)
REM ---Skip remaining lines if no SSH signed message---
for /f "tokens=2" %i in ('findstr /b "U " __fsig') do set fusr=%i
dos2unix __fsig __fsig.sig
ssh-keygen -Y verify -f %USERPROFILE%\.ssh\allowed_signers -I "%fusr%" ^
-n fossilscm -s __fsig.sig < __fsig
del __fsig __fsig.sig 2>nul & set "fusr="
```
|
Changes to www/ssl-server.md.
| ︙ | ︙ | |||
10 11 12 13 14 15 16 | proxy that handled the SSL/TLS decryption/encryption and passed cleartext down to Fossil. [0]: ./ssl.wiki [1]: /timeline?c=b05cb4a0e15d0712&y=ci&n=13 Beginning in [late December 2021](/timeline?c=f6263bb64195b07f&y=a&n=13), | | | < < < < | | | < < < | | | > | | | > > | | > > > | > > > | > > | > | > > > > > > > > | < < < > > > > | > > | < | > > > > | > > > > > > > > | > > > < | > > > < < < > | > | | | | | > > | | | | > > > > > > > > | > > > > > > | > | > > > > > > | > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > < < < | > | | | | < < | > | | > | > > | > > | > > | > | | | > > | 10 11 12 13 14 15 16 17 18 19 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 73 74 75 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 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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 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 233 234 235 236 237 238 239 240 241 242 243 244 245 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 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
proxy that handled the SSL/TLS decryption/encryption and passed cleartext
down to Fossil.
[0]: ./ssl.wiki
[1]: /timeline?c=b05cb4a0e15d0712&y=ci&n=13
Beginning in [late December 2021](/timeline?c=f6263bb64195b07f&y=a&n=13),
Fossil servers are now able to converse directly over TLS. Commands like
* "[fossil server](/help?cmd=server)"
* "[fossil ui](/help?cmd=ui)", and
* "[fossil http](/help?cmd=http)"
may now handle the encryption natively when suitably configured, without
requiring a third-party proxy layer.
## <a id="usage"></a>Usage
To put any of the Fossil server commands into SSL/TLS mode, simply
add the "`--cert`" command-line option:
fossil ui --cert unsafe-builtin
Here, we are passing the magic name "unsafe-builtin" to cause Fossil to
use a [hard-coded self-signed cert][hcssc] rather than one obtained from
a recognized [Certificate Authority][CA], or "CA".
As the name implies, this self-signed cert is _not secure_ and should
only be used for testing. Your web browser is likely to complain
bitterly about it and will refuse to display the pages using the
"unsafe-builtin" cert until you placate it. The complexity of the
ceremony demanded depends on how paranoid your browser’s creators have
decided to be. It may require as little as clicking a single big "I know
the risks" type of button, or it may require a sequence be several
clicks designed to discourage the “yes, yes, just let me do the thing”
crowd lest they run themselves into trouble by disregarding well-meant
warnings.
Our purpose here is to show you an alternate path that will avoid the
issue entirely, not weigh in on which browser handles self-signed
certificates best.
[CA]: https://en.wikipedia.org/wiki/Certificate_authority
[hcssc]: /info/c2a7b14c3f541edb96?ln=89-116
## <a id="about"></a>About Certs
The X.509 certificate system used by browsers to secure TLS connections
is based on asymmetric public-key cryptography. The methods for
obtaining one vary widely, with a resulting tradeoff we may summarize as
trustworthiness versus convenience, the latter characteristic falling as
the former rises.(^No strict correlation exists. CAs have invented
highly inconvenient certification schemes that offer little additional
real-world trustworthiness. Extreme cases along this axis may be fairly
characterized as [security theater][st]. We focus in this document on
well-balanced trade-offs between decreasing convenience and useful
levels of trustworthiness gained thereby.)
The self-signed method demonstrated above offers approximately zero
trustworthiness, though not zero _value_ since it does still provide
connection encryption.
More trustworthy methods are necessarily less convenient. One such is to
send your public key and the name of the domain you want to protect to a
recognized CA, which then performs one or more tests to convince itself
that the requester is in control of that domain. If the CA’s tests all
pass, it produces an X.509 certificate bound to that domain, which
includes assorted other information under the CA’s digital signature
attesting to the validity of the document’s contents. The result is sent
back to the requester, which may then use it to transitively attest to
these tests’ success: presuming one cannot fake the type of signature
used, the document must have been signed by the trusted, recognized CA.
There is one element of the assorted information included with a
certificate that is neither supplied by the requester nor rubber-stamped
on it in passing by the CA. It also generates a one-time key pair and
stores the public half in the certificate. The cryptosystem this keypair
is intended to work with varies both by the CA and by time, as older
systems become obsolete. Details aside, the CA then puts this matching
private half of the key in a separate file, often encrypted under a
separate cryptosystem for security.
SSL/TLS servers need both resulting halves to make these attestations,
but they send only the public half to the client when establishing the
connection. The client then makes its own checks to determine whether it
trusts the attestations being made.
A properly written and administered server never releases the private
key to anyone. Ideally, it goes directly from the CA to the requesting
server and never moves from there; then when it expires, the server
deletes it permanently.
[st]: https://en.wikipedia.org/wiki/Security_theater
## <a id="startup"></a>How To Tell Fossil About Your Cert And Private Key
As we saw [above](#usage),
if you do not have your own cert and private key, you can ask Fossil
to use "unsafe-builtin", which is a self-signed cert that is built into
Fossil. This is wildly insecure, since the private key is not really private;
it is [in plain sight][hcssc] in the Fossil
source tree for anybody to read. <b>Never add the private key that is
built into Fossil to your OS's trust store</b> as doing so will severely
compromise your computer.[^ssattack] This built-in cert is only useful for testing.
If you want actual security, you will need to come up with your own private
key and cert.
Fossil wants to read certs and public keys in the
[PEM format](https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail).
PEM is a pure ASCII text format. The private key consists of text
like this:
-----BEGIN PRIVATE KEY-----
*base-64 encoding of the private key*
-----END PRIVATE KEY-----
Similarly, a PEM-encoded cert will look like this:
-----BEGIN CERTIFICATE-----
*base-64 encoding of the certificate*
-----END CERTIFICATE-----
In both formats, text outside of the delimiters is ignored. That means
that if you have a PEM-formatted private key and a separate PEM-formatted
certificate, you can concatenate the two into a single file, and the
individual components will still be easily accessible.
### <a id="cat"></a>Separate or Concatenated?
Given a single concatenated file that holds both your private key and your
cert, you can hand it off to the "[fossil server](/help?cmd=server)"
command using the `--cert` option, like this:
fossil server --port 443 --cert mycert.pem /home/www/myproject.fossil
The command above is sufficient to run a fully-encrypted web site for
the "myproject.fossil" Fossil repository. This command must be run as
root, since it wants to listen on TCP port 443, and only root processes are
allowed to do that. This is safe, however, since before reading any
information off of the wire, Fossil will [put itself inside a chroot
jail](./chroot.md) at `/home/www` and drop all root privileges.
This method of combining your cert and private key into a single big PEM
file carries risks, one of which is that the system administrator must
make both halves readable by the user running the Fossil server. Given
the chroot jail feature, a more secure scheme separates the halves so
that only root can read the private half, which then means that when
Fossil drops its root privileges, it becomes unable to access the
private key on disk. Fossil’s `server` feature includes the `--pkey`
option to allow for that use case:
fossil server --port 443 --cert fullchain.pem --pkey privkey.pem /home/www/myproject.fossil
[^ssattack]: ^How, you ask? Because the keys are known, they can be used
to provide signed certificates for **any** other domain. One foolish
enough to tell their OS’s TLS mechanisms to trust the signing
certificate is implicitly handing over all TLS encryption controls
to any attacker that knows they did this. Don’t do it.
### <a id="chain"></a>Chains and Links
The file name “`fullchain.pem`” used above is a reference to a term of
art within this world of TLS protocols and their associated X.509
certificates. Within the simplistic scheme originally envisioned by the
creators of SSL — the predecessor to TLS — we were all expected to agree
on a single set of CA root authorities, and we would all agree to get
our certificates from one of them. The real world is more complicated:
* The closest we have to universal acceptance of CAs is via the
[CA/Browser Forum][CAB], and even within its select membership there
is continual argument over which roots are trustworthy. (Hashing
that out is arguably this group’s key purpose.)
* CAB’s decision regarding trustworthiness may not match that of any
given system’s administrator. There are solid, defensible reasons to
prune back the stock CA root set included with your browser, then to
augment it with ones CAB _doesn’t_ trust.
* TLS isn’t limited to use between web browsers and public Internet
sites. Several common use cases preclude use of the process CAB
envisions, with servers able to contact Internet-based CA roots as
part of proving their identity. Different use cases demand different
CA root authority stores.
The most common of these divergent cases are servers behind strict
firewalls and edge devices that never interact with the public
Internet. This class ranges from cheap home IoT devices to the
internal equipment managed by IT for a massive global corporation.
Your private Fossil server is liable to fall into that last category.
This may then require that you generate a more complicated “chain” of
certificates for Fossil to use here, without which the client may not be
able to get back to a CA root it trusts. This is true regardless of
whether that client is another copy of Fossil or a web browser
traversing Fossil’s web UI, though that fact complicates matters by
allowing for multiple classes of client, each of which may have their
own rules for modifying the stock certificate scheme.
This is distressingly common, in fact: Fossil links to OpenSSL to
provide its TLS support, but there is a good chance that your browser
uses another TLS implementation entirely. They may or may not agree on a
single CA root store.
How you accommodate all this complexity varies by the CA and other
details. As but one example, Firefox’s “View Certificate” feature offers
_two_ ways to download a given web site’s certificate: the cert alone or
the “chain” leading back to the root. Depending on the use case, the
standalone certificate might suffice, or you might need some type of
cert chain. Complicating this is that the last link in the chain may be
left off when it is for a mutually trusted CA root, implicitly
completing the chain.
[CAB]: https://en.wikipedia.org/wiki/CA/Browser_Forum
## <a id="acme"></a>The ACME Protocol
The [ACME Protocol][2] simplifies all this by automating the process of
proving to a recognized public CA that you are in control of a given
website. Without this proof, no valid CA will issue a cert for that
domain, as that allows fraudulent impersonation.
The primary implementation of ACME is [certbot], a product of the Let’s
Encrypt organization.
Here is, in a nutshell, what certbot will do to obtain your cert:
1. It sends your "signing request" (the document that contains
your public key and your domain name) to the CA.
2. After receiving the signing request, the CA needs to verify that
you control the domain of the cert. One of several methods certbot has
for accomplishing this is to create a secret token and place it at
a well-known location, then tell the CA about it over ACME.
3. The CA then tries pulling that token, which if successful proves
that the requester is able to create arbitrary data on the server,
implicitly proving control over that server. This must be done
over the unencrypted HTTP protocol since TLS isn’t working yet.
4. If satisfied by this proof of control, the CA then creates the
keypair described above and bakes the public half into the
certificate it signs. It then sends this and the private half of
the key back to certbot.
5. Certbot stores these halves separately for the reasons sketched
out above.
6. It then deletes the secret one-time-use token it used to prove
domain control. ACME’s design precludes replay attacks.
In order for all of this to happen, certbot needs to be able to create
a subdirectory named ".well-known", within a directory you specify,
then populate that subdirectory with a token file of some kind. To support
this, the "[fossil server](/help?cmd=server)" and
"[fossil http](/help?cmd=http)" commands have the --acme option.
When specified, Fossil sees a URL where the path
begins with ".well-known", then instead of doing its normal processing, it
looks for a file with that pathname and returns it to the client. If
the "server" or "http" command is referencing a single Fossil repository,
then the ".well-known" sub-directory should be in the same directory as
the repository file. If the "server" or "http" command are run against
a directory full of Fossil repositories, then the ".well-known" sub-directory
should be in that top-level directory.
Thus, to set up a project website, you should first run Fossil in ordinary
unencrypted HTTP mode like this:
fossil server --port 80 --acme /home/www/myproject.fossil
Then you create your public/private key pair and run certbot, giving it
a --webroot of /home/www. Certbot will create the sub-directory
named "/home/www/.well-known" and put token files there, which the CA
will verify. Then certbot will store your new cert in a particular file.
Once certbot has obtained your cert, you may either pass the two halves
to Fossil separately using the `--pkey` and `--cert` options described
above, or you may concatenate them and pass that via `--cert` alone.
[2]: https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment
[certbot]: https://certbot.eff.org
|
Changes to www/sync.wiki.
| ︙ | ︙ | |||
787 788 789 790 791 792 793 794 795 796 797 798 799 800 | <li><b>ci-unlock</b> <i>CLIENT-ID</i> A client sends the "ci-unlock" pragma to the server after a successful commit. This instructs the server to release any lock on any check-in previously held by that client. The ci-unlock pragma helps to avoid false-positive lock warnings that might arise if a check-in is aborted and then restarted on a branch. </ol> <h3 id="comment">3.12 Comment Cards</h3> Any card that begins with "#" (ASCII 0x23) is a comment card and is silently ignored. | > > > > > > > > | 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 | <li><b>ci-unlock</b> <i>CLIENT-ID</i> A client sends the "ci-unlock" pragma to the server after a successful commit. This instructs the server to release any lock on any check-in previously held by that client. The ci-unlock pragma helps to avoid false-positive lock warnings that might arise if a check-in is aborted and then restarted on a branch. <li><b>req-clusters</b> A client sends the "req-clusters" pragma to the server to ask the server to reply with "igot" cards for every [./fileformat.wiki#cluster|cluster artifact] that it holds. The client typically does this when it thinks that it might be attempting to pull a long chain of cluster artifacts. Sending the artifacts all at once can dramatically reduce the number of round trip messages needed to complete the synchronization. </ol> <h3 id="comment">3.12 Comment Cards</h3> Any card that begins with "#" (ASCII 0x23) is a comment card and is silently ignored. |
| ︙ | ︙ |