Fossil

Check-in [1140b020de]
Login

Check-in [1140b020de]

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: 1140b020de296a7724c5d444f1bb73d96a666333b38111280efcf6f81c36a761
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
Unified Diff Ignore Whitespace Patch
Changes to Dockerfile.
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 aren't pinning to a more stable version of Alpine 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 basic Alpine Linux 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
### Alpine environment 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 ] ;                                             \







|







|











|





|
|
|







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
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
LIB += $(LIB.$(HOST_OS))

TCC.DragonFly += -DUSE_PREAD
TCC.FreeBSD += -DUSE_PREAD
TCC.NetBSD += -DUSE_PREAD
TCC.OpenBSD += -DUSE_PREAD
TCC += $(TCC.$(HOST_OS))







|







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
87
88
89
90
91
92
93
94
# 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 /bin/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







|







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
109
110
111
112
113
114
115
116
        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 -O2"]
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







|







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

235


236
237
238
239
240
241
242
    file delete ./conftest__
  }
  test_system_sqlite

}

proc is_mingw {} {

    return [string match *mingw* [get-define host]]


}

if {[is_mingw]} {
    define-append EXTRA_CFLAGS -DBROKEN_MINGW_CMDLINE
    define-append LIBS -lkernel32 -lws2_32
} else {
    #







>
|
>
>







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
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
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 "ssl 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 "ssl 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 ssl"
                    set cflags ""
                    set ldflags ""
                } else {
                    set msg "ssl in $dir"
                    set cflags "-I$dir/include"
                    set ldflags "-L$dir/lib"
                }
                if {[check-for-openssl $msg "$cflags $ldflags"]} {
                    incr found
                    break









                }
            }
        }
    }
    if {$found} {
        define FOSSIL_ENABLE_SSL
        define-append EXTRA_CFLAGS $cflags







|



|
















|



|






>
>
>
>
>
>
>
>
>







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
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
    #
    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
}

# Emscripten is a purely optional component used only for doing
# in-tree builds of WASM stuff, as opposed to WASM binaries we import
# from other places. This is only set up for Unix-style OSes and is
# untested anywhere but Linux.
set emsdkHome [opt-val with-emsdk]
define EMSDK_HOME ""
define EMSDK_ENV ""
define EMCC_OPT "-Oz"
if {$emsdkHome eq "" && [info exists ::env(EMSDK)]} {
  # Fall back to checking the environment. $EMSDK gets set
  # by sourcing emsdk_env.sh.
  set emsdkHome $::env(EMSDK)
}
if {$emsdkHome ne ""} {
  define EMSDK_HOME $emsdkHome
  set emsdkEnv "$emsdkHome/emsdk_env.sh"
  if {[file exists $emsdkEnv]} {
    puts "Using Emscripten SDK environment from $emsdkEnv."
    define EMSDK_ENV $emsdkEnv
    if {[info exists ::env(EMCC_OPT)]} {
      define EMCC_OPT $::env(EMCC_OPT)
    }
  } else {
    puts "emsdk_env.sh not found. Assuming emcc is in the PATH."
  }
}

# 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
    }
}




# 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







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








>
>
>







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
749
750
751
752
753
754
755
756
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







|







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



































841



































842

843
844
845
846

847
848
849
850
851
852
853
}
if {[opt-bool static]} {
    # Linux can only infer the dependency on pthread from OpenSSL when
    # doing dynamic linkage.
    define-append LIBS -lpthread
}




































if {[get-define EMSDK_HOME] ne ""} {



































  define EMCC_WRAPPER $::autosetup(dir)/../tools/emcc.sh

  make-template tools/emcc.sh.in
  catch {exec chmod u+x tools/emcc.sh}
} else {
  define EMCC_WRAPPER ""

  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







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>




>







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
462
463
464
465
466
467
468
469
470
471
472
    /* 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;
#ifndef SQLITE_USE_STDIO_FOR_CONSOLE
    DWORD nRead = 0;
    if( IsConsole(in)
     && ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz, &nRead, 0)
    ){
      b1[nRead] = 0;
    }else
#endif
    {
      _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
      if( fgetws(b1, sz/4, in)==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
540
541
542
543
544
545
546
547
548
549

550
551
552
553
554
555
556
557
558
    */
    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;

#ifndef SQLITE_STDIO_FOR_CONSOLE
    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
    {

      /* For non-console I/O, or if SQLITE_USE_STDIO_FOR_CONSOLE is defined
      ** then write using the standard library. */
      _setmode(_fileno(out), _O_U8TEXT);
      if( UseBinaryWText(out) ){
        piecemealOutput(b1, sz, out);
      }else{
        fputws(b1, out);
      }
    }







|









>
|
|







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
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
    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;
      case WS:
        /* Treat whitespace as pad and terminate this group.*/
        nti = nac;
        deliberate_fall_through;
      case PC:
        bdp = 0;
        --nbo;
        deliberate_fall_through;
      default: /* bdp is the digit value. */
        qv = qv<<6 | bdp;
        break;
      }
    }
    switch( nbo ){
    case 3:
      pOut[2] = (qv) & 0xff;

    case 2:
      pOut[1] = (qv>>8) & 0xff;

    case 1:
      pOut[0] = (qv>>16) & 0xff;

    }
    pOut += nbo;
  }
  return pOut;
}

/* This function does the work for the SQLite base64(x) UDF. */







|



|



|








>


>


>







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
7697

7698
7699
7700
7701
7702
7703
7704
  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(ReCompiled *pRe){

  if( pRe ){
    sqlite3_free(pRe->aOp);
    sqlite3_free(pRe->aArg);
    sqlite3_free(pRe);
  }
}








|
>







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
8363
8364
8365
8366
8367
8368
8369
8370
    LONGLONG intervals;
    HANDLE hFile;
    LPWSTR zUnicodeName;
    extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);

    GetSystemTime(&currentTime);
    SystemTimeToFileTime(&currentTime, &lastAccess);
    intervals = Int32x32To64(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(







|







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(&currentTime);
    SystemTimeToFileTime(&currentTime, &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










17005











17006
17007
17008
17009
17010
17011
17012
  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;
}
























/*
** Open an vfstrace file handle.
*/
static int vfstraceOpen(
  sqlite3_vfs *pVfs,







>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>







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
17167
17168
17169
17170
17171
17172
17173
17174
/*
** 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.xDlOpen()\n", pInfo->zVfsName);
  pRoot->xDlClose(pRoot, pHandle);
}

/*
** Populate the buffer pointed to by zBufOut with nByte bytes of 
** random data.
*/







|







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
27465
27466
27467
27468
27469
27470
27471
27472
      pAr->bGlob = 1;
      break;
    case AR_SWITCH_VERBOSE:
      pAr->bVerbose = 1;
      break;
    case AR_SWITCH_APPEND:
      pAr->bAppend = 1;
      deliberate_fall_through;
    case AR_SWITCH_FILE:
      pAr->zFile = zArg;
      break;
    case AR_SWITCH_DIRECTORY:
      pAr->zDir = zArg;
      break;
  }







|







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

30261
30262
30263
30264
30265
30266
30267
30268
#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 ){

          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(







>












>
|







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
32153
32154
32155
32156
32157
32158
32159
32160
          CONTINUE_PROMPT_AWAITS(pst, "/*");
          qss = QSS_SETV(qss, cWait);
          goto TermScan;
        }
        break;
      case '[':
        cin = ']';
        deliberate_fall_through;
      case '`': case '\'': case '"':
        cWait = cin;
        qss = QSS_HasDark | cWait;
        CONTINUE_PROMPT_AWAITC(pst, cin);
        goto TermScan;
      case '(':
        CONTINUE_PAREN_INCR(pst, 1);







|







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
32188
32189
32190
32191
32192
32193
32194
32195
          goto PlainScan;
        case '`': case '\'': case '"':
          if(*zLine==cWait){
            /* Swallow doubled end-delimiter.*/
            ++zLine;
            continue;
          }
          deliberate_fall_through;
        case ']':
          CONTINUE_PROMPT_AWAITC(pst, 0);
          qss = QSS_SETV(qss, 0);
          goto PlainScan;
        default: assert(0);
        }
      }







|







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
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.48.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
** e2bae4143afd07de1ae55a6d2606a3b541a5 with changes in files:
**
**    
*/
#ifndef SQLITE_AMALGAMATION
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
#ifndef SQLITE_PRIVATE


|

















|







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
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.48.0"
#define SQLITE_VERSION_NUMBER 3048000
#define SQLITE_SOURCE_ID      "2024-12-09 20:46:36 e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653"

/*
** 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







|
|
|







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
2311
2312
2313
2314
2315
2316
2317



2318
2319
2320
2321
2322
2323
2324
** 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 and the second is the number of
** slots allocated to each database connection.)^  ^(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.)^ </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>
**







|

|
|
|
|
|
>
>
>







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


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
#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 argument to the [sqlite3_db_config()] interface.






**
** 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> ^This option takes three additional arguments that determine the
** [lookaside memory allocator] configuration for the [database connection].







** ^The first argument (the third parameter to [sqlite3_db_config()] is a
** pointer to a memory buffer to use for lookaside memory.
** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
** may be NULL in which case SQLite will allocate the
** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the

** size of each lookaside buffer slot.  ^The third argument is the number of










** slots.  The size of the buffer in the first argument must be greater than
** or equal to the product of the second and third arguments.  The buffer
** must be aligned to an 8-byte boundary.  ^If the second argument to
** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally
** rounded down to the next smaller multiple of 8.  ^(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 "current value" returned by
** [sqlite3_db_status](D,[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].)^</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].  There should be two additional arguments.

** 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>
**







>
>
|
>
>
>
>
>
>











|
|
>
>
>
>
>
>
>
|

<
|
|
>
|
>
>
>
>
>
>
>
>
>
>
|
|
|
<
|


<
|


|
>
>
>
>
>
>
>
>
>
>




|
>







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
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
2647
2648
2649
2650
2651
2652
2653
2654
2655

2656
2657

2658

2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
** 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 should 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 should 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 should 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.  ^The sole argument is 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 this DBCONFIG option 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 this will mean that there are now no

** connections at all to the database. If so, it performs a checkpoint
** operation before closing the connection. This option may be used to

** override this behavior. The first parameter passed to this operation

** is an integer - positive to disable checkpoints-on-close, or zero (the
** default) to enable them, and 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 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,







|





|


















|














|













>
>
>
>
|
|
|
|
|




|
|
>
|
|
>
|
>
|
|
|







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
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
** <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.  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].  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>
**


















































** </dl>



















*/
#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* */







|













|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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



2867
2868
2869
2870
2871
2872
2873
2874
#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_MAX                   1019 /* 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







>
>
>
|







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
11070
11071

11072
11073
11074
11075
11076
11077
11078
** [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 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.







|
|
>







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
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
  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: Upgrade the Schema of a Changeset/Patchset
*/
SQLITE_API int sqlite3changeset_upgrade(
  sqlite3 *db,
  const char *zDb,
  int nIn, const void *pIn,       /* Input changeset */
  int *pnOut, void **ppOut        /* OUT: Inverse of input */
);



/*
** CAPI3REF: Changegroup Handle
**
** A changegroup is an object used to combine two or more
** [changesets] or [patchsets]
*/







<
<
<
<
<
<
<
<
<
<
<
<
<







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
14053
14054
14055
14056
14057
14058
14059
14060
*/
#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
# define SQLITE_MAX_FUNCTION_ARG 127
#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,







>
>
>
>


|







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

14876
14877
14878
14879
14880
14881
14882
14883
#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_ILLEGAL                        185

/************** End of parse.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>







>
|







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
15398
15399
15400
15401
15402
15403
15404
15405
15406
15407
15408
15409
15410
15411
15412
15413
15414
15415
15416


15417
15418
15419
15420
15421
15422
15423
**
** (---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
** 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()


*/


/*
** An instance of the following structure is used to store the busy-handler
** callback for a given sqlite handle.
**







|


















>
>







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
18118
18119
18120
18121
18122
18123
18124
18125
** 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 {
  i8 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 */







|







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
19411
19412
19413
19414
19415
19416
19417
19418
19419
19420
19421
19422
19423
19424
**
**     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 */
  u8 eU4;          /* Which element of a.u4 is valid */
  struct IdList_item {
    char *zName;      /* Name of the identifier */
    union {
      int idx;          /* Index in some Table.aCol[] of a column named zName */
      Expr *pExpr;      /* Expr to implement a USING variable -- NOT USED */
    } u4;
  } a[1];
};

/*
** Allowed values for IdList.eType, which determines which value of the a.u4
** is valid.
*/







<


<
<
<
<







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
20013
20014
20015
20016
20017
20018
20019
20020
20021
20022
20023
20024
20025




20026
20027
20028
20029
20030


20031




20032
20033
20034
20035
20036
20037
20038
20039
20040
20041
20042
20043
20044
20045
20046
20047
20048
20049
20050
20051
20052
20053
20054
20055
20056
20057
20058
20059
20060
20061
20062
20063
20064
20065
20066
20067
20068
20069
20070
20071
20072
20073
20074
20075
20076
20077
20078
20079
20080
20081
20082
20083
20084
20085
20086













20087
20088
20089
20090
20091
20092
20093
20094
20095
20096
20097
20098
20099
20100
20101
20102
20103
20104
20105
20106
20107
20108
20109
20110
20111
20112
20113
** 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 */
  u8 colNamesSet;      /* TRUE after OP_ColumnName has been issued to pVdbe */
  u8 checkSchema;      /* Causes schema cookie check after an error */
  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 okConstFactor;    /* OK to factor out constants */
  u8 disableLookaside; /* Number of times lookaside has been disabled */
  u8 prepFlags;        /* SQLITE_PREPARE_* flags */
  u8 withinRJSubrtn;   /* Nesting level for RIGHT JOIN body subroutines */
  u8 bHasWith;         /* True if statement contains WITH */
  u8 mSubrtnSig;       /* mini Bloom filter on available SubrtnSig.selId */




#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 */


#endif




  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 */
  Token constraintName;/* Name of the constraint currently being parsed */
  yDbMask writeMask;   /* Start a write transaction on these databases */
  yDbMask cookieMask;  /* Bitmask of schema verified databases */
  int regRowid;        /* Register holding rowid of CREATE TABLE entry */
  int regRoot;         /* Register holding root page number for new objects */
  int nMaxArg;         /* Max args passed to user function by sub-program */
  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 */
  union {
    int addrCrTab;         /* Address of OP_CreateBtree on CREATE TABLE */
    Returning *pReturning; /* The RETURNING clause */
  } u1;
  u32 oldmask;         /* Mask of old.* columns referenced */
  u32 newmask;         /* Mask of new.* columns referenced */
  LogEst nQueryLoop;   /* Est number of iterations of a query (10*log2(N)) */
  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 */

  /**************************************************************************
  ** 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 */














  /************************************************************************
  ** 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 */
#ifndef SQLITE_OMIT_EXPLAIN
  int addrExplain;          /* Address of current OP_Explain opcode */
#endif
  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 */







|
<





<



<

>
>
>
>





>
>

>
>
>
>














<


<
<
|













<
<
<
<
<
<
<
<
<
<
<











>
>
>
>
>
>
>
>
>
>
>
>
>

















<

<







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
23713
23714
23715
23716
23717
23718
23719
23720
23721
23722
23723
23724
23725
23726
23727
  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 */
  u8 argc;                /* Number of arguments */
  sqlite3_value *argv[1]; /* Argument set */
};

/* 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 */

/* 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







|



<
<
<
<







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
23781
23782
23783
23784
23785
23786
23787
23788
23789
23790
23791
23792
23793
23794
23795
23796
23797
23798
23799
23800

23801
23802
23803
23804
23805
23806
23807
  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 to currently executing user function */
  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 */

#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 */







|



















>







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
25869
25870
25871
25872
25873
25874
25875
25876
      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( 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;
      }







|







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
32429
32430
32431
32432
32433
32434
32435
32436
** 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, p->nChar+1 );
  if( zText ){
    memcpy(zText, p->zText, p->nChar+1);
    p->printfFlags |= SQLITE_PRINTF_MALLOCED;
  }else{
    sqlite3StrAccumSetError(p, SQLITE_NOMEM);
  }
  p->zText = zText;







|







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

33037


33038
33039
33040
33041
33042
33043
33044
    if( pItem->fg.jointype & JT_LTORJ ){
      sqlite3_str_appendf(&x, " LTORJ");
    }
    if( pItem->fg.fromDDL ){
      sqlite3_str_appendf(&x, " DDL");
    }
    if( pItem->fg.isCte ){

      sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse);


    }
    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");







>
|
>
>







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
33068
33069
33070
33071
33072
33073
33074
33075
33076
33077
    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) );
      sqlite3TreeViewPush(&pView, 0);
      sqlite3TreeViewLine(pView, "SUBQUERY");
      sqlite3TreeViewPop(&pView);
      sqlite3TreeViewSelect(pView, pItem->u4.pSubq->pSelect, 0);
    }
    if( pItem->fg.isTabFunc ){
      sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:");
    }
    sqlite3TreeViewPop(&pView);
  }







<
<
<







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
33800
33801
33802
33803
33804
33805
33806
33807
33808
33809
33810
33811
33812
33813
33814
33815
33816
33817
33818
33819
33820
33821
    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);
      if( pList->eU4==EU4_NONE ){
        fprintf(stdout, "%s\n", zName);
      }else if( pList->eU4==EU4_IDX ){
        fprintf(stdout, "%s (%d)\n", zName, pList->a[i].u4.idx);
      }else{
        assert( pList->eU4==EU4_EXPR );
        if( pList->a[i].u4.pExpr==0 ){
          fprintf(stdout, "%s (pExpr=NULL)\n", zName);
        }else{
          fprintf(stdout, "%s\n", zName);
          sqlite3TreeViewPush(&pView, i<pList->nId-1);
          sqlite3TreeViewExpr(pView, pList->a[i].u4.pExpr, 0);
          sqlite3TreeViewPop(&pView);
        }
      }
      sqlite3TreeViewPop(&pView);
    }
  }
}
SQLITE_PRIVATE void sqlite3TreeViewIdList(
  TreeView *pView,
  const IdList *pList,







<
|
<
<
<
<
<
<
<
<
<
<
<
<
<







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

36295



36296
36297
36298
36299
36300
36301
36302
          j--;
        }
      }
    }
  }
  p->z = &p->zBuf[i+1];
  assert( i+p->n < sizeof(p->zBuf) );

  while( ALWAYS(p->n>0) && p->z[p->n-1]=='0' ){ p->n--; }



}

/*
** 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.







>
|
>
>
>







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
37081
37082
37083
37084
37085





37086



37087
37088
37089
37090
37091
37092
37093
}

/*
** The hashing function.
*/
static unsigned int strHash(const char *z){
  unsigned int h = 0;
  unsigned char c;
  while( (c = (unsigned char)*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. */





    h += sqlite3UpperToLower[c];



    h *= 0x9e3779b1;
  }
  return h;
}


/* Link pNew element into the hash table pH.  If pEntry!=0 then also







<
|


|
>
>
>
>
>
|
>
>
>







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
37159
37160
37161
37162
37163
37164
37165
37166
37167
37168
37169
37170
37171
37172
37173
37174
37175
37176
37177
37178
37179
37180

37181
37182
37183
37184
37185
37186
37187
37188
37189
37190
37191
37192
37193
37194
37195
37196
37197
37198
37199
37200
37201
37202
37203
37204
37205
37206
37207
37208
37209
37210
37211
37212
37213
37214
37215
37216
37217
37218
37219
37220
37221
37222
37223
37224
37225
37226
37227
37228
37229

  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){
    unsigned int h = strHash(elem->pKey) % new_size;
    next_elem = elem->next;
    insertElement(pH, &new_ht[h], 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 };


  if( pH->ht ){   /*OPTIMIZATION-IF-TRUE*/
    struct _ht *pEntry;
    h = strHash(pKey) % pH->htsize;
    pEntry = &pH->ht[h];
    elem = pEntry->chain;
    count = pEntry->count;
  }else{
    h = 0;
    elem = pH->first;
    count = pH->count;
  }
  if( pHash ) *pHash = h;
  while( count ){
    assert( elem!=0 );
    if( 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 removeElementGivenHash(
  Hash *pH,         /* The pH containing "elem" */
  HashElem* elem,   /* The element to be removed from the pH */
  unsigned int h    /* Hash value for the element */
){
  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[h];
    if( pEntry->chain==elem ){
      pEntry->chain = elem->next;
    }
    assert( pEntry->count>0 );
    pEntry->count--;
  }
  sqlite3_free( 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
37273
37274
37275
37276
37277
37278
37279
37280
37281
37282
37283

37284
37285
37286
37287
37288
37289
37290
37291
37292
37293
37294
37295
37296
37297
37298
37299

  assert( pH!=0 );
  assert( pKey!=0 );
  elem = findElementWithHash(pH,pKey,&h);
  if( elem->data ){
    void *old_data = elem->data;
    if( data==0 ){
      removeElementGivenHash(pH,elem,h);
    }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->data = data;
  pH->count++;
  if( pH->count>=10 && pH->count > 2*pH->htsize ){
    if( rehash(pH, pH->count*2) ){
      assert( pH->htsize>0 );
      h = strHash(pKey) % pH->htsize;
    }
  }
  insertElement(pH, pH->ht ? &pH->ht[h] : 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. */







|










>


|
|
<
<
|
<
|







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
40155
40156
40157
40158
40159
40160
40161
40162
  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 );
      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;







|







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
50703
50704
50705
50706
50707
50708
50709
50710

  /* 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) + 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);







|







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
51524
51525
51526
51527
51528
51529
51530
51531
51532
51533
51534
51535
51536

51537
51538
51539
51540
51541
51542
51543
  static char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789";
  size_t i, j;
  DWORD pid;
  int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
  int 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 = nMax + 2;

  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







|











|
>







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
52395
52396
52397
52398
52399
52400
52401
52402
  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( pVfs->mxPathname+1 );
    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);







|







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
52490
52491
52492
52493
52494
52495
52496
52497
52498
52499
52500
52501
52502
52503
52504
52505
52506
52507
52508
52509
52510
52511
52512
52513
52514
52515
52516
52517
52518
52519
52520
52521
52522
52523
52524
52525
52526
52527
52528
52529
    LPWSTR zTemp;
    nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
    if( nByte==0 ){
      sqlite3_free(zConverted);
      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
                         "winFullPathname1", zRelative);
    }
    nByte += 3;
    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
    if( zTemp==0 ){
      sqlite3_free(zConverted);
      return SQLITE_IOERR_NOMEM_BKPT;
    }
    nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, 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);
    }
    nByte += 3;
    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
    if( zTemp==0 ){
      sqlite3_free(zConverted);
      return SQLITE_IOERR_NOMEM_BKPT;
    }
    nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
    if( nByte==0 ){
      sqlite3_free(zConverted);
      sqlite3_free(zTemp);
      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
                         "winFullPathname4", zRelative);
    }
    sqlite3_free(zConverted);







<
|




|



















<
|




|







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
53551
53552
53553
53554
53555
53556
53557
53558
53559
53560
53561
53562
53563
53564
      if( strcmp(memdb_g.apMemStore[i]->zFName,zName)==0 ){
        p = memdb_g.apMemStore[i];
        break;
      }
    }
    if( p==0 ){
      MemStore **apNew;
      p = sqlite3Malloc( sizeof(*p) + szName + 3 );
      if( p==0 ){
        sqlite3_mutex_leave(pVfsMutex);
        return SQLITE_NOMEM;
      }
      apNew = sqlite3Realloc(memdb_g.apMemStore,
                             sizeof(apNew[0])*(memdb_g.nMemStore+1) );
      if( apNew==0 ){
        sqlite3_free(p);
        sqlite3_mutex_leave(pVfsMutex);
        return SQLITE_NOMEM;
      }
      apNew[memdb_g.nMemStore++] = p;
      memdb_g.apMemStore = 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
54267
54268
54269
54270
54271
54272
54273
54274
  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( (sz+7)/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);








|







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
55814
55815
55816
55817
55818
55819
55820
55821
55822
55823
55824
55825
55826
** 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;
  unsigned int nNew;
  unsigned int i;

  assert( sqlite3_mutex_held(p->pGroup->mutex) );

  nNew = p->nHash*2;
  if( nNew<256 ){
    nNew = 256;
  }

  pcache1LeaveMutex(p->pGroup);
  if( p->nHash ){ sqlite3BeginBenignMalloc(); }
  apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);







|
|



|







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
56042
56043
56044
56045
56046
56047
56048
56049
** 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 */
  int 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 ){







|







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
58019
58020
58021
58022
58023
58024
58025
58026
58027
58028
58029
58030
58031
58032
58033
58034
58035
58036
58037
58038
58039
58040
58041
58042
58043
58044
58045
58046
58047
58048
58049
58050
58051
58052
58053
58054
58055
58056
58057
58058
58059
*/
#if SQLITE_MAX_MMAP_SIZE>0
# define USEFETCH(x) ((x)->bUseFetch)
#else
# define USEFETCH(x) 0
#endif

/*
** 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)

#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);
    return iRead==0; /* Condition (4) */
  }
#endif
  assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
  if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
        & SQLITE_IOCAP_SUBPAGE_READ)==0 ){
    return 0; /* Case (2) */
  }







<
<
<
<
<
<
<
<
<
<
<
<
<
<



















|







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
58535
58536
58537
58538
58539
58540
58541
58542
**
** 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, u32 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';







|







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
59318
59319
59320
59321
59322
59323
59324
59325
          ** 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







|







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
59771
59772
59773
59774
59775
59776
59777
59778
59779
59780
59781
59782
59783
59784
59785
59786
59787
59788
59789
59790
59791
59792
59793
59794

59795
59796
59797
59798


59799
59800
59801
59802
59803
59804
59805
  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 */
  int 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(pVfs->szOsFile * 2);
  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 = pVfs->mxPathname+1;

  zFree = sqlite3Malloc(4 + nSuperJournal + nSuperPtr + 2);
  if( !zFree ){
    rc = SQLITE_NOMEM_BKPT;
    goto delsuper_out;


  }
  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;







|




|

















|
>




>
>







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
60059
60060
60061
60062
60063
60064
60065
60066
  ** 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, pPager->pVfs->mxPathname+1);
  if( rc==SQLITE_OK && zSuper[0] ){
    rc = sqlite3OsAccess(pVfs, zSuper, SQLITE_ACCESS_EXISTS, &res);
  }
  zSuper = 0;
  if( rc!=SQLITE_OK || !res ){
    goto end_playback;
  }







|







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
60198
60199
60200
60201
60202
60203
60204
60205

  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, pPager->pVfs->mxPathname+1);
    testcase( rc!=SQLITE_OK );
  }
  if( rc==SQLITE_OK
   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
  ){
    rc = sqlite3PagerSync(pPager, 0);
  }







|







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
61994
61995
61996
61997
61998
61999
62000
62001
62002

  /* 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, nPathname*2);
    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 ){







|
|







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
62082
62083
62084
62085
62086
62087
62088
62089
62090
62091
62092
62093
62094
62095
62096
  ** 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 */
    journalFileSize * 2 +                /* The two journal files */
    SQLITE_PTRSIZE +                     /* Space to hold a pointer */
    4 +                                  /* Database prefix */
    nPathname + 1 +                      /* database filename */
    nUriByte +                           /* query parameters */
    nPathname + 8 + 1 +                  /* Journal filename */
#ifndef SQLITE_OMIT_WAL
    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;







|


|
|
|

|







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
65795
65796
65797
65798
65799
65800
65801
65802
  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*)*(iPage+1);
    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,







|







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
68028
68029
68030
68031
68032
68033
68034
68035
68036
68037
68038
68039
** 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 */
  u32 mxReadMark;                 /* Largest aReadMark[] value */
  int mxI;                        /* Index of largest aReadMark[] value */
  int i;                          /* Loop counter */
  int rc = SQLITE_OK;             /* Return code  */
  u32 mxFrame;                    /* Wal frame to lock to */
#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 */







<
<
<

<







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





68138
68139
68140
68141
68142
68143
68144
68145
68146
68147
68148
68149
68150
68151
68152
68153
68154
68155
68156
68157
68158
68159
68160
68161
68162
68163
68164
68165
68166
68167
68168
68169
68170
68171
68172
68173
68174
68175
68176
68177
68178
68179
68180
68181
68182
68183
68184
68185
68186
68187
68188
68189
68190
68191
68192
68193
68194
68195
68196
68197
68198
68199
68200
68201
68202
68203
68204
68205
68206
68207
68208
68209
68210
68211
68212
68213
68214
68215
68216
68217
68218
68219
68220
68221
68222
68223
68224
68225
68226
68227
68228
68229
68230
68231
68232
68233
68234
68235
68236
68237
68238
68239
68240
68241
68242
68243
68244
68245
68246
68247
68248
68249
68250
68251
68252
68253
68254
68255
68256
68257
68258
68259
68260
68261
68262
68263
68264
68265
68266
68267
68268
68269
68270
68271
68272

68273
68274
68275
68276
68277
68278
68279
    }
  }

  assert( pWal->nWiData>0 );
  assert( pWal->apWiData[0]!=0 );
  pInfo = walCkptInfo(pWal);
  SEH_INJECT_FAULT;





  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().







>
>
>
>
>
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|

|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|

|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>







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
71417
71418
71419
71420
71421
71422
71423
71424
    ** 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( 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);







|







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
76788
76789
76790
76791
76792
76793
76794
76795
        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( nCell+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 */







|







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
83279
83280
83281
83282
83283
83284
83285
83286
*/
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;
  if( NEVER(pMem->z==0) ) return;
  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;







|







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

83998
83999
84000
84001
84002
84003
84004
84005
84006
84007
84008
84009
84010
84011
84012
84013
84014
84015
84016
84017
84018


84019
84020
84021
84022
84023
84024
84025
**
** 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;

  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->pScopyFrom = 0;
}
#endif /* SQLITE_DEBUG */

/*
** Make an shallow copy of pFrom into pTo.  Prior contents of







>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
>
>







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
84389
84390
84391
84392
84393
84394
84395
84396
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 */
      int 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);







|







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
84455
84456
84457
84458
84459
84460
84461
84462
  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;                   /* Size of apVal[] array */
  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 );







|







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
85734
85735
85736
85737
85738
85739
85740
85741
    p->iAddr++;
    if( p->iAddr==nOp ){
      p->iSub++;
      p->iAddr = 0;
    }

    if( pRet->p4type==P4_SUBPROGRAM ){
      int nByte = (p->nSub+1)*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 ){







|







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
85864
85865
85866
85867
85868
85869
85870
85871
85872
85873
85874
85875
85876
85877
85878
85879
85880
85881
85882
85883
85884
85885
85886
/*
** 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 any SQL function
**     and store that value in *pMaxFuncArgs.
**
** (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 *pMaxFuncArgs){
  int nMaxArgs = *pMaxFuncArgs;
  Op *pOp;
  Parse *pParse = p->pParse;
  int *aLabel = pParse->aLabel;

  assert( pParse->db->mallocFailed==0 ); /* tag-20230419-1 */
  p->readOnly = 1;
  p->bIsReader = 0;







|
|












|
|







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
85924
85925
85926
85927
85928



85929
85930

85931
85932
85933
85934
85935
85936
85937
85938
85939
        }
        case OP_Init: {
          assert( pOp->p2>=0 );
          goto resolve_p2_values_loop_exit;
        }
#ifndef SQLITE_OMIT_VIRTUALTABLE
        case OP_VUpdate: {
          if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
          break;
        }
        case OP_VFilter: {
          int n;



          assert( (pOp - p->aOp) >= 3 );
          assert( pOp[-1].opcode==OP_Integer );

          n = pOp[-1].p1;
          if( n>nMaxArgs ) nMaxArgs = 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







|




>
>
>


>

|







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
85973
85974
85975
85976
85977
85978
85979
85980
  }
resolve_p2_values_loop_exit:
  if( aLabel ){
    sqlite3DbNNFreeNN(p->db, pParse->aLabel);
    pParse->aLabel = 0;
  }
  pParse->nLabel = 0;
  *pMaxFuncArgs = nMaxArgs;
  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







|







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
86202
86203
86204
86205
86206
86207
86208
86209
  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) ){
    sqlite3_int64 nByte = (p->nScan+1) * 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;







|







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
87648
87649
87650
87651
87652
87653
87654
87655
87656

87657
87658
87659
87660
87661
87662
87663
  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;                      /* Number of arguments in subprograms */
  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 );

  p->pVList = pParse->pVList;
  pParse->pVList =  0;
  db = p->db;
  assert( db->mallocFailed==0 );
  nVar = pParse->nVar;
  nMem = pParse->nMem;
  nCursor = pParse->nTab;







|








>







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
90622
90623
90624
90625
90626
90627
90628
90629
** 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->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=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);







<







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
91342
91343
91344
91345
91346
91347
91348
91349
      ** 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==0 && 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{







|







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
91894
91895
91896
91897
91898
91899
91900
91901
**
** Specifically, this is called from within:
**
**     sqlite3_column_int()
**     sqlite3_column_int64()
**     sqlite3_column_text()
**     sqlite3_column_text16()
**     sqlite3_column_real()
**     sqlite3_column_bytes()
**     sqlite3_column_bytes16()
**     sqlite3_column_blob()
*/
static void columnMallocFailure(sqlite3_stmt *pStmt)
{
  /* If malloc() failed during an encoding conversion within an







|







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
92749


92750
92751
92752
92753
92754
92755
92756
92757
92758
** 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 ){
    iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx);


  }
  if( iIdx>=p->pCsr->nField || iIdx<0 ){
    rc = SQLITE_RANGE;
    goto preupdate_old_out;
  }

  if( iIdx==p->pTab->iPKey ){
    *ppValue = pMem = &p->oldipk;
    sqlite3VdbeMemSetInt64(pMem, p->iKey1);







>














|
>
>

|







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
92782
92783
92784
92785
92786
92787
92788


92789
92790
92791
92792
92793
92794
92795
92796
      if( rc!=SQLITE_OK ){
        sqlite3DbFree(db, aRec);
        goto preupdate_old_out;
      }
      p->aRecord = aRec;
    }

    pMem = *ppValue = &p->pUnpacked->aMem[iIdx];
    if( iIdx>=p->pUnpacked->nField ){
      /* This occurs when the table has been extended using ALTER TABLE
      ** ADD COLUMN. The value to return is the default value of the column. */
      Column *pCol = &p->pTab->aCol[iIdx];
      if( pCol->iDflt>0 ){
        if( p->apDflt==0 ){


          int nByte = sizeof(sqlite3_value*)*p->pTab->nCol;
          p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte);
          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) );







|
|





>
>
|







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
92899


92900

92901
92902
92903
92904
92905
92906
92907
92908
92909
92910
92911
92912
92913
92914
92915
92916
92917
92918
92919
92920
92921
92922
92923
92924
92925
92926
92927
92928
92929
92930
92931
92932
92933
92934

92935
92936
92937
92938
92939
92940
92941
92942
92943
92944
92945
92946
92947
92948
92949
92950
92951
92952
92953
92954
** 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 ){
    iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx);


  }

  if( iIdx>=p->pCsr->nField || iIdx<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[iIdx];
    if( iIdx==p->pTab->iPKey ){
      sqlite3VdbeMemSetInt64(pMem, p->iKey2);
    }else if( iIdx>=pUnpack->nField ){
      pMem = (sqlite3_value *)columnNullValue();
    }
  }else{
    /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required
    ** value. Make a copy of the cell contents and return a pointer to it.
    ** It is not safe to return a pointer to the memory cell itself as the
    ** caller may modify the value text encoding.
    */
    assert( p->op==SQLITE_UPDATE );
    if( !p->aNew ){

      p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField);
      if( !p->aNew ){
        rc = SQLITE_NOMEM;
        goto preupdate_new_out;
      }
    }
    assert( iIdx>=0 && iIdx<p->pCsr->nField );
    pMem = &p->aNew[iIdx];
    if( pMem->flags==0 ){
      if( iIdx==p->pTab->iPKey ){
        sqlite3VdbeMemSetInt64(pMem, p->iKey2);
      }else{
        rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]);
        if( rc!=SQLITE_OK ) goto preupdate_new_out;
      }
    }
  }
  *ppValue = pMem;

 preupdate_new_out:







>












|
>
>

>
|



















|


|



|






>
|





|
|




|







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
93705
93706
93707
93708
93709
93710
93711
93712
  **
  ** 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;

  int 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*/







|







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
93733
93734
93735
93736
93737
93738
93739
93740
      sqlite3DbFreeNN(pMem->db, pMem->zMalloc);
    }
    pMem->z = pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, nByte);
    if( pMem->zMalloc==0 ){
      pMem->szMalloc = 0;
      return 0;
    }
    pMem->szMalloc = 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];







|







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
100751
100752
100753
100754
100755
100756
100757
100758
**
** 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 */
  int 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 */








|







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
100802
100803
100804
100805
100806
100807
100808
100809
100810
100811
100812
100813
100814
100815
100816
100817
    */
    nMem = pProgram->nMem + pProgram->nCsr;
    assert( nMem>0 );
    if( pProgram->nCsr==0 ) nMem++;
    nByte = ROUND8(sizeof(VdbeFrame))
              + nMem * sizeof(Mem)
              + pProgram->nCsr * sizeof(VdbeCursor*)
              + (pProgram->nOp + 7)/8;
    pFrame = sqlite3DbMallocZero(db, nByte);
    if( !pFrame ){
      goto no_mem;
    }
    sqlite3VdbeMemRelease(pRt);
    pRt->flags = MEM_Blob|MEM_Dyn;
    pRt->z = (char*)pFrame;
    pRt->n = nByte;
    pRt->xDel = sqlite3VdbeFrameMemDel;

    pFrame->v = p;
    pFrame->nChildMem = nMem;
    pFrame->nChildCsr = pProgram->nCsr;
    pFrame->pc = (int)(pOp - aOp);
    pFrame->aMem = p->aMem;







|







|







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



100909
100910
100911
100912
100913
100914

100915
100916
100917
100918
100919
100920
100921
**
** 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( db->flags & SQLITE_DeferFKs ){
    db->nDeferredImmCons += pOp->p2;
  }else if( pOp->p1 ){
    db->nDeferredCons += pOp->p2;
  }else{
    p->nFkConstraint += pOp->p2;

  }
  break;
}

/* Opcode: FkIfZero P1 P2 * * *
** Synopsis: if fkctr[P1]==0 goto P2
**







>
>
>
|
|
<
<
|
|
>







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
102844
102845
102846
102847
102848
102849
102850
102851
102852
102853
102854
102855
102856
      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. */
    for(iCol=0; iCol<pTab->nCol; iCol++) {
      if( sqlite3StrICmp(pTab->aCol[iCol].zCnName, zColumn)==0 ){
        break;
      }
    }
    if( iCol==pTab->nCol ){
      sqlite3DbFree(db, zErr);
      zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn);
      rc = SQLITE_ERROR;
      sqlite3BtreeLeaveAll(db);
      goto blob_open_out;
    }








<
|
<
<
<
|







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
104111
104112
104113
104114
104115
104116
104117
104118
  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 */
  int sz;                         /* Size of pSorter in bytes */
  int rc = SQLITE_OK;
#if SQLITE_MAX_WORKER_THREADS==0
# define nWorker 0
#else
  int nWorker;
#endif








|







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
104352
104353
104354
104355
104356
104357
104358
104359
** 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 */
  int 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));








|







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
107395
107396
107397
107398
107399
107400
107401
107402
  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 */
  Column *pCol;                     /* A column of pTab */
  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) );







<







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
107446
107447
107448
107449
107450
107451
107452
107453
  assert( pNC && cnt==0 );
  do{
    ExprList *pEList;
    SrcList *pSrcList = pNC->pSrcList;

    if( pSrcList ){
      for(i=0, pItem=pSrcList->a; i<pSrcList->nSrc; i++, pItem++){
        u8 hCol;
        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:







<







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
107534
107535
107536
107537
107538
107539
107540
107541
107542
107543
107544
107545
107546
107547
107548
107549
107550
107551
107552
107553
107554
107555
107556
107557
107558
107559
107560
107561
107562
107563
107564
107565
107566
107567
107568
107569
107570
107571
107572
107573
107574
107575
107576
107577
            if( !isValidSchemaTableName(zTab, pTab, zDb) ) continue;
          }
          assert( ExprUseYTab(pExpr) );
          if( IN_RENAME_OBJECT && pItem->zAlias ){
            sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
          }
        }
        hCol = sqlite3StrIHash(zCol);
        for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
          if( pCol->hName==hCol
           && sqlite3StrICmp(pCol->zCnName, zCol)==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);
            }
            break;
          }
        }
        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.







|
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<







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
107660
107661
107662
107663
107664
107665
107666
107667
107668
107669
107670
107671
107672
107673
107674
107675



107676
107677
107678
107679
107680
107681
107682
          pExpr->iTable = EXCLUDED_TABLE_NUMBER;
        }
      }
#endif /* SQLITE_OMIT_UPSERT */

      if( pTab ){
        int iCol;
        u8 hCol = sqlite3StrIHash(zCol);
        pSchema = pTab->pSchema;
        cntTab++;
        for(iCol=0, pCol=pTab->aCol; iCol<pTab->nCol; iCol++, pCol++){
          if( pCol->hName==hCol
           && sqlite3StrICmp(pCol->zCnName, zCol)==0
          ){
            if( iCol==pTab->iPKey ){
              iCol = -1;
            }
            break;
          }
        }
        if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){
          /* IMP: R-51414-32910 */
          iCol = -1;



        }
        if( iCol<pTab->nCol ){
          cnt++;
          pMatch = 0;
#ifndef SQLITE_OMIT_UPSERT
          if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){
            testcase( iCol==(-1) );







<


<
<
|
<
|
|
|
<
<
<
|
<
|
>
>
>







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
109901
109902
109903
109904
109905
109906
109907
109908
    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, (u8)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







|







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
111271
111272
111273
111274
111275
111276
111277
111278
          pNewExpr->pRight = pPriorSelectColNew;
        }
        pNewExpr->pLeft = pPriorSelectColNew;
      }
    }
    pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);
    pItem->fg = pOldItem->fg;
    pItem->fg.done = 0;
    pItem->u = pOldItem->u;
  }
  return pNew;
}

/*
** If cursors, triggers, views and subqueries are all omitted from







<







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
111354
111355
111356
111357
111358
111359
111360
111361
111362
111363
111364
111365
111366
111367
111368
111369
111370
  return pNew;
}
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
  IdList *pNew;
  int i;
  assert( db!=0 );
  if( p==0 ) return 0;
  assert( p->eU4!=EU4_EXPR );
  pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) );
  if( pNew==0 ) return 0;
  pNew->nId = p->nId;
  pNew->eU4 = p->eU4;
  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);
    pNewItem->u4 = pOldItem->u4;
  }
  return pNew;
}
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
  Select *pRet = 0;
  Select *pNext = 0;
  Select **pp = &pRet;







<



<




<







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
112391
112392
112393
112394
112395
112396
112397
112398
112399
112400
112401
112402
112403
112404
** 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++){
    int iCol;
    for(iCol=0; iCol<pTab->nCol; iCol++){
      if( sqlite3_stricmp(azOpt[ii], pTab->aCol[iCol].zCnName)==0 ) break;
    }
    if( iCol==pTab->nCol ){
      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







<
<
<
<
<
|
<







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
112800
112801
112802
112803
112804
112805
112806
112807
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, nVal+1);
  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);







|







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
112952
112953
112954
112955
112956
112957
112958
112959
){
  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.
    */
    SubrtnSig *pSig = 0;
    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);
      }







>




















<







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
117442
117443
117444
117445
117446
117447
117448
117449
117450
117451
117452
  }
#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;
  for(iCol=0; iCol<pTab->nCol; iCol++){
    if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break;
  }
  if( iCol==pTab->nCol ){
    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);







<
|
<
|







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

119344
119345
119346
119347
119348
119349
119350
119351
        /* 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
        );

        aRoot[i] = (u32)pParse->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;







>
|







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
119535
119536
119537
119538
119539
119540
119541
119542
  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 */
  int 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 */







|







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
121309
121310
121311
121312
121313
121314
121315
121316
121317
121318
121319
121320
121321
121322
121323
121324
121325
121326






121327
121328
121329
121330
121331
121332
121333
    ** 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])*(db->nDb+1) );
      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;






    }
    assert( pVfs );
    flags |= SQLITE_OPEN_MAIN_DB;
    rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags);
    db->nDb++;
    pNew->zDbSName = sqlite3DbStrDup(db, zName);
  }







|

















>
>
>
>
>
>







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
122196
122197
122198
122199


122200
122201
122202
122203
122204
122205
122206
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) pParse->rc = SQLITE_ERROR;
  }
  assert( !pParse->isMultiWrite
       || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
  if( v ){
    if( pParse->bReturning ){
      Returning *pReturning = pParse->u1.pReturning;
      int addrRewind;
      int reg;



      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++){







|



>
>







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
122275


122276
122277
122278
122279
122280
122281
122282
      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 = pParse->u1.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);







|
>
>







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

123347
123348
123349
123350
123351
123352
123353
123354
123355
123356
123357
123358
123359
123360
123361
123362
123363
123364
123365
123366
123367
123368
123369
123370
123371
123372
123373
123374
123375
123376
123377
123378
123379
123380
123381
123382
      sqlite3VdbeAddOp0(v, OP_VBegin);
    }
#endif

    /* If the file format and encoding in the database have not been set,
    ** set them now.
    */

    reg1 = pParse->regRowid = ++pParse->nMem;
    reg2 = pParse->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->regRowid.
    ** The root page number of the new table is left in reg pParse->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.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);







>
|
|














|
|










|







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

123453
123454
123455
123456
123457
123458
123459
123460
  }
  pParse->bReturning = 1;
  pRet = sqlite3DbMallocZero(db, sizeof(*pRet));
  if( pRet==0 ){
    sqlite3ExprListDelete(db, pList);
    return;
  }

  pParse->u1.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);







>
|







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
123495
123496
123497
123498
123499
123500
123501
123502
SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){
  Table *p;
  int i;
  char *z;
  char *zType;
  Column *pCol;
  sqlite3 *db = pParse->db;
  u8 hName;
  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] ){







<







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
123549
123550
123551
123552
123553
123554
123555
123556
123557
123558
123559
123560
123561
123562
123563
123564
123565
123566
123567
123568
123569
123570
123571
123572
123573

  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);
  hName = sqlite3StrIHash(z);
  for(i=0; i<p->nCol; i++){
    if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zCnName)==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 = hName;
  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;







|
<
<
|
|
|
<










|







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

123592
123593
123594
123595
123596
123597
123598
123599
    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++;

  pParse->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.







>
>
>
>


>
|







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
123856
123857
123858
123859
123860
123861
123862
123863
123864
123865
123866
123867
123868
123869
123870
123871
  }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 ){
        const char *zCName;
        assert( !ExprHasProperty(pCExpr, EP_IntValue) );
        zCName = pCExpr->u.zToken;
        for(iCol=0; iCol<pTab->nCol; iCol++){
          if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zCnName)==0 ){
            pCol = &pTab->aCol[iCol];
            makeColumnPartOfPrimaryKey(pParse, pCol);
            break;
          }
        }
      }
    }
  }
  if( nTerm==1
   && pCol
   && pCol->eCType==COLTYPE_INTEGER







<

|
|
<
|
|
<
<







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

123916
123917

123918
123919
123920
123921
123922
123923
123924
#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);

    if( pParse->constraintName.n ){
      sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->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);







>
|
|
>







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
124112

124113
124114
124115
124116
124117
124118
124119

/*
** 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, 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;
  }







|
>







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

124136
124137
124138
124139
124140
124141
124142
124143
124144
124145
124146
124147
124148
124149
124150
124151


124152
124153
124154
124155

124156
124157
124158
124159
124160
124161
124162
124163
124164
124165
124166
124167
124168
124169

124170
124171
124172
124173


124174
124175
124176
124177
124178
124179
124180
124181
  }
  n += 35 + 6*p->nCol;
  zStmt = sqlite3DbMallocRaw(0, n);
  if( zStmt==0 ){
    sqlite3OomFault(db);
    return 0;
  }

  sqlite3_snprintf(n, zStmt, "CREATE TABLE ");
  k = sqlite3Strlen30(zStmt);
  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",
    };
    int len;
    const char *zType;



    sqlite3_snprintf(n-k, &zStmt[k], zSep);
    k += sqlite3Strlen30(&zStmt[k]);
    zSep = zSep2;
    identPut(zStmt, &k, pCol->zCnName);

    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) );

    memcpy(&zStmt[k], zType, len);
    k += len;
    assert( k<=n );
  }


  sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd);
  return zStmt;
}

/*
** Resize an Index object to hold N columns total.  Return SQLITE_OK
** on success and SQLITE_NOMEM on an OOM error.
*/







>
|
|











<


>
>
|
|


>














>




>
>
|







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
124367
124368
124369
124370
124371
124372
124373
124374
124375
124376
    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.addrCrTab ){
    assert( v );
    sqlite3VdbeChangeP3(v, pParse->u1.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;







|

|







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
124809
124810
124811
124812
124813
124814
124815
124816
      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->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







|







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

124840
124841
124842
124843
124844
124845
124846
124847
        return;
      }
      iCsr = pParse->nTab++;
      regYield = ++pParse->nMem;
      regRec = ++pParse->nMem;
      regRowid = ++pParse->nMem;
      sqlite3MayAbort(pParse);

      sqlite3VdbeAddOp3(v, OP_OpenWrite, iCsr, pParse->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 );







>
|







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
124893
124894
124895
124896
124897
124898
124899
124900
124901
124902
      );
    }

    /* 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,
      pParse->regRoot,
      zStmt,
      pParse->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.







>








|

|







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
125866
125867
125868
125869
125870
125871
125872
125873
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 */
  int 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);







|







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
126719
126720
126721
126722
126723
126724
126725
126726
/*
** Delete an IdList.
*/
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){
  int i;
  assert( db!=0 );
  if( pList==0 ) return;
  assert( pList->eU4!=EU4_EXPR ); /* EU4_EXPR mode is not currently used */
  for(i=0; i<pList->nId; i++){
    sqlite3DbFree(db, pList->a[i].zName);
  }
  sqlite3DbNNFreeNN(db, pList);
}

/*







<







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
128100

128101
128102
128103
128104
128105





128106
128107
128108
128109
128110
128111
128112
#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>=-1 );


  /* 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;





  }

  /* 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{







|
>



|

>
>
>
>
>







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
129728
129729
129730
129731
129732
129733
129734
129735
129736
129737
129738
129739
129740
129741
129742
129743
129744
129745
129746
129747
129748
129749
129750
129751
129752
129753
129754
129755
129756
129757
129758
129759
129760
129761
129762
129763
129764
129765
129766
129767
129768
129769











129770
129771
129772



129773
129774

129775
129776
129777
129778
129779
129780
129781
129782
129783
129784
129785

129786
129787

129788
129789
129790
129791
129792
129793
129794
129795
129796
129797
129798
129799
129800
129801


129802
129803
129804
129805
129806
129807
129808
129809
129810
129811
129812
129813
129814
129815
129816
129817
129818
129819
129820
129821
129822
129823
129824
129825
129826
129827
129828
129829
129830
129831
129832
129833
129834
129835
129836
129837
129838
129839
129840
129841
129842
  sqlite3_value **argv
){
  const unsigned char *z;
  const unsigned char *z2;
  int len;
  int p0type;
  i64 p1, p2;
  int negP2 = 0;

  assert( argc==3 || argc==2 );
  if( sqlite3_value_type(argv[1])==SQLITE_NULL
   || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL)
  ){
    return;
  }
  p0type = sqlite3_value_type(argv[0]);
  p1 = sqlite3_value_int(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);
      }
    }
  }
#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. */
  if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */
#endif
  if( argc==3 ){
    p2 = sqlite3_value_int(argv[2]);
    if( p2<0 ){
      p2 = -p2;
      negP2 = 1;
    }
  }else{
    p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH];
  }











  if( p1<0 ){
    p1 += len;
    if( p1<0 ){



      p2 += p1;
      if( p2<0 ) p2 = 0;

      p1 = 0;
    }
  }else if( p1>0 ){
    p1--;
  }else if( p2>0 ){
    p2--;
  }
  if( negP2 ){
    p1 -= p2;
    if( p1<0 ){
      p2 += p1;

      p1 = 0;
    }

  }
  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+p2>len ){


      p2 = len-p1;
      if( p2<0 ) 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){
  int 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_int(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",n,r);
    if( zBuf==0 ){
      sqlite3_result_error_nomem(context);
      return;
    }
    sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8);
    sqlite3_free(zBuf);
  }







<


<
<
<
<
<

|















<
<
<
<
<
<
<
<

|
|
<
<
<



>
>
>
>
>
>
>
>
>
>
>



>
>
>
|
<
>







|
<
|
|
>
|

>













|
>
>

|










|





|














|







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
130794
130795
130796
130797
130798
130799
130800
130801
  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, (i64)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) ){







|







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
130944
130945
130946
130947
130948
130949
130950
130951
){
  i64 j, k, n = 0;
  int i;
  char *z;
  for(i=0; i<argc; i++){
    n += sqlite3_value_bytes(argv[i]);
  }
  n += (argc-1)*nSep;
  z = sqlite3_malloc64(n+1);
  if( z==0 ){
    sqlite3_result_error_nomem(context);
    return;
  }
  j = 0;
  for(i=0; i<argc; 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
131242



131243
131244
131245
131246
131247
131248
131249
  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 ){
      p->iSum -= sqlite3_value_int64(argv[0]);



    }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);







|
>
>
>







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
132068
132069
132070
132071
132072
132073
132074
132075
132076
132077
132078
132079
132080
#endif
    FUNCTION(ltrim,              1, 1, 0, trimFunc         ),
    FUNCTION(ltrim,              2, 1, 0, trimFunc         ),
    FUNCTION(rtrim,              1, 2, 0, trimFunc         ),
    FUNCTION(rtrim,              2, 2, 0, trimFunc         ),
    FUNCTION(trim,               1, 3, 0, trimFunc         ),
    FUNCTION(trim,               2, 3, 0, trimFunc         ),
    FUNCTION(min,               -1, 0, 1, minmaxFunc       ),
    FUNCTION(min,                0, 0, 1, 0                ),
    WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0,
                                 SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ),
    FUNCTION(max,               -1, 1, 1, minmaxFunc       ),
    FUNCTION(max,                0, 1, 1, 0                ),
    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),







|
<


|
<







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
132100
132101
132102
132103
132104
132105
132106
132107
132108
132109
132110
132111
    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,            -1, 0, 0, concatFunc       ),
    FUNCTION(concat,             0, 0, 0, 0                ),
    FUNCTION(concat_ws,         -1, 0, 0, concatwsFunc     ),
    FUNCTION(concat_ws,          0, 0, 0, 0                ),
    FUNCTION(concat_ws,          1, 0, 0, 0                ),
    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       ),







|
<
|
<
<







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
132148
132149
132150
132151
132152
132153
132154
132155
132156
#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
    FUNCTION(coalesce,           1, 0, 0, 0                ),
    FUNCTION(coalesce,           0, 0, 0, 0                ),
#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







<
<







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
132187
132188
132189
132190
132191
132192
132193
132194
132195
132196
132197
132198
#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,       -1, INLINEFUNC_coalesce, 0 ),
    INLINE_FUNC(iif,             2, INLINEFUNC_iif,      0 ),
    INLINE_FUNC(iif,             3, INLINEFUNC_iif,      0 ),
    INLINE_FUNC(if,              2, INLINEFUNC_iif,      0 ),
    INLINE_FUNC(if,              3, INLINEFUNC_iif,      0 ),
  };
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions();
#endif
  sqlite3WindowFunctions();
  sqlite3RegisterDateTimeFunctions();
  sqlite3RegisterJsonFunctions();







|
|
<
|
<







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
134781
134782
134783
134784
134785
134786
134787
134788
134789

134790
134791
134792
134793
134794
134795
134796
134797
134798
134799
134800
134801
134802
134803
134804
134805
134806
134807
134808
134809
134810
134811
134812
  ** 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 ){
    assert( pColumn->eU4!=EU4_EXPR );
    pColumn->eU4 = EU4_IDX;
    for(i=0; i<pColumn->nId; i++){
      pColumn->a[i].u4.idx = -1;
    }
    for(i=0; i<pColumn->nId; i++){
      for(j=0; j<pTab->nCol; j++){
        if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zCnName)==0 ){
          pColumn->a[i].u4.idx = j;

          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
          break;
        }
      }
      if( j>=pTab->nCol ){
        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;







|
|

|
<
<
<
<
|
>
|
|
|
|

|
|
|
|
|
|

<
|
<
<







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
135103
135104
135105
135106
135107
135108
135109
135110
135111
135112
135113
135114
135115
135116
135117
135118
135119
135120
135121
135122
135123
135124
135125
135126
135127
135128
        ** 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 there default value */
        sqlite3ExprCodeFactorable(pParse,
            sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
            iRegStore);
        continue;
      }
    }
    if( pColumn ){
      assert( pColumn->eU4==EU4_IDX );
      for(j=0; j<pColumn->nId && pColumn->a[j].u4.idx!=i; j++){}
      if( j>=pColumn->nId ){
        /* A column not named in the insert column list gets its
        ** default value */
        sqlite3ExprCodeFactorable(pParse,
            sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
            iRegStore);
        continue;
      }
      k = j;
    }else if( nColumn==0 ){
      /* This is INSERT INTO ... DEFAULT VALUES.  Load the default value. */
      sqlite3ExprCodeFactorable(pParse,
          sqlite3ColumnExpr(pTab, &pTab->aCol[i]),
          iRegStore);
      continue;
    }else{







|







|
|
|







|







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

135366


135367
135368
135369
135370
135371
135372
135373
  }

insert_cleanup:
  sqlite3SrcListDelete(db, pTabList);
  sqlite3ExprListDelete(db, pList);
  sqlite3UpsertDelete(db, pUpsert);
  sqlite3SelectDelete(db, pSelect);

  sqlite3IdListDelete(db, pColumn);


  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







>
|
>
>







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
140713



140714
140715
140716
140717
140718
140719
140720
        if( (mask & SQLITE_WriteSchema)==0
         || (db->flags & SQLITE_Defensive)==0
        ){
          db->flags |= mask;
        }
      }else{
        db->flags &= ~mask;
        if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 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);







|
>
>
>







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
141321
141322
141323
141324
141325
141326
141327
141328
      /* 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, (u8)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);







|







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




144047


144048








144049




144050





144051
144052
144053
144054
144055
144056
144057

/*
** 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 = sqlite3StrIHash(zCol);


  Column *pCol;








  for(pCol=pTab->aCol, i=0; i<pTab->nCol; pCol++, i++){




    if( pCol->hName==h && sqlite3StrICmp(pCol->zCnName, zCol)==0 ) return i;





  }
  return -1;
}

/*
** Mark a subquery result column as having been used.
*/







>
>
>
>
|
>
>
|
>
>
>
>
>
>
>
>
|
>
>
>
>
|
>
>
>
>
>







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
150554
150555
150556
150557
150558
150559
150560
150561
          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, (u8)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);







|







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
150717
150718
150719
150720
150721
150722
150723
150724
        }
        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, (u8)nArg);
      sqlite3ReleaseTempRange(pParse, regAgg, nArg);
    }
    if( addrNext ){
      sqlite3VdbeResolveLabel(v, addrNext);
    }
    if( pParse->nErr ) return;
  }







|







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

152772
152773
152774
152775
152776
152777
152778
152779
      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->u1.pReturning->retTrig) == pTrig );
      pTrig->table = pTab->zName;
      pTrig->pTabSchema = pTab->pSchema;
      pTrig->pNext = pList;
      pList = pTrig;
    }
    p = sqliteHashNext(p);
  }







>
|







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

153749
153750
153751
153752
153753
153754
153755
153756
  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 );

  pReturning = pParse->u1.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);







>
|







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
154111
154112
154113
154114
154115
154116
154117
154118
        (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, (u8)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







|







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
154733
154734
154735
154736
154737
154738
154739
154740
154741
154742
154743
154744
154745
154746
154747
154748
154749
154750
154751
154752
154753
154754
154755
154756
154757
154758
154759
154760
154761
154762
154763
154764
154765
154766
154767
154768
154769
154770
154771
  ** 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++){
    u8 hCol = sqlite3StrIHash(pChanges->a[i].zEName);
    /* 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;
    }
    for(j=0; j<pTab->nCol; j++){
      if( pTab->aCol[j].hName==hCol
       && sqlite3StrICmp(pTab->aCol[j].zCnName, pChanges->a[i].zEName)==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;
        break;
      }
    }
    if( j>=pTab->nCol ){
      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);







<





<
<
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|

|
<
|
<
<







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
156871
156872
156873
156874
156875

156876
156877
156878
156879
156880
156881
156882
156883
156884
156885
156886
156887
156888
156889
156890
156891
    }
    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->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);

    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->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);







|




>








|







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

157222

157223
157224
157225
157226
157227
157228
157229
  /* 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 );

    if( tokenType!=aKeyword[i] ){
      sqlite3ErrorWithMsg(db, SQLITE_ERROR, "syntax error");
      return SQLITE_ERROR;
    }
  }

  sqlite3_mutex_enter(db->mutex);







>
|
>







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
157954

157955
157956
157957
157958
157959
157960
157961
  } 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
                        ** initialized unless pWInfo->nOutStarDelta>0 */

  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.







>

|
>







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
158003
158004
158005
158006
158007
158008
158009
158010
** 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 rUnsorted;     /* 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







|







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
158276
158277

158278



158279
158280
158281
158282
158283
158284
158285
  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) */
  LogEst nOutStarDelta;     /* Artifical nOut reduction for star-query */

  LogEst nRowOut;           /* Estimated number of output rows */



  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 */







|
|
>

>
>
>







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
161589
161590
161591
161592
161593
161594
161595
161596
161597
161598
161599
161600
161601

161602

161603
161604
161605
161606
161607
161608
161609
    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.
    ** or U+fffd character.  If the underlying database has a UTF16LE
    ** encoding, then only consider ASCII characters.  Note that the
    ** encoding of z[] is UTF8 - we are dealing with only UTF8 here in
    ** this code, but the database engine itself might be processing
    ** content using a different encoding. */
    cnt = 0;
    while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){
      cnt++;
      if( c==wc[3] && z[cnt]>0 && z[cnt]<0x80 ){
        cnt++;
      }else if( c>=0x80 ){
        const u8 *z2 = z+cnt-1;

        if( sqlite3Utf8Read(&z2)==0xfffd || ENC(db)==SQLITE_UTF16LE ){

          cnt--;
          break;
        }else{
          cnt = (int)(z2-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
162754
162755
162756
162757
162758
162759
162760
162761
162762
162763
162764
162765
162766



162767




162768
162769
162770
162771
162772
162773
162774
      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 c, *pC;       /* Last character before the first wildcard */
      pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1];
      c = *pC;
      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( c=='A'-1 ) isComplete = 0;
        c = sqlite3UpperToLower[c];
      }



      *pC = c + 1;




    }
    zCollSeqName = noCase ? "NOCASE" : sqlite3StrBINARY;
    pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
    pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
           sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
           pStr1);
    transferJoinMarkings(pNewExpr1, pExpr);







|

<







|
|

>
>
>
|
>
>
>
>







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
164219
164220
164221
164222
164223
164224
164225
164226
    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 );
    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 = ", ";







|







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
164361

164362
164363
164364
164365
164366
164367
164368
  ** 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 */
  pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 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++){







>
>
>
>
>
>
>
>
>
>
>
>
>












|
>







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

164417
164418

164419
164420
164421
164422
164423
164424
164425
    for(i=BMS-1; i<pTable->nCol; i++){
      pIdx->aiColumn[n] = i;
      pIdx->azColl[n] = sqlite3StrBINARY;
      n++;
    }
  }
  assert( n==nKeyCol );

  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);







>
|
|
>







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
165686
165687
165688
165689
165690
165691
165692
165693
165694
165695

165696
165697
165698
165699
165700
165701
165702
**     |  |   .-- 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 ){
    WhereInfo *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{

    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 ){







>

|









>







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




165727

165728
165729
165730
165731
165732
165733
165734
    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);
  }




  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);
    }
  }
}







>
>
>
>
|
>







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
167193
167194
167195
167196
167197
167198
167199
167200
#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 */
   && HasRowid(pTab)         /* Not WITHOUT ROWID table. (FIXME: Why not?) */
   && !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;







<







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
168696
168697

168698
168699


168700
168701
168702
168703


168704
168705
168706

168707









168708
168709













168710
168711
168712
168713
168714
168715


168716


168717





168718






168719


168720

168721






168722

168723
168724
168725












168726







168727





168728
168729

168730
168731
168732
168733




168734

168735
168736
168737
168738
168739
168740

168741

168742



168743

168744

168745

168746
168747


168748


168749












168750






168751
168752

168753
168754
168755

168756
168757






















168758
168759
168760
168761
168762
168763
168764
** 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 SQLite, a star-query is defined as a query
** with a large central table that is joined against four or more

** smaller tables.  The central table is called the "fact" table.
** The smaller tables that get joined are "dimension tables".


**
** SIDE EFFECT:  (and really the whole point of this subroutine)
**
** If pWInfo describes a star-query, then the cost on WhereLoops for the


** fact table is reduced.  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.  The total amount of heuristic cost









** adjustment is stored in pWInfo->nOutStarDelta and the cost adjustment
** for each WhereLoop is stored in its rStarDelta field.













*/
static int computeMxChoice(WhereInfo *pWInfo, LogEst nRowEst){
  int nLoop = pWInfo->nLevel;    /* Number of terms in the join */
  if( nRowEst==0 && nLoop>=5 ){
    /* Check to see if we are dealing with a star schema and if so, reduce
    ** the cost of fact tables relative to dimension tables, as a heuristic


    ** to help keep the fact tables in outer loops.


    */





    int iLoop;                /* Counter over join terms */






    Bitmask m;                /* Bitmask for current loop */


    assert( pWInfo->nOutStarDelta==0 );

    for(iLoop=0, m=1; iLoop<nLoop; iLoop++, m<<=1){






      WhereLoop *pWLoop;        /* For looping over WhereLoops */

      int nDep = 0;             /* Number of dimension tables */
      LogEst rDelta;            /* Heuristic cost adjustment */
      Bitmask mSeen = 0;        /* Mask of dimension tables */












      for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){







        if( (pWLoop->prereq & m)!=0 && (pWLoop->maskSelf & mSeen)==0 ){





          nDep++;
          mSeen |= pWLoop->maskSelf;

        }
      }
      if( nDep<=3 ) continue;
      rDelta = 15*(nDep-3);




#ifdef WHERETRACE_ENABLED /* 0x4 */

      if( sqlite3WhereTrace&0x4 ){
         SrcItem *pItem = pWInfo->pTabList->a + iLoop;
         sqlite3DebugPrintf("Fact-table %s: %d dimensions, cost reduced %d\n",
             pItem->zAlias ? pItem->zAlias : pItem->pSTab->zName,
             nDep, rDelta);
      }

#endif

      if( pWInfo->nOutStarDelta==0 ){



        for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){

          pWLoop->rStarDelta = 0;

        }

      }
      pWInfo->nOutStarDelta += rDelta;


      for(pWLoop=pWInfo->pLoops; pWLoop; pWLoop=pWLoop->pNextLoop){


        if( pWLoop->maskSelf==m ){












          pWLoop->rRun -= rDelta;






          pWLoop->nOut -= rDelta;
          pWLoop->rStarDelta = rDelta;

        }
      }
    }

  }
  return pWInfo->nOutStarDelta>0 ? 18 : 12;






















}

/*
** 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.
**







|
|
>
|
|
>
>



|
>
>
|
|
|
>
|
>
>
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
>
>
>
>
>
>

|

|
|
|
>
>
|
>
>
|
>
>
>
>
>
|
>
>
>
>
>
>
|
>
>
|
>
|
>
>
>
>
>
>
|
>

|

>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
|
|
>



|
>
>
>
>
|
>
|
|
<
<
|
|
>

>
|
>
>
>
|
>
|
>
|
>
|
<
>
>
|
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
|
|
>



>

|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
168781
168782
168783
168784
168785
168786
168787
168788
  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 mxUnsorted = 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 */







|







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
168811
168812
168813
168814
168815
168816
168817
168818
  **       2            5
  **       3+        12 or 18        // see computeMxChoice()
  */
  if( nLoop<=1 ){
    mxChoice = 1;
  }else if( nLoop==2 ){
    mxChoice = 5;


  }else{
    mxChoice = computeMxChoice(pWInfo, nRowEst);
  }
  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







>
>

|







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
168878
168879
168880
168881
168882
168883
168884
168885
168886
168887
168888
168889
168890
168891
168892
168893
168894
168895
168896
168897
168898
168899
168900
168901
168902
168903
168904
168905
168906
168907
  ** 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 rUnsorted;                 /* 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 */
        rUnsorted = pWLoop->rRun + pFrom->nRow;
        if( pWLoop->rSetup ){
          rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup, rUnsorted);
        }
        rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted);
        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,







|

















|

|

|







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
168922
168923
168924
168925
168926
168927
168928
168929
168930
168931
168932
168933
168934
168935
168936
168937
                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(rUnsorted, aSortCost[isOrdered]) + 3;

          WHERETRACE(0x002,
              ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",
               aSortCost[isOrdered], (nOrderBy-isOrdered), nOrderBy,
               rUnsorted, rCost));
        }else{
          rCost = rUnsorted;
          rUnsorted -= 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







|




|

|
|







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
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
            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 && rUnsorted>=mxUnsorted))
          ){
            /* 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, rUnsorted,
                  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, rUnsorted,
                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->rUnsorted) <= (rCost,nOut,rUnsorted)
          */
          if( pTo->rCost<rCost
           || (pTo->rCost==rCost
               && (pTo->nRow<nOut
                   || (pTo->nRow==nOut && pTo->rUnsorted<=rUnsorted)
                  )
              )
          ){
#ifdef WHERETRACE_ENABLED /* 0x4 */
            if( sqlite3WhereTrace&0x4 ){
              sqlite3DebugPrintf(
                  "Skip   %s cost=%-3d,%3d,%3d order=%c",
                  wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted,
                  isOrdered>=0 ? isOrdered+'0' : '?');
              sqlite3DebugPrintf("   vs %s cost=%-3d,%3d,%3d order=%c\n",
                  wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
                  pTo->rUnsorted, 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, rUnsorted,
                isOrdered>=0 ? isOrdered+'0' : '?');
            sqlite3DebugPrintf("  was %s cost=%-3d,%3d,%3d order=%c\n",
                wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow,
                pTo->rUnsorted, 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->rUnsorted = rUnsorted;
        pTo->isOrdered = isOrdered;
        memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop);
        pTo->aLoop[iLoop] = pWLoop;
        if( nTo>=mxChoice ){
          mxI = 0;
          mxCost = aTo[0].rCost;
          mxUnsorted = aTo[0].nRow;
          for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
            if( pTo->rCost>mxCost
             || (pTo->rCost==mxCost && pTo->rUnsorted>mxUnsorted)
            ){
              mxCost = pTo->rCost;
              mxUnsorted = pTo->rUnsorted;
              mxI = jj;
            }
          }
        }
      }
    }

#ifdef WHERETRACE_ENABLED  /* >=2 */
    if( sqlite3WhereTrace & 0x02 ){
      LogEst rMin, rFloor = 0;
      int nDone = 0;

      sqlite3DebugPrintf("---- after round %d ----\n", iLoop);
      while( nDone<nTo ){


        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++;

          }
        }
        rFloor = rMin;
      }
    }
#endif

    /* Swap the roles of aFrom and aTo for the next generation */
    pFrom = aTo;
    aTo = aFrom;
    aFrom = pFrom;







|







|


















|










|

|
|
|
|
|
<





|



|













|



|








|






|


|


|











>

<
>
>















>



|







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
169177



169178
169179
169180
169181
169182
169183
169184
      if( nOrder==pWInfo->pOrderBy->nExpr ){
        pWInfo->sorted = 1;
        pWInfo->revMask = revMask;
      }
    }
  }

  pWInfo->nRowOut = pFrom->nRow + pWInfo->nOutStarDelta;




  /* Free temporary memory and return success */
  sqlite3StackFreeNN(pParse->db, pSpace);
  return SQLITE_OK;
}

/*







|
>
>
>







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
169575
169576
169577
169578
169579
169580
169581
169582
           "-> 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;
    if( pWInfo->nOutStarDelta ) nSearch += pLoop->rStarDelta;
  }
}

/*
** 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







<







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
170058

170059
170060
170061
170062
170063
170064
170065
  }
  if( pParse->nErr ){
    goto whereBeginError;
  }
  assert( db->mallocFailed==0 );
#ifdef WHERETRACE_ENABLED
  if( sqlite3WhereTrace ){
    sqlite3DebugPrintf("---- Solution nRow=%d", 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;







|
>







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
172528
172529
172530
172531
172532
172533
172534
172535
        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, (u8)nArg);
      if( pWin->bExprArgs ){
        sqlite3ReleaseTempRange(pParse, regArg, nArg);
      }
    }

    if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
  }







|







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

174315
174316
174317
174318
174319
174320
174321
174322
#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_ILLEGAL                        185
#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.







>
|







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
174380
174381
174382
174383
174384
174385
174386
174387

174388
174389
174390
174391

174392
174393

174394
174395
174396
174397
174398

174399
174400
174401
174402
174403
174404
174405
174406
174407
174408
174409
174410
174411
**    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 322
#define YYACTIONTYPE unsigned short int
#define YYWILDCARD 102
#define sqlite3ParserTOKENTYPE Token
typedef union {
  int yyinit;
  sqlite3ParserTOKENTYPE yy0;
  ExprList* yy14;

  With* yy59;
  Cte* yy67;
  Upsert* yy122;
  IdList* yy132;

  int yy144;
  const char* yy168;

  SrcList* yy203;
  Window* yy211;
  OnOrUsing yy269;
  struct TrigEvent yy286;
  struct {int value; int mask;} yy383;

  u32 yy391;
  TriggerStep* yy427;
  Expr* yy454;
  u8 yy462;
  struct FrameBound yy509;
  Select* yy555;
} YYMINORTYPE;
#ifndef YYSTACKDEPTH
#define YYSTACKDEPTH 100
#endif
#define sqlite3ParserARG_SDECL
#define sqlite3ParserARG_PDECL
#define sqlite3ParserARG_PARAM







|






|
>
|
<
<
|
>
|
|
>
|
|
|
|
|
>
|
|
|
<
<
|







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
174426
174427
174428
174429
174430
174431
174432
174433
174434
174435
174436
174437
174438
174439
174440
174441
174442
174443
#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             186
#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       205
#define YY_MAX_DSTRCTR       319
/************* 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







|








|
|







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
174532
174533
174534
174535
174536
174537
174538
174539
174540
174541
174542
174543
174544
174545
174546
174547
174548
174549
174550
174551
174552
174553
174554
174555
174556
174557
174558
174559
174560
174561
174562
174563
174564
174565
174566
174567
174568
174569
174570
174571
174572
174573
174574
174575
174576
174577
174578
174579
174580
174581
174582
174583
174584
174585
174586
174587
174588
174589
174590
174591
174592
174593
174594
174595
174596
174597
174598
174599
174600
174601
174602
174603
174604
174605
174606
174607
174608
174609
174610
174611
174612
174613
174614
174615
174616
174617
174618
174619
174620
174621
174622
174623
174624
174625
174626
174627
174628
174629
174630
174631
174632
174633
174634
174635
174636
174637
174638
174639
174640
174641
174642
174643
174644
174645
174646
174647
174648
174649
174650
174651
174652
174653
174654
174655
174656
174657
174658
174659
174660
174661
174662
174663
174664
174665
174666
174667
174668
174669
174670
174671
174672
174673
174674
174675
174676
174677
174678
174679
174680
174681
174682
174683
174684
174685
174686
174687
174688
174689
174690
174691
174692
174693
174694
174695
174696
174697
174698
174699
174700
174701
174702
174703
174704
174705
174706
174707
174708
174709
174710
174711
174712
174713
174714
174715
174716
174717
174718
174719
174720
174721
174722
174723
174724
174725
174726
174727
174728
174729
174730
174731
174732
174733
174734
174735
174736
174737
174738
174739
174740
174741
174742
174743
174744
174745
174746
174747
174748
174749
174750
174751
174752
174753
174754
174755
174756
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
174796
174797
174798
174799
174800
174801
174802
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
174828
174829
174830
174831
174832
174833
174834
174835
174836
174837
174838
174839
174840
174841
174842
174843
174844
174845
174846
174847
174848
174849
174850
174851
174852
174853
174854
174855
174856
174857
174858
174859
174860
174861
174862
174863
174864
174865
174866
174867
174868
174869
174870
174871
174872
174873
174874
174875
174876
174877
174878
174879
174880
174881
174882
174883
174884
174885
174886
174887
174888
174889
174890
174891
174892
174893
174894
174895
174896
174897
174898
174899
174900
174901
174902
174903
174904
174905
174906
174907
174908
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
 /*    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,   44, 1050, 1050, 1064, 1067,
 /*   120 */  1255,    1,    1,  582,    2, 1259,  581, 1174, 1259, 1174,
 /*   130 */   321,  413,  155,  321, 1584,  155,  379,  112,  498, 1341,
 /*   140 */   456,  299, 1341,  134,  134,  134,  134,  133,  133,  132,
 /*   150 */   132,  132,  131,  128,  451,  137,  138,   91, 1105, 1228,
 /*   160 */  1228, 1063, 1066, 1053, 1053,  135,  135,  136,  136,  136,
 /*   170 */   136, 1204,  320,  567,  288,  288,  283,  288,  288,  523,
 /*   180 */   523, 1250,  139, 1541,    7,  214,  503,  573, 1169,  562,
 /*   190 */   573, 1054,  562,  136,  136,  136,  136,  129,  401,  547,
 /*   200 */   487, 1169,  245, 1568, 1169,  245,  133,  133,  132,  132,
 /*   210 */   132,  131,  128,  451,  261,  134,  134,  134,  134,  133,
 /*   220 */   133,  132,  132,  132,  131,  128,  451,  451, 1204, 1205,
 /*   230 */  1204,  130,  127,  234,  455,  413,  182,  455,  130,  127,
 /*   240 */   234,  134,  134,  134,  134,  133,  133,  132,  132,  132,
 /*   250 */   131,  128,  451,  136,  136,  136,  136,  538,  576,  137,
 /*   260 */   138,   91,  261, 1228, 1228, 1063, 1066, 1053, 1053,  135,
 /*   270 */   135,  136,  136,  136,  136,   44,  472,  346, 1204,  472,
 /*   280 */   346,   51,   51,  418,   93,  157,  134,  134,  134,  134,
 /*   290 */   133,  133,  132,  132,  132,  131,  128,  451,  166,  363,
 /*   300 */   298,  134,  134,  134,  134,  133,  133,  132,  132,  132,
 /*   310 */   131,  128,  451, 1293,  461, 1570,  423,  377,  275,  134,
 /*   320 */   134,  134,  134,  133,  133,  132,  132,  132,  131,  128,
 /*   330 */   451,  418,  320,  567, 1292, 1204, 1205, 1204,  257,  413,
 /*   340 */   483,  511,  508,  507,   94,  132,  132,  132,  131,  128,
 /*   350 */   451,  506, 1204,  548,  548,  388,  576,  384,    7,  413,
 /*   360 */   550,  229,  522,  137,  138,   91,  530, 1228, 1228, 1063,
 /*   370 */  1066, 1053, 1053,  135,  135,  136,  136,  136,  136,   51,
 /*   380 */    51, 1582,  380,  137,  138,   91,  331, 1228, 1228, 1063,
 /*   390 */  1066, 1053, 1053,  135,  135,  136,  136,  136,  136,  320,
 /*   400 */   567,  288,  288,  320,  567, 1602,  582,    2, 1259, 1204,
 /*   410 */  1205, 1204, 1628,  321,  573,  155,  562,  576, 1511,  264,
 /*   420 */   231,  520, 1341,  134,  134,  134,  134,  133,  133,  132,
 /*   430 */   132,  132,  131,  128,  451,  519, 1511, 1513, 1333, 1333,
 /*   440 */    82,   82,  498,  134,  134,  134,  134,  133,  133,  132,
 /*   450 */   132,  132,  131,  128,  451, 1435,  257,  288,  288,  511,
 /*   460 */   508,  507,  944, 1568,  413, 1019, 1204,  943,  360,  506,
 /*   470 */   573, 1598,  562,   44,  575,  551,  551,  557, 1107, 1582,
 /*   480 */   544,  576, 1107,   40,  417,  245,  531, 1505,  137,  138,
 /*   490 */    91,  219, 1228, 1228, 1063, 1066, 1053, 1053,  135,  135,
 /*   500 */   136,  136,  136,  136,   81,   81, 1281, 1204,  413,  553,
 /*   510 */  1511,   48,  512,  448,  447,  493,  578,  455,  578,  344,
 /*   520 */    45, 1204, 1233, 1204, 1205, 1204,  428, 1235,  158,  882,
 /*   530 */   320,  567,  137,  138,   91, 1234, 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 */  1236,  576, 1236,  329, 1204, 1205, 1204,  387,  492,  403,
 /*   570 */  1040,  382,  489,  123,  568, 1569,    4,  377, 1204, 1205,
 /*   580 */  1204,  570,  570,  570,   82,   82,  882, 1029, 1331, 1331,
 /*   590 */   571, 1028,  134,  134,  134,  134,  133,  133,  132,  132,
 /*   600 */   132,  131,  128,  451,  288,  288, 1281, 1204,  576,  423,
 /*   610 */   576, 1568,  413,  423,  452,  378,  886,  573, 1279,  562,
 /*   620 */    46,  557,  532, 1028, 1028, 1030,  565,  130,  127,  234,
 /*   630 */   556,   82,   82,   82,   82,  479,  137,  138,   91,  462,
 /*   640 */  1228, 1228, 1063, 1066, 1053, 1053,  135,  135,  136,  136,
 /*   650 */   136,  136, 1188,  487, 1506, 1040,  413,    6, 1204,   50,
 /*   660 */   879,  121,  121,  948, 1204, 1205, 1204,  358,  557,  122,
 /*   670 */   316,  452,  577,  452,  535, 1204, 1028,  439,  303,  212,
 /*   680 */   137,  138,   91,  213, 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,  288,  288, 1204, 1205, 1204, 1040, 1339,
 /*   720 */   533,  123,  568, 1569,    4,  377,  573, 1019,  562,  353,
 /*   730 */  1277,  356, 1204, 1205, 1204, 1029,  488, 1188,  571, 1028,
 /*   740 */   134,  134,  134,  134,  133,  133,  132,  132,  132,  131,
 /*   750 */   128,  451,  576,  343,  288,  288,  449,  449,  449,  971,
 /*   760 */   413, 1627,  452,  911, 1187,  288,  288,  573,  464,  562,
 /*   770 */   238, 1028, 1028, 1030,  565,   82,   82,  498,  573,  411,
 /*   780 */   562,  344,  467,  332,  137,  138,   91,  197, 1228, 1228,
 /*   790 */  1063, 1066, 1053, 1053,  135,  135,  136,  136,  136,  136,
 /*   800 */  1188,  528, 1169, 1040,  413, 1110, 1110,  495, 1041,  121,
 /*   810 */   121, 1204,  317,  540,  862, 1169, 1244,  122, 1169,  452,
 /*   820 */   577,  452, 1340,  198, 1028, 1204,  481,  526,  137,  138,
 /*   830 */    91,  560, 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, 1204,  288,  288, 1204,  477,  288,  288, 1204, 1205,
 /*   870 */  1204,  539,  481,  437,  470,  573, 1451,  562,  364,  573,
 /*   880 */  1153,  562, 1204, 1205, 1204, 1188,    5,  576,  134,  134,
 /*   890 */   134,  134,  133,  133,  132,  132,  132,  131,  128,  451,
 /*   900 */   221,  214,  302,   96, 1149, 1657,  232, 1657,  413,  392,
 /*   910 */    19,   19, 1024,  949,  406,  373, 1595, 1085, 1204, 1205,
 /*   920 */  1204, 1204, 1205, 1204, 1204,  426, 1149, 1658,  413, 1658,
 /*   930 */  1659,  399,  137,  138,   91,    3, 1228, 1228, 1063, 1066,
 /*   940 */  1053, 1053,  135,  135,  136,  136,  136,  136,  304, 1311,
 /*   950 */   514, 1204,  137,  138,   91, 1498, 1228, 1228, 1063, 1066,
 /*   960 */  1053, 1053,  135,  135,  136,  136,  136,  136,  434,  131,
 /*   970 */   128,  451,  375, 1204,  274,  291,  372,  517,  367,  516,
 /*   980 */   262, 1204, 1205, 1204, 1147,  227,  363,  448,  447, 1435,
 /*   990 */  1568, 1310,  134,  134,  134,  134,  133,  133,  132,  132,
 /*  1000 */   132,  131,  128,  451, 1568,  576, 1147,  487, 1204, 1205,
 /*  1010 */  1204,  442,  134,  134,  134,  134,  133,  133,  132,  132,
 /*  1020 */   132,  131,  128,  451,  386,  576,  485,  576,   19,   19,
 /*  1030 */  1204, 1205, 1204, 1345, 1236,  970, 1236,  574,   47,  936,
 /*  1040 */   936,  473,  413,  431, 1552,  573, 1125,  562,   19,   19,
 /*  1050 */    19,   19,   49,  336,  850,  851,  852,  111, 1368,  315,
 /*  1060 */   429,  576,  413,  433,  341,  306,  137,  138,   91,  115,
 /*  1070 */  1228, 1228, 1063, 1066, 1053, 1053,  135,  135,  136,  136,
 /*  1080 */   136,  136,  576, 1309,   82,   82,  137,  138,   91,  529,
 /*  1090 */  1228, 1228, 1063, 1066, 1053, 1053,  135,  135,  136,  136,
 /*  1100 */   136,  136, 1569,  222,  377,   19,   19,  305, 1126, 1169,
 /*  1110 */   398, 1148,   22,   22,  498,  333, 1569,  335,  377,  576,
 /*  1120 */   438,  445, 1169, 1127,  486, 1169,  134,  134,  134,  134,
 /*  1130 */   133,  133,  132,  132,  132,  131,  128,  451, 1128,  576,
 /*  1140 */   902,  576,  145,  145,    6,  576,  134,  134,  134,  134,
 /*  1150 */   133,  133,  132,  132,  132,  131,  128,  451,  214, 1336,
 /*  1160 */   922,  576,   19,   19,   19,   19, 1282,  419,   19,   19,
 /*  1170 */   923,  412,  515,  141,  576, 1169,  413,  206,  465,  207,
 /*  1180 */   903,  215, 1575,  552,  147,  147,    7,  227, 1169,  411,
 /*  1190 */  1250, 1169,  120,  307,  117,  307,  413,   66,   66,  334,
 /*  1200 */   137,  138,   91,  119, 1228, 1228, 1063, 1066, 1053, 1053,
 /*  1210 */   135,  135,  136,  136,  136,  136,  413,  285,  209,  969,
 /*  1220 */   137,  138,   91,  471, 1228, 1228, 1063, 1066, 1053, 1053,
 /*  1230 */   135,  135,  136,  136,  136,  136,  435,   10, 1450,  267,
 /*  1240 */   137,  126,   91, 1435, 1228, 1228, 1063, 1066, 1053, 1053,
 /*  1250 */   135,  135,  136,  136,  136,  136, 1435, 1435,  410,  409,
 /*  1260 */   134,  134,  134,  134,  133,  133,  132,  132,  132,  131,
 /*  1270 */   128,  451,  576,  969,  576, 1224,  498,  373, 1595, 1554,
 /*  1280 */   134,  134,  134,  134,  133,  133,  132,  132,  132,  131,
 /*  1290 */   128,  451,  532,  457,  576,   82,   82,   82,   82,  111,
 /*  1300 */   134,  134,  134,  134,  133,  133,  132,  132,  132,  131,
 /*  1310 */   128,  451,  109,  233,  430, 1576,  546,   67,   67,    7,
 /*  1320 */   413,  351,  550, 1550,  260,  259,  258,  494,  443,  569,
 /*  1330 */   419,  983,  446, 1224,  450,  545, 1207,  576,  969,  984,
 /*  1340 */   413,  475, 1449, 1574, 1180,  138,   91,    7, 1228, 1228,
 /*  1350 */  1063, 1066, 1053, 1053,  135,  135,  136,  136,  136,  136,
 /*  1360 */    21,   21,  267,  576,  300, 1126,   91,  233, 1228, 1228,
 /*  1370 */  1063, 1066, 1053, 1053,  135,  135,  136,  136,  136,  136,
 /*  1380 */  1127,  373, 1595,  161, 1573,   16,   53,   53,    7,  108,
 /*  1390 */   533,   38,  969,  125, 1207, 1128, 1180,  576, 1224,  123,
 /*  1400 */   568,  893,    4,  324,  134,  134,  134,  134,  133,  133,
 /*  1410 */   132,  132,  132,  131,  128,  451,  571,  564,  534,  576,
 /*  1420 */    68,   68,  576,   39,  134,  134,  134,  134,  133,  133,
 /*  1430 */   132,  132,  132,  131,  128,  451,  576,  160, 1571, 1223,
 /*  1440 */   452,  576,   54,   54,  576,   69,   69,  576, 1366,  576,
 /*  1450 */   420,  184,  565,  463,  297,  576, 1224,  463,  297,   70,
 /*  1460 */    70,  576,   44,  474,   71,   71,  576,   72,   72,  576,
 /*  1470 */    73,   73,   55,   55,  411,  874,  242,  576,   56,   56,
 /*  1480 */   576, 1040,  576,  478,   57,   57,  576,  121,  121,   59,
 /*  1490 */    59,   23,   60,   60,  411,  122,  319,  452,  577,  452,
 /*  1500 */    74,   74, 1028,   75,   75,   76,   76,  411,  290,   20,
 /*  1510 */    20,  108,  287,  231,  553,  123,  568,  325,    4,  320,
 /*  1520 */   567,   97,  218,  944, 1144,  328,  400,  576,  943,  576,
 /*  1530 */  1380,  424,  571,  874, 1028, 1028, 1030, 1031,   35,  293,
 /*  1540 */   534,  576, 1104,  576, 1104,    9,  576,  342,  576,  111,
 /*  1550 */    77,   77,  143,  143,  576,  205,  452,  222, 1379,  889,
 /*  1560 */   576,  901,  900, 1188,  144,  144,   78,   78,  565,   62,
 /*  1570 */    62,   79,   79,  323, 1021,  576,  266,   63,   63,  908,
 /*  1580 */   909, 1589,  542,   80,   80,  576,  371,  541,  123,  568,
 /*  1590 */   480,    4,  266,  482,  244,  266,  370, 1040,   64,   64,
 /*  1600 */   576,  466,  576,  121,  121,  571, 1557,  576,  170,  170,
 /*  1610 */   576,  122,  576,  452,  577,  452,  576,  889, 1028,  576,
 /*  1620 */   165,  576,  111,  171,  171,   87,   87,  337, 1616,  452,
 /*  1630 */    65,   65, 1530,   83,   83,  146,  146,  986,  987,   84,
 /*  1640 */    84,  565,  168,  168,  148,  148, 1092,  347, 1032,  111,
 /*  1650 */  1028, 1028, 1030, 1031,   35,  542, 1103,  576, 1103,  576,
 /*  1660 */   543,  123,  568,  504,    4,  263,  576,  361, 1529,  111,
 /*  1670 */  1040, 1088,  576,  263,  576,  490,  121,  121,  571, 1188,
 /*  1680 */   142,  142,  169,  169,  122,  576,  452,  577,  452,  162,
 /*  1690 */   162, 1028,  576,  563,  576,  152,  152,  151,  151,  348,
 /*  1700 */  1376,  974,  452,  266, 1092,  942, 1032,  125,  149,  149,
 /*  1710 */   939,  576,  125,  576,  565,  150,  150,   86,   86,  872,
 /*  1720 */   352,  159,  576, 1028, 1028, 1030, 1031,   35,  542,  941,
 /*  1730 */   576,  125,  355,  541,   88,   88,   85,   85,  357,  359,
 /*  1740 */  1324, 1308,  366, 1040,  376,   52,   52,  499, 1389,  121,
 /*  1750 */   121, 1434, 1188,   58,   58, 1362, 1374,  122, 1439,  452,
 /*  1760 */   577,  452, 1289,  167, 1028, 1280,  280, 1268, 1267, 1269,
 /*  1770 */  1609, 1359,  312,  313,   12,  314,  397, 1421,  224, 1416,
 /*  1780 */   295,  237, 1409,  339,  340, 1426,  301,  345,  484,  228,
 /*  1790 */  1371, 1307, 1372, 1370, 1425,  404, 1028, 1028, 1030, 1031,
 /*  1800 */    35, 1601, 1192,  454,  509,  369,  292, 1502,  210, 1501,
 /*  1810 */  1369,  396,  396,  395,  277,  393,  211,  566,  859, 1612,
 /*  1820 */  1244,  123,  568,  391,    4, 1188,  223,  270, 1549, 1547,
 /*  1830 */  1241,  239,  186,  327,  422,   96,  195,  220,  571,  235,
 /*  1840 */   180,  326,  188,  468,  190, 1507,  191,  192,   92,  193,
 /*  1850 */   469,   95, 1422,   13,  502,  247, 1430,  109,  199,  402,
 /*  1860 */   476,  405,  452, 1496, 1428, 1427,   14,  491,  251,  102,
 /*  1870 */   497, 1518,  241,  281,  565,  253,  203,  354,  500,  254,
 /*  1880 */   175, 1270,  407,   43,  350,  518, 1327,  436,  255, 1326,
 /*  1890 */  1325, 1318,  104,  893, 1626,  229,  408,  440, 1625,  441,
 /*  1900 */   240,  310, 1296, 1040,  311, 1317,  527, 1594, 1297,  121,
 /*  1910 */   121,  368, 1295, 1624,  268,  269, 1580,  122, 1579,  452,
 /*  1920 */   577,  452,  374,  444, 1028, 1394, 1393,  140,  553,   90,
 /*  1930 */   568,   11,    4, 1483,  383,  414,  385,  110,  116,  216,
 /*  1940 */   320,  567, 1350,  555,   42,  318,  571,  537, 1349,  389,
 /*  1950 */   390,  579, 1198,  276,  279,  278, 1028, 1028, 1030, 1031,
 /*  1960 */    35,  580,  415, 1265,  458, 1260,  416,  185, 1534,  172,
 /*  1970 */   452, 1535,  173,  156,  308,  846, 1533, 1532,  453,  217,
 /*  1980 */   225,   89,  565,  174,  322, 1188,  226,  236, 1102,  154,
 /*  1990 */  1100,  330,  176,  187, 1223,  189,  925,  338,  243, 1116,
 /*  2000 */   246,  194,  177,  178,  425,  427,   98,   99,  196,  100,
 /*  2010 */   101, 1040,  179, 1119,  248, 1115,  249,  121,  121,   24,
 /*  2020 */   163,  250,  349, 1108,  266,  122, 1238,  452,  577,  452,
 /*  2030 */  1192,  454, 1028,  200,  292,  496,  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,  284, 1188,  286,  978,  265,  204,  125, 1171,
 /*  2100 */   241,  230,  972, 1175,   28, 1160,   29, 1179,  175, 1173,
 /*  2110 */    30,   43,   31, 1178,  241,   32,   41,  549,    8,   33,
 /*  2120 */   208,  111,  175, 1083, 1070,   43,  113, 1068,  240,  114,
 /*  2130 */  1072,   34, 1073,  561, 1124,  118,  271,   36,   18, 1194,
 /*  2140 */  1033,  873,  240,  935,  124,   37,  272,  273, 1617,  572,
 /*  2150 */   183,  153,  394, 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 */   276,  277,  278,  240,  241,  224,  194,  226,  194,  240,
 /*    10 */   241,  194,  216,  220,  194,  234,  253,  194,  255,   19,
 /*    20 */   224,  297,  253,  194,  255,  205,  212,  213,  205,  217,
 /*    30 */   218,   31,  205,  194,  217,  218,  194,  217,  218,   39,
 /*    40 */   217,  218,  312,   43,   44,   45,  316,   47,   48,   49,
 /*    50 */    50,   51,   52,   53,   54,   55,   56,   57,   58,   19,
 /*    60 */   240,  241,  194,  240,  241,  194,  254,  240,  241,  276,
 /*    70 */   277,  278,  233,  253,  254,  255,  253,  254,  255,  217,
 /*    80 */   253,  239,  255,   43,   44,   45,  263,   47,   48,   49,
 /*    90 */    50,   51,   52,   53,   54,   55,   56,   57,   58,  270,
 /*   100 */   286,   22,   23,  103,  104,  105,  106,  107,  108,  109,
 /*   110 */   110,  111,  112,  113,  114,   82,   47,   48,   49,   50,
 /*   120 */   186,  187,  188,  189,  190,  191,  189,   87,  191,   89,
 /*   130 */   196,   19,  198,  196,  317,  198,  319,   25,  194,  205,
 /*   140 */   298,  270,  205,  103,  104,  105,  106,  107,  108,  109,
 /*   150 */   110,  111,  112,  113,  114,   43,   44,   45,   11,   47,
 /*   160 */    48,   49,   50,   51,   52,   53,   54,   55,   56,   57,
 /*   170 */    58,   60,  139,  140,  240,  241,  214,  240,  241,  311,
 /*   180 */   312,  102,   70,  239,  316,  194,   19,  253,   77,  255,
 /*   190 */   253,  122,  255,   55,   56,   57,   58,   59,  207,   88,
 /*   200 */   194,   90,  268,  194,   93,  268,  107,  108,  109,  110,
 /*   210 */   111,  112,  113,  114,   47,  103,  104,  105,  106,  107,
 /*   220 */   108,  109,  110,  111,  112,  113,  114,  114,  117,  118,
 /*   230 */   119,  276,  277,  278,  300,   19,  194,  300,  276,  277,
 /*   240 */   278,  103,  104,  105,  106,  107,  108,  109,  110,  111,
 /*   250 */   112,  113,  114,   55,   56,   57,   58,  146,  194,   43,
 /*   260 */    44,   45,   47,   47,   48,   49,   50,   51,   52,   53,
 /*   270 */    54,   55,   56,   57,   58,   82,  129,  130,   60,  129,
 /*   280 */   130,  217,  218,  116,   68,   25,  103,  104,  105,  106,
 /*   290 */   107,  108,  109,  110,  111,  112,  113,  114,   23,  132,
 /*   300 */   294,  103,  104,  105,  106,  107,  108,  109,  110,  111,
 /*   310 */   112,  113,  114,  217,  121,  306,  194,  308,   26,  103,
 /*   320 */   104,  105,  106,  107,  108,  109,  110,  111,  112,  113,
 /*   330 */   114,  116,  139,  140,  217,  117,  118,  119,  120,   19,
 /*   340 */   194,  123,  124,  125,   24,  109,  110,  111,  112,  113,
 /*   350 */   114,  133,   60,  311,  312,  250,  194,  252,  316,   19,
 /*   360 */   194,  166,  167,   43,   44,   45,  205,   47,   48,   49,
 /*   370 */    50,   51,   52,   53,   54,   55,   56,   57,   58,  217,
 /*   380 */   218,  317,  318,   43,   44,   45,  264,   47,   48,   49,
 /*   390 */    50,   51,   52,   53,   54,   55,   56,   57,   58,  139,
 /*   400 */   140,  240,  241,  139,  140,  188,  189,  190,  191,  117,
 /*   410 */   118,  119,  231,  196,  253,  198,  255,  194,  194,  258,
 /*   420 */   259,  146,  205,  103,  104,  105,  106,  107,  108,  109,
 /*   430 */   110,  111,  112,  113,  114,  109,  212,  213,  236,  237,
 /*   440 */   217,  218,  194,  103,  104,  105,  106,  107,  108,  109,
 /*   450 */   110,  111,  112,  113,  114,  194,  120,  240,  241,  123,
 /*   460 */   124,  125,  136,  194,   19,   74,   60,  141,   23,  133,
 /*   470 */   253,  194,  255,   82,  194,  309,  310,  254,   29,  317,
 /*   480 */   318,  194,   33,   22,  199,  268,  263,  239,   43,   44,
 /*   490 */    45,  151,   47,   48,   49,   50,   51,   52,   53,   54,
 /*   500 */    55,   56,   57,   58,  217,  218,  194,   60,   19,  146,
 /*   510 */   286,  242,   23,  107,  108,   66,  204,  300,  206,  128,
 /*   520 */    73,   60,  116,  117,  118,  119,  265,  121,  165,   60,
 /*   530 */   139,  140,   43,   44,   45,  129,   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 */   154,  194,  156,  194,  117,  118,  119,  280,  283,  205,
 /*   570 */   101,  220,  287,   19,   20,  306,   22,  308,  117,  118,
 /*   580 */   119,  211,  212,  213,  217,  218,  117,  118,  236,  237,
 /*   590 */    36,  122,  103,  104,  105,  106,  107,  108,  109,  110,
 /*   600 */   111,  112,  113,  114,  240,  241,  194,   60,  194,  194,
 /*   610 */   194,  194,   19,  194,   60,  194,   23,  253,  206,  255,
 /*   620 */    73,  254,   19,  154,  155,  156,   72,  276,  277,  278,
 /*   630 */   263,  217,  218,  217,  218,  271,   43,   44,   45,  271,
 /*   640 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
 /*   650 */    57,   58,  183,  194,  285,  101,   19,  214,   60,  242,
 /*   660 */    23,  107,  108,  109,  117,  118,  119,   16,  254,  115,
 /*   670 */   254,  117,  118,  119,  194,   60,  122,  263,  205,  264,
 /*   680 */    43,   44,   45,  264,   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,  240,  241,  117,  118,  119,  101,  205,
 /*   720 */   117,   19,   20,  306,   22,  308,  253,   74,  255,   78,
 /*   730 */   205,   80,  117,  118,  119,  118,  293,  183,   36,  122,
 /*   740 */   103,  104,  105,  106,  107,  108,  109,  110,  111,  112,
 /*   750 */   113,  114,  194,  294,  240,  241,  211,  212,  213,  144,
 /*   760 */    19,   23,   60,   25,   23,  240,  241,  253,  245,  255,
 /*   770 */    15,  154,  155,  156,   72,  217,  218,  194,  253,  256,
 /*   780 */   255,  128,  129,  130,   43,   44,   45,   22,   47,   48,
 /*   790 */    49,   50,   51,   52,   53,   54,   55,   56,   57,   58,
 /*   800 */   183,   19,   77,  101,   19,  128,  129,  130,   23,  107,
 /*   810 */   108,   60,  254,   88,   21,   90,   61,  115,   93,  117,
 /*   820 */   118,  119,  239,   22,  122,   60,  194,  205,   43,   44,
 /*   830 */    45,  205,   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,   60,  240,  241,   60,  116,  240,  241,  117,  118,
 /*   870 */   119,  146,  194,   19,   81,  253,  275,  255,   24,  253,
 /*   880 */    98,  255,  117,  118,  119,  183,   22,  194,  103,  104,
 /*   890 */   105,  106,  107,  108,  109,  110,  111,  112,  113,  114,
 /*   900 */   151,  194,  270,  152,   22,   23,  194,   25,   19,  202,
 /*   910 */   217,  218,   23,  109,  207,  314,  315,  124,  117,  118,
 /*   920 */   119,  117,  118,  119,   60,  232,   22,   23,   19,   25,
 /*   930 */   303,  304,   43,   44,   45,   22,   47,   48,   49,   50,
 /*   940 */    51,   52,   53,   54,   55,   56,   57,   58,  270,  227,
 /*   950 */    96,   60,   43,   44,   45,  162,   47,   48,   49,   50,
 /*   960 */    51,   52,   53,   54,   55,   56,   57,   58,  114,  112,
 /*   970 */   113,  114,  194,   60,  120,  121,  122,  123,  124,  125,
 /*   980 */   126,  117,  118,  119,  102,   25,  132,  107,  108,  194,
 /*   990 */   194,  227,  103,  104,  105,  106,  107,  108,  109,  110,
 /*  1000 */   111,  112,  113,  114,  194,  194,  102,  194,  117,  118,
 /*  1010 */   119,  233,  103,  104,  105,  106,  107,  108,  109,  110,
 /*  1020 */   111,  112,  113,  114,  194,  194,   19,  194,  217,  218,
 /*  1030 */   117,  118,  119,  241,  154,  144,  156,  135,  242,  137,
 /*  1040 */   138,  130,   19,  232,  194,  253,   23,  255,  217,  218,
 /*  1050 */   217,  218,  242,   16,    7,    8,    9,   25,  261,  262,
 /*  1060 */   265,  194,   19,  232,  153,  232,   43,   44,   45,  160,
 /*  1070 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
 /*  1080 */    57,   58,  194,  227,  217,  218,   43,   44,   45,  194,
 /*  1090 */    47,   48,   49,   50,   51,   52,   53,   54,   55,   56,
 /*  1100 */    57,   58,  306,  143,  308,  217,  218,  294,   12,   77,
 /*  1110 */    22,   23,  217,  218,  194,   78,  306,   80,  308,  194,
 /*  1120 */   232,  254,   90,   27,  117,   93,  103,  104,  105,  106,
 /*  1130 */   107,  108,  109,  110,  111,  112,  113,  114,   42,  194,
 /*  1140 */    35,  194,  217,  218,  214,  194,  103,  104,  105,  106,
 /*  1150 */   107,  108,  109,  110,  111,  112,  113,  114,  194,  239,
 /*  1160 */    64,  194,  217,  218,  217,  218,  209,  210,  217,  218,
 /*  1170 */    74,  207,   67,   22,  194,   77,   19,  232,  245,  232,
 /*  1180 */    75,   24,  312,  232,  217,  218,  316,   25,   90,  256,
 /*  1190 */   102,   93,  159,  229,  161,  231,   19,  217,  218,  162,
 /*  1200 */    43,   44,   45,  160,   47,   48,   49,   50,   51,   52,
 /*  1210 */    53,   54,   55,   56,   57,   58,   19,   23,  288,   25,
 /*  1220 */    43,   44,   45,  293,   47,   48,   49,   50,   51,   52,
 /*  1230 */    53,   54,   55,   56,   57,   58,  131,   22,  275,   24,
 /*  1240 */    43,   44,   45,  194,   47,   48,   49,   50,   51,   52,
 /*  1250 */    53,   54,   55,   56,   57,   58,  194,  194,  107,  108,
 /*  1260 */   103,  104,  105,  106,  107,  108,  109,  110,  111,  112,
 /*  1270 */   113,  114,  194,   25,  194,   60,  194,  314,  315,  194,
 /*  1280 */   103,  104,  105,  106,  107,  108,  109,  110,  111,  112,
 /*  1290 */   113,  114,   19,  194,  194,  217,  218,  217,  218,   25,
 /*  1300 */   103,  104,  105,  106,  107,  108,  109,  110,  111,  112,
 /*  1310 */   113,  114,  150,  119,  265,  312,   67,  217,  218,  316,
 /*  1320 */    19,  239,  194,  194,  128,  129,  130,  265,  265,  209,
 /*  1330 */   210,   31,  254,  118,  254,   86,   60,  194,  144,   39,
 /*  1340 */    19,  130,  275,  312,   95,   44,   45,  316,   47,   48,
 /*  1350 */    49,   50,   51,   52,   53,   54,   55,   56,   57,   58,
 /*  1360 */   217,  218,   24,  194,  153,   12,   45,  119,   47,   48,
 /*  1370 */    49,   50,   51,   52,   53,   54,   55,   56,   57,   58,
 /*  1380 */    27,  314,  315,   22,  312,   24,  217,  218,  316,  116,
 /*  1390 */   117,   22,  144,   25,  118,   42,  147,  194,   60,   19,
 /*  1400 */    20,  127,   22,  194,  103,  104,  105,  106,  107,  108,
 /*  1410 */   109,  110,  111,  112,  113,  114,   36,   64,  145,  194,
 /*  1420 */   217,  218,  194,   54,  103,  104,  105,  106,  107,  108,
 /*  1430 */   109,  110,  111,  112,  113,  114,  194,   22,  310,   25,
 /*  1440 */    60,  194,  217,  218,  194,  217,  218,  194,  260,  194,
 /*  1450 */   301,  302,   72,  262,  262,  194,  118,  266,  266,  217,
 /*  1460 */   218,  194,   82,  245,  217,  218,  194,  217,  218,  194,
 /*  1470 */   217,  218,  217,  218,  256,   60,   24,  194,  217,  218,
 /*  1480 */   194,  101,  194,  245,  217,  218,  194,  107,  108,  217,
 /*  1490 */   218,   22,  217,  218,  256,  115,  245,  117,  118,  119,
 /*  1500 */   217,  218,  122,  217,  218,  217,  218,  256,   22,  217,
 /*  1510 */   218,  116,  258,  259,  146,   19,   20,  194,   22,  139,
 /*  1520 */   140,  150,  151,  136,   23,  194,   25,  194,  141,  194,
 /*  1530 */   194,   62,   36,  118,  154,  155,  156,  157,  158,  100,
 /*  1540 */   145,  194,  154,  194,  156,   49,  194,   23,  194,   25,
 /*  1550 */   217,  218,  217,  218,  194,  257,   60,  143,  194,   60,
 /*  1560 */   194,  121,  122,  183,  217,  218,  217,  218,   72,  217,
 /*  1570 */   218,  217,  218,  134,   23,  194,   25,  217,  218,    7,
 /*  1580 */     8,  321,   86,  217,  218,  194,  122,   91,   19,   20,
 /*  1590 */    23,   22,   25,   23,  142,   25,  132,  101,  217,  218,
 /*  1600 */   194,  194,  194,  107,  108,   36,  194,  194,  217,  218,
 /*  1610 */   194,  115,  194,  117,  118,  119,  194,  118,  122,  194,
 /*  1620 */    23,  194,   25,  217,  218,  217,  218,  194,  142,   60,
 /*  1630 */   217,  218,  194,  217,  218,  217,  218,   84,   85,  217,
 /*  1640 */   218,   72,  217,  218,  217,  218,   60,   23,   60,   25,
 /*  1650 */   154,  155,  156,  157,  158,   86,  154,  194,  156,  194,
 /*  1660 */    91,   19,   20,   23,   22,   25,  194,   23,  194,   25,
 /*  1670 */   101,   23,  194,   25,  194,  194,  107,  108,   36,  183,
 /*  1680 */   217,  218,  217,  218,  115,  194,  117,  118,  119,  217,
 /*  1690 */   218,  122,  194,  237,  194,  217,  218,  217,  218,  194,
 /*  1700 */   194,   23,   60,   25,  118,   23,  118,   25,  217,  218,
 /*  1710 */    23,  194,   25,  194,   72,  217,  218,  217,  218,   23,
 /*  1720 */   194,   25,  194,  154,  155,  156,  157,  158,   86,   23,
 /*  1730 */   194,   25,  194,   91,  217,  218,  217,  218,  194,  194,
 /*  1740 */   194,  194,  194,  101,  194,  217,  218,  290,  194,  107,
 /*  1750 */   108,  194,  183,  217,  218,  194,  194,  115,  194,  117,
 /*  1760 */   118,  119,  194,  243,  122,  194,  289,  194,  194,  194,
 /*  1770 */   194,  257,  257,  257,  244,  257,  192,  273,  215,  269,
 /*  1780 */   246,  299,  269,  295,  247,  273,  247,  246,  295,  230,
 /*  1790 */   261,  226,  261,  261,  273,  273,  154,  155,  156,  157,
 /*  1800 */   158,    0,    1,    2,  221,  220,    5,  220,  250,  220,
 /*  1810 */   261,   10,   11,   12,   13,   14,  250,  282,   17,  197,
 /*  1820 */    61,   19,   20,  246,   22,  183,  244,  142,  201,  201,
 /*  1830 */    38,   30,  299,   32,  201,  152,   22,  151,   36,  299,
 /*  1840 */    43,   40,  235,   18,  238,  285,  238,  238,  296,  238,
 /*  1850 */   201,  296,  274,  272,   18,  200,  235,  150,  235,  247,
 /*  1860 */   247,  247,   60,  247,  274,  274,  272,  201,  200,  159,
 /*  1870 */    63,  292,   71,  201,   72,  200,   22,  201,  222,  200,
 /*  1880 */    79,  201,  222,   82,  291,  116,  219,   65,  200,  219,
 /*  1890 */   219,  228,   22,  127,  225,  166,  222,   24,  225,  114,
 /*  1900 */    99,  284,  221,  101,  284,  228,  307,  315,  219,  107,
 /*  1910 */   108,  219,  219,  219,  201,   92,  320,  115,  320,  117,
 /*  1920 */   118,  119,  222,   83,  122,  267,  267,  149,  146,   19,
 /*  1930 */    20,   22,   22,  279,  250,  134,  201,  148,  159,  249,
 /*  1940 */   139,  140,  251,  141,   25,  281,   36,  147,  251,  248,
 /*  1950 */   247,  203,   13,  195,    6,  195,  154,  155,  156,  157,
 /*  1960 */   158,  193,  305,  193,  163,  193,  305,  302,  214,  208,
 /*  1970 */    60,  214,  208,  223,  223,    4,  214,  214,    3,   22,
 /*  1980 */   215,  214,   72,  208,  164,  183,  215,   15,   23,   16,
 /*  1990 */    23,  140,  131,  152,   25,  143,   20,   16,   24,    1,
 /*  2000 */   145,  143,  131,  131,   62,   37,   54,   54,  152,   54,
 /*  2010 */    54,  101,  131,  117,   34,    1,  142,  107,  108,   22,
 /*  2020 */     5,  116,  162,   69,   25,  115,   76,  117,  118,  119,
 /*  2030 */     1,    2,  122,   69,    5,   41,  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,   23,  183,   23,  117,   34,   22,   25,   89,
 /*  2100 */    71,  142,  144,   76,   34,   23,   34,   76,   79,   87,
 /*  2110 */    34,   82,   34,   94,   71,   34,   22,   24,   44,   34,
 /*  2120 */    25,   25,   79,   23,   23,   82,  143,   23,   99,  143,
 /*  2130 */    23,   22,   11,   25,   23,   25,   22,   22,   22,    1,
 /*  2140 */    23,   23,   99,  136,   22,   22,  142,  142,  142,   25,
 /*  2150 */    25,   23,   15,    1,  322,  322,  322,  322,  322,  322,
 /*  2160 */   322,  322,  322,  134,  322,  322,  322,  322,  139,  140,
 /*  2170 */   322,  322,  322,  322,  322,  322,  322,  134,  322,  322,
 /*  2180 */   322,  322,  139,  140,  322,  322,  322,  322,  322,  322,
 /*  2190 */   322,  322,  163,  322,  322,  322,  322,  322,  322,  322,
 /*  2200 */   322,  322,  322,  322,  322,  322,  163,  322,  322,  322,
 /*  2210 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2220 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2230 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2240 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2250 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2260 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2270 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2280 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2290 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2300 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2310 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2320 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2330 */   322,  322,  322,  322,  322,  322,  322,  322,  322,  322,
 /*  2340 */   186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
 /*  2350 */   186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
 /*  2360 */   186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
 /*  2370 */   186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
 /*  2380 */   186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
 /*  2390 */   186,  186,  186,
};
#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,   33,  391, 1496, 1569, 1642,
 /*    10 */   702,  702,  702,  193,   33,   33,   33,   33,   33,    0,
 /*    20 */     0,  216, 1177,  702,  702,  702,  702,  702,  702,  702,
 /*    30 */   702,  702,  702,  702,  702,  702,  702,  702,  406,  406,
 /*    40 */   111,  111,  218,  447,  547,  598,  598,  260,  260,  260,
 /*    50 */   260,   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,  236,  292,  598,  793,  167,  598,  598,  880,
 /*   160 */   880,  598,  857,  150,  195,  195,  195,  264,  113,  113,
 /*   170 */  2207, 2207,  854,  854,  854,  751,  765,  765,  765,  765,
 /*   180 */  1096, 1096,  725,  292,  882,  904,  598,  598,  598,  598,
 /*   190 */   598,  598,  598,  598,  598,  598,  598,  598,  598,  598,
 /*   200 */   598,  598,  598,  598,  598, 1273, 1032, 1032,  598,  147,
 /*   210 */  1098, 1098,  603,  603, 1276, 1276,  363, 2207, 2207, 2207,
 /*   220 */  2207, 2207, 2207, 2207,  469,  617,  617,  801,  336,  461,
 /*   230 */   804,  864,  615,  891,  913,  598,  598,  598,  598,  598,
 /*   240 */   598,  598,  598,  598,  598,  653,  598,  598,  598,  598,
 /*   250 */   598,  598,  598,  598,  598,  598,  598,  598, 1105, 1105,
 /*   260 */  1105,  598,  598,  598, 1194,  598,  598,  598, 1215, 1249,
 /*   270 */   598, 1353,  598,  598,  598,  598,  598,  598,  598,  598,
 /*   280 */   677,  449,  902, 1338, 1338, 1338, 1338, 1248,  902,  902,
 /*   290 */   326, 1151, 1047,  755,  749, 1371,  960, 1371, 1007, 1162,
 /*   300 */   749,  749, 1162,  749,  960, 1007, 1274,  738,  215, 1300,
 /*   310 */  1300, 1300, 1395, 1395, 1395, 1395, 1368, 1368, 1033, 1414,
 /*   320 */  1387, 1361, 1759, 1759, 1685, 1685, 1792, 1792, 1685, 1683,
 /*   330 */  1686, 1814, 1797, 1825, 1825, 1825, 1825, 1685, 1836, 1707,
 /*   340 */  1686, 1686, 1707, 1814, 1797, 1707, 1797, 1707, 1685, 1836,
 /*   350 */  1710, 1807, 1685, 1836, 1854, 1685, 1836, 1685, 1836, 1854,
 /*   360 */  1769, 1769, 1769, 1822, 1870, 1870, 1854, 1769, 1766, 1769,
 /*   370 */  1822, 1769, 1769, 1729, 1873, 1785, 1785, 1854, 1685, 1823,
 /*   380 */  1823, 1840, 1840, 1778, 1782, 1909, 1685, 1779, 1778, 1789,
 /*   390 */  1800, 1707, 1919, 1939, 1939, 1948, 1948, 1948, 2207, 2207,
 /*   400 */  2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207, 2207,
 /*   410 */  2207, 2207, 2207,   69, 1037,   79, 1088,  651, 1196, 1415,
 /*   420 */  1501, 1439, 1369, 1452,  911, 1211, 1524, 1469, 1551, 1567,
 /*   430 */  1570, 1624, 1640, 1644, 1499, 1440, 1572, 1464, 1597,  275,
 /*   440 */   782, 1586, 1648, 1678, 1553, 1682, 1687, 1388, 1502, 1696,
 /*   450 */  1706, 1588, 1486, 1971, 1975, 1957, 1820, 1972, 1973, 1965,
 /*   460 */  1967, 1851, 1841, 1861, 1969, 1969, 1974, 1852, 1976, 1855,
 /*   470 */  1981, 1998, 1858, 1871, 1969, 1872, 1942, 1968, 1969, 1856,
 /*   480 */  1952, 1953, 1955, 1956, 1881, 1896, 1980, 1874, 2014, 2015,
 /*   490 */  1997, 1905, 1860, 1954, 1999, 1964, 1950, 1994, 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, 1959,
 /*   530 */  2069, 2071, 1978, 2062, 2075, 1958, 2073, 2070, 2072, 2076,
 /*   540 */  2078, 2010, 2027, 2022, 2074, 2031, 2019, 2081, 2082, 2094,
 /*   550 */  2093, 2095, 2096, 2085, 1983, 1986, 2100, 2073, 2101, 2104,
 /*   560 */  2107, 2109, 2108, 2110, 2111, 2114, 2121, 2115, 2116, 2117,
 /*   570 */  2118, 2122, 2123, 2124, 2007, 2004, 2005, 2006, 2125, 2128,
 /*   580 */  2137, 2138, 2152,
};
#define YY_REDUCE_COUNT (412)
#define YY_REDUCE_MIN   (-276)
#define YY_REDUCE_MAX   (1775)
static const short yy_reduce_ofst[] = {
 /*     0 */   -66,  217,  -63, -177, -180,  161,  364,   64, -183,  162,
 /*    10 */   223,  367,  414, -173,  473,  514,  525,  622,  626, -207,
 /*    20 */   351, -276,  -38,  693,  811,  831,  833,  888, -188,  945,
 /*    30 */   947,  416,  558,  951,  867,  287, 1078, 1080, -186,  224,
 /*    40 */  -132,   42,  964,  269,  417,  796,  810, -237, -231, -237,
 /*    50 */  -231,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
 /*    60 */   -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
 /*    70 */   -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
 /*    80 */   -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  895,
 /*    90 */   925,  967,  980, 1100, 1143, 1169, 1203, 1225, 1228, 1242,
 /*   100 */  1247, 1250, 1253, 1255, 1261, 1267, 1272, 1275, 1283, 1286,
 /*   110 */  1288, 1292, 1333, 1335, 1347, 1349, 1352, 1354, 1360, 1366,
 /*   120 */  1381, 1391, 1406, 1408, 1413, 1416, 1418, 1422, 1425, 1427,
 /*   130 */  1463, 1465, 1472, 1478, 1480, 1491, 1498, 1500, 1517, 1519,
 /*   140 */  1528, 1536,  -45,  -45,  -45,  -45,  -45,  -45,  -45,  -45,
 /*   150 */   -45,  -45,  -45,  312, -158,  285, -219,    9,  166,  370,
 /*   160 */   545,  707,  -45,  930,  601,  963, 1067,  792,  -45,  -45,
 /*   170 */   -45,  -45, -204, -204, -204,  369, -171, -129,  632,  678,
 /*   180 */   202,  352, -270,  412,  627,  627,   -9,  122,  415,  419,
 /*   190 */   -56,  248,  583,  920,    6,  261,  459,  795, 1049,  813,
 /*   200 */  1062, 1082, -161,  778, 1063,  797,  870, 1003, 1128,  443,
 /*   210 */  1031, 1072, 1191, 1192,  957, 1120,  105, 1149,  523,  933,
 /*   220 */  1218, 1238, 1254, 1251, -138,   96,  117,  146,  181,  277,
 /*   230 */   280,  421,  480,  712,  830,  850, 1085, 1099, 1129, 1209,
 /*   240 */  1323, 1331, 1336, 1364, 1407,  368, 1412, 1433, 1438, 1474,
 /*   250 */  1481, 1505, 1506, 1526, 1538, 1544, 1545, 1546,  722,  764,
 /*   260 */   856, 1547, 1548, 1550, 1188, 1554, 1557, 1561, 1298, 1260,
 /*   270 */  1562, 1456, 1564,  280, 1568, 1571, 1573, 1574, 1575, 1576,
 /*   280 */  1457, 1477, 1520, 1514, 1515, 1516, 1518, 1188, 1520, 1520,
 /*   290 */  1530, 1563, 1584, 1482, 1504, 1510, 1534, 1513, 1488, 1537,
 /*   300 */  1512, 1521, 1539, 1522, 1541, 1493, 1583, 1559, 1565, 1585,
 /*   310 */  1587, 1589, 1529, 1531, 1532, 1549, 1558, 1566, 1535, 1577,
 /*   320 */  1582, 1622, 1533, 1540, 1627, 1628, 1552, 1555, 1633, 1560,
 /*   330 */  1578, 1581, 1607, 1606, 1608, 1609, 1611, 1649, 1655, 1612,
 /*   340 */  1590, 1591, 1613, 1594, 1621, 1614, 1623, 1616, 1666, 1668,
 /*   350 */  1579, 1593, 1672, 1675, 1656, 1676, 1679, 1680, 1688, 1660,
 /*   360 */  1667, 1670, 1671, 1663, 1669, 1673, 1674, 1689, 1681, 1692,
 /*   370 */  1677, 1693, 1694, 1592, 1599, 1617, 1620, 1700, 1713, 1596,
 /*   380 */  1598, 1658, 1659, 1691, 1684, 1654, 1735, 1664, 1697, 1690,
 /*   390 */  1701, 1703, 1748, 1758, 1760, 1768, 1770, 1772, 1657, 1661,
 /*   400 */  1665, 1761, 1754, 1757, 1762, 1763, 1764, 1750, 1751, 1765,
 /*   410 */  1771, 1767, 1775,
};
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,







|

|

|

|
|
|
|
|
|
|

|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|


|
|
|
|
|
|
|
|

|
|
|
|


|
|
|

|
|
|
|

|
|
|
|


|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|

|
|
|
|
|
|

|
|
|
|
|

|

|

|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|





|
|
|
|
|
|
|







|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|


|
|
|
|
|
|
|
|

|
|
|
|


|
|
|

|
|
|
|

|
|
|
|


|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|

|
|
|
|
|
|
|
|
|
|

|
|
|
|
|

|

|

|
|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|





|
|

|
|
|









|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|


|
|
|
|
|
|
|


|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
175629
175630
175631
175632
175633
175634
175635
175636
175637
175638
175639
175640
175641
175642
175643
175644
175645
175646
175647
175648
175649
175650
175651
175652
175653
175654
175655
175656
175657
175658
175659
175660
175661
175662
175663
175664
175665
175666
175667
175668
175669
175670
175671
175672
175673
175674
175675
175676
175677
175678
175679
175680
175681
175682
175683
175684
175685
175686
175687
175688
175689
175690
175691
175692
175693
175694
175695
175696
175697
175698
175699
175700
175701
175702
175703
175704
175705
175706
175707
175708
175709
175710
175711
175712
175713
175714
175715
175716
175717
175718
175719
175720
175721
175722
175723
175724
175725
175726
175727
175728
175729
175730
175731
175732
175733
175734
175735
175736
175737
175738
175739
175740
175741
175742
175743
175744
175745
175746
175747
175748
175749
175750
175751
175752
175753
175754
175755
175756
175757
175758
175759
175760
175761
175762
175763
175764
175765

175766
175767
175768
175769
175770
175771
175772
  /*  178 */ "SELECT_COLUMN",
  /*  179 */ "IF_NULL_ROW",
  /*  180 */ "ASTERISK",
  /*  181 */ "SPAN",
  /*  182 */ "ERROR",
  /*  183 */ "QNUMBER",
  /*  184 */ "SPACE",
  /*  185 */ "ILLEGAL",
  /*  186 */ "input",
  /*  187 */ "cmdlist",
  /*  188 */ "ecmd",
  /*  189 */ "cmdx",
  /*  190 */ "explain",
  /*  191 */ "cmd",
  /*  192 */ "transtype",
  /*  193 */ "trans_opt",
  /*  194 */ "nm",
  /*  195 */ "savepoint_opt",
  /*  196 */ "create_table",
  /*  197 */ "create_table_args",
  /*  198 */ "createkw",
  /*  199 */ "temp",
  /*  200 */ "ifnotexists",
  /*  201 */ "dbnm",
  /*  202 */ "columnlist",
  /*  203 */ "conslist_opt",
  /*  204 */ "table_option_set",
  /*  205 */ "select",
  /*  206 */ "table_option",
  /*  207 */ "columnname",
  /*  208 */ "carglist",
  /*  209 */ "typetoken",
  /*  210 */ "typename",
  /*  211 */ "signed",
  /*  212 */ "plus_num",
  /*  213 */ "minus_num",
  /*  214 */ "scanpt",
  /*  215 */ "scantok",
  /*  216 */ "ccons",
  /*  217 */ "term",
  /*  218 */ "expr",
  /*  219 */ "onconf",
  /*  220 */ "sortorder",
  /*  221 */ "autoinc",
  /*  222 */ "eidlist_opt",
  /*  223 */ "refargs",
  /*  224 */ "defer_subclause",
  /*  225 */ "generated",
  /*  226 */ "refarg",
  /*  227 */ "refact",
  /*  228 */ "init_deferred_pred_opt",
  /*  229 */ "conslist",
  /*  230 */ "tconscomma",
  /*  231 */ "tcons",
  /*  232 */ "sortlist",
  /*  233 */ "eidlist",
  /*  234 */ "defer_subclause_opt",
  /*  235 */ "orconf",
  /*  236 */ "resolvetype",
  /*  237 */ "raisetype",
  /*  238 */ "ifexists",
  /*  239 */ "fullname",
  /*  240 */ "selectnowith",
  /*  241 */ "oneselect",
  /*  242 */ "wqlist",
  /*  243 */ "multiselect_op",
  /*  244 */ "distinct",
  /*  245 */ "selcollist",
  /*  246 */ "from",
  /*  247 */ "where_opt",
  /*  248 */ "groupby_opt",
  /*  249 */ "having_opt",
  /*  250 */ "orderby_opt",
  /*  251 */ "limit_opt",
  /*  252 */ "window_clause",
  /*  253 */ "values",
  /*  254 */ "nexprlist",
  /*  255 */ "mvalues",
  /*  256 */ "sclp",
  /*  257 */ "as",
  /*  258 */ "seltablist",
  /*  259 */ "stl_prefix",
  /*  260 */ "joinop",
  /*  261 */ "on_using",
  /*  262 */ "indexed_by",
  /*  263 */ "exprlist",
  /*  264 */ "xfullname",
  /*  265 */ "idlist",
  /*  266 */ "indexed_opt",
  /*  267 */ "nulls",
  /*  268 */ "with",
  /*  269 */ "where_opt_ret",
  /*  270 */ "setlist",
  /*  271 */ "insert_cmd",
  /*  272 */ "idlist_opt",
  /*  273 */ "upsert",
  /*  274 */ "returning",
  /*  275 */ "filter_over",
  /*  276 */ "likeop",
  /*  277 */ "between_op",
  /*  278 */ "in_op",
  /*  279 */ "paren_exprlist",
  /*  280 */ "case_operand",
  /*  281 */ "case_exprlist",
  /*  282 */ "case_else",
  /*  283 */ "uniqueflag",
  /*  284 */ "collate",
  /*  285 */ "vinto",
  /*  286 */ "nmnum",
  /*  287 */ "trigger_decl",
  /*  288 */ "trigger_cmd_list",
  /*  289 */ "trigger_time",
  /*  290 */ "trigger_event",
  /*  291 */ "foreach_clause",
  /*  292 */ "when_clause",
  /*  293 */ "trigger_cmd",
  /*  294 */ "trnm",
  /*  295 */ "tridxby",
  /*  296 */ "database_kw_opt",
  /*  297 */ "key_opt",
  /*  298 */ "add_column_fullname",
  /*  299 */ "kwcolumn_opt",
  /*  300 */ "create_vtab",
  /*  301 */ "vtabarglist",
  /*  302 */ "vtabarg",
  /*  303 */ "vtabargtoken",
  /*  304 */ "lp",
  /*  305 */ "anylist",
  /*  306 */ "wqitem",
  /*  307 */ "wqas",
  /*  308 */ "withnm",
  /*  309 */ "windowdefn_list",
  /*  310 */ "windowdefn",
  /*  311 */ "window",
  /*  312 */ "frame_opt",
  /*  313 */ "part_opt",
  /*  314 */ "filter_clause",
  /*  315 */ "over_clause",
  /*  316 */ "range_or_rows",
  /*  317 */ "frame_bound",
  /*  318 */ "frame_bound_s",
  /*  319 */ "frame_bound_e",
  /*  320 */ "frame_exclude_opt",
  /*  321 */ "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[] = {







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>







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
176305
176306
176307
176308
176309
176310
176311
176312
176313
176314
176315
176316
176317
176318
176319
176320
176321
176322
176323
176324
176325
176326
176327
176328
176329
176330
176331
176332
176333
176334
176335
176336
176337
176338
176339
176340
176341
176342
176343
176344
176345
176346
176347
176348
176349
176350
176351
176352
176353
176354
176355
176356
176357
176358
176359
176360
176361
176362
176363
176364
176365
176366
176367
176368
176369
176370
176371
176372
176373
176374
176375

176376
176377
176378
176379
176380
176381
176382
176383
176384
176385
176386
176387
176388
176389
176390
176391
176392
176393
176394
176395
176396
176397
176398
176399
176400
176401
176402
176403
    ** 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 205: /* select */
    case 240: /* selectnowith */
    case 241: /* oneselect */
    case 253: /* values */
    case 255: /* mvalues */
{
sqlite3SelectDelete(pParse->db, (yypminor->yy555));
}
      break;
    case 217: /* term */
    case 218: /* expr */
    case 247: /* where_opt */
    case 249: /* having_opt */
    case 269: /* where_opt_ret */
    case 280: /* case_operand */
    case 282: /* case_else */
    case 285: /* vinto */
    case 292: /* when_clause */
    case 297: /* key_opt */
    case 314: /* filter_clause */
{
sqlite3ExprDelete(pParse->db, (yypminor->yy454));
}
      break;
    case 222: /* eidlist_opt */
    case 232: /* sortlist */
    case 233: /* eidlist */
    case 245: /* selcollist */
    case 248: /* groupby_opt */
    case 250: /* orderby_opt */
    case 254: /* nexprlist */
    case 256: /* sclp */
    case 263: /* exprlist */
    case 270: /* setlist */
    case 279: /* paren_exprlist */
    case 281: /* case_exprlist */
    case 313: /* part_opt */
{
sqlite3ExprListDelete(pParse->db, (yypminor->yy14));
}
      break;
    case 239: /* fullname */
    case 246: /* from */
    case 258: /* seltablist */
    case 259: /* stl_prefix */
    case 264: /* xfullname */
{
sqlite3SrcListDelete(pParse->db, (yypminor->yy203));
}
      break;
    case 242: /* wqlist */
{
sqlite3WithDelete(pParse->db, (yypminor->yy59));
}
      break;
    case 252: /* window_clause */
    case 309: /* windowdefn_list */
{
sqlite3WindowListDelete(pParse->db, (yypminor->yy211));
}
      break;
    case 265: /* idlist */
    case 272: /* idlist_opt */
{
sqlite3IdListDelete(pParse->db, (yypminor->yy132));
}
      break;
    case 275: /* filter_over */
    case 310: /* windowdefn */
    case 311: /* window */
    case 312: /* frame_opt */

    case 315: /* over_clause */
{
sqlite3WindowDelete(pParse->db, (yypminor->yy211));
}
      break;
    case 288: /* trigger_cmd_list */
    case 293: /* trigger_cmd */
{
sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy427));
}
      break;
    case 290: /* trigger_event */
{
sqlite3IdListDelete(pParse->db, (yypminor->yy286).b);
}
      break;
    case 317: /* frame_bound */
    case 318: /* frame_bound_s */
    case 319: /* frame_bound_e */
{
sqlite3ExprDelete(pParse->db, (yypminor->yy509).pExpr);
}
      break;
/********* End destructor definitions *****************************************/
    default:  break;   /* If no destructor action specified: do nothing */
  }
}








|
|
|
|
|

|


|
|
|
|
|
|
|
|
|
|
|

|


|
|
|
|
|
|
|
|
|
|
|
|
|

|


|
|
|
|
|

|


|

|


|
|

|


|
|

|


|
<
|
|
>
|

|


|
|

|


|

|


|
|
|

|







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
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
176790
176791
176792
176793
176794
176795
176796
176797
176798
176799
176800
176801
176802
176803
176804
176805
176806
176807
176808
176809
176810
176811
176812
176813
176814
176815
176816
176817
176818
176819
176820
176821
176822
176823
176824
176825
176826
176827
176828
176829
176830
176831
176832
176833
176834
176835
176836
176837
176838
176839
176840
176841
176842
176843
176844
176845
176846
176847
176848
176849
176850
176851
176852
176853
176854
176855
176856
176857
176858
176859
176860
176861
176862
176863
176864
176865
176866
176867
176868
176869
176870
176871
176872
176873
176874
176875
176876
176877
176878
176879
176880
176881
176882
176883
176884
176885
176886
176887
176888
176889
176890
176891
176892
176893
176894
176895
176896
176897
176898
176899
176900
176901
176902
176903
176904
176905
176906
176907
176908
176909
176910
176911
176912
176913
176914
176915
176916
176917
176918
176919
176920
176921
176922
176923
176924
176925
176926
176927
176928
176929
176930
176931
176932
176933
176934
176935
176936
176937
176938
176939
176940
176941
176942
176943
176944
176945
176946
176947
176948
176949
176950
176951
176952
176953
176954
176955
176956
176957
176958
176959
176960
176961
176962
176963
176964
176965
176966
176967
176968
176969
176970
176971
176972
176973
176974
176975
176976
176977
176978
176979
176980
176981
176982
176983
176984
176985
176986
176987
176988
176989
176990
176991
176992
176993
176994
176995
176996
176997
176998
176999
177000
177001
177002
177003
177004
177005
177006
177007
177008
177009
177010
177011
177012
177013
177014
177015
177016
177017
177018
177019
177020
177021
177022
177023
177024
177025
177026
177027
177028
177029
177030
177031
177032
177033
177034
177035
177036
177037
177038
177039
177040
177041
177042
177043
177044
177045
177046
177047
177048
177049
177050
177051
177052
177053
177054
177055
177056
177057
177058
177059
177060
177061
177062
177063
177064
177065
177066
177067
177068
177069
177070
177071
177072
177073
177074
177075
177076
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
  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[] = {
   190,  /* (0) explain ::= EXPLAIN */
   190,  /* (1) explain ::= EXPLAIN QUERY PLAN */
   189,  /* (2) cmdx ::= cmd */
   191,  /* (3) cmd ::= BEGIN transtype trans_opt */
   192,  /* (4) transtype ::= */
   192,  /* (5) transtype ::= DEFERRED */
   192,  /* (6) transtype ::= IMMEDIATE */
   192,  /* (7) transtype ::= EXCLUSIVE */
   191,  /* (8) cmd ::= COMMIT|END trans_opt */
   191,  /* (9) cmd ::= ROLLBACK trans_opt */
   191,  /* (10) cmd ::= SAVEPOINT nm */
   191,  /* (11) cmd ::= RELEASE savepoint_opt nm */
   191,  /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */
   196,  /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */
   198,  /* (14) createkw ::= CREATE */
   200,  /* (15) ifnotexists ::= */
   200,  /* (16) ifnotexists ::= IF NOT EXISTS */
   199,  /* (17) temp ::= TEMP */
   199,  /* (18) temp ::= */
   197,  /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */
   197,  /* (20) create_table_args ::= AS select */
   204,  /* (21) table_option_set ::= */
   204,  /* (22) table_option_set ::= table_option_set COMMA table_option */
   206,  /* (23) table_option ::= WITHOUT nm */
   206,  /* (24) table_option ::= nm */
   207,  /* (25) columnname ::= nm typetoken */
   209,  /* (26) typetoken ::= */
   209,  /* (27) typetoken ::= typename LP signed RP */
   209,  /* (28) typetoken ::= typename LP signed COMMA signed RP */
   210,  /* (29) typename ::= typename ID|STRING */
   214,  /* (30) scanpt ::= */
   215,  /* (31) scantok ::= */
   216,  /* (32) ccons ::= CONSTRAINT nm */
   216,  /* (33) ccons ::= DEFAULT scantok term */
   216,  /* (34) ccons ::= DEFAULT LP expr RP */
   216,  /* (35) ccons ::= DEFAULT PLUS scantok term */
   216,  /* (36) ccons ::= DEFAULT MINUS scantok term */
   216,  /* (37) ccons ::= DEFAULT scantok ID|INDEXED */
   216,  /* (38) ccons ::= NOT NULL onconf */
   216,  /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */
   216,  /* (40) ccons ::= UNIQUE onconf */
   216,  /* (41) ccons ::= CHECK LP expr RP */
   216,  /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */
   216,  /* (43) ccons ::= defer_subclause */
   216,  /* (44) ccons ::= COLLATE ID|STRING */
   225,  /* (45) generated ::= LP expr RP */
   225,  /* (46) generated ::= LP expr RP ID */
   221,  /* (47) autoinc ::= */
   221,  /* (48) autoinc ::= AUTOINCR */
   223,  /* (49) refargs ::= */
   223,  /* (50) refargs ::= refargs refarg */
   226,  /* (51) refarg ::= MATCH nm */
   226,  /* (52) refarg ::= ON INSERT refact */
   226,  /* (53) refarg ::= ON DELETE refact */
   226,  /* (54) refarg ::= ON UPDATE refact */
   227,  /* (55) refact ::= SET NULL */
   227,  /* (56) refact ::= SET DEFAULT */
   227,  /* (57) refact ::= CASCADE */
   227,  /* (58) refact ::= RESTRICT */
   227,  /* (59) refact ::= NO ACTION */
   224,  /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
   224,  /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */
   228,  /* (62) init_deferred_pred_opt ::= */
   228,  /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */
   228,  /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
   203,  /* (65) conslist_opt ::= */
   230,  /* (66) tconscomma ::= COMMA */
   231,  /* (67) tcons ::= CONSTRAINT nm */
   231,  /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
   231,  /* (69) tcons ::= UNIQUE LP sortlist RP onconf */
   231,  /* (70) tcons ::= CHECK LP expr RP onconf */
   231,  /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */
   234,  /* (72) defer_subclause_opt ::= */
   219,  /* (73) onconf ::= */
   219,  /* (74) onconf ::= ON CONFLICT resolvetype */
   235,  /* (75) orconf ::= */
   235,  /* (76) orconf ::= OR resolvetype */
   236,  /* (77) resolvetype ::= IGNORE */
   236,  /* (78) resolvetype ::= REPLACE */
   191,  /* (79) cmd ::= DROP TABLE ifexists fullname */
   238,  /* (80) ifexists ::= IF EXISTS */
   238,  /* (81) ifexists ::= */
   191,  /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */
   191,  /* (83) cmd ::= DROP VIEW ifexists fullname */
   191,  /* (84) cmd ::= select */
   205,  /* (85) select ::= WITH wqlist selectnowith */
   205,  /* (86) select ::= WITH RECURSIVE wqlist selectnowith */
   205,  /* (87) select ::= selectnowith */
   240,  /* (88) selectnowith ::= selectnowith multiselect_op oneselect */
   243,  /* (89) multiselect_op ::= UNION */
   243,  /* (90) multiselect_op ::= UNION ALL */
   243,  /* (91) multiselect_op ::= EXCEPT|INTERSECT */
   241,  /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
   241,  /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
   253,  /* (94) values ::= VALUES LP nexprlist RP */
   241,  /* (95) oneselect ::= mvalues */
   255,  /* (96) mvalues ::= values COMMA LP nexprlist RP */
   255,  /* (97) mvalues ::= mvalues COMMA LP nexprlist RP */
   244,  /* (98) distinct ::= DISTINCT */
   244,  /* (99) distinct ::= ALL */
   244,  /* (100) distinct ::= */
   256,  /* (101) sclp ::= */
   245,  /* (102) selcollist ::= sclp scanpt expr scanpt as */
   245,  /* (103) selcollist ::= sclp scanpt STAR */
   245,  /* (104) selcollist ::= sclp scanpt nm DOT STAR */
   257,  /* (105) as ::= AS nm */
   257,  /* (106) as ::= */
   246,  /* (107) from ::= */
   246,  /* (108) from ::= FROM seltablist */
   259,  /* (109) stl_prefix ::= seltablist joinop */
   259,  /* (110) stl_prefix ::= */
   258,  /* (111) seltablist ::= stl_prefix nm dbnm as on_using */
   258,  /* (112) seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
   258,  /* (113) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
   258,  /* (114) seltablist ::= stl_prefix LP select RP as on_using */
   258,  /* (115) seltablist ::= stl_prefix LP seltablist RP as on_using */
   201,  /* (116) dbnm ::= */
   201,  /* (117) dbnm ::= DOT nm */
   239,  /* (118) fullname ::= nm */
   239,  /* (119) fullname ::= nm DOT nm */
   264,  /* (120) xfullname ::= nm */
   264,  /* (121) xfullname ::= nm DOT nm */
   264,  /* (122) xfullname ::= nm DOT nm AS nm */
   264,  /* (123) xfullname ::= nm AS nm */
   260,  /* (124) joinop ::= COMMA|JOIN */
   260,  /* (125) joinop ::= JOIN_KW JOIN */
   260,  /* (126) joinop ::= JOIN_KW nm JOIN */
   260,  /* (127) joinop ::= JOIN_KW nm nm JOIN */
   261,  /* (128) on_using ::= ON expr */
   261,  /* (129) on_using ::= USING LP idlist RP */
   261,  /* (130) on_using ::= */
   266,  /* (131) indexed_opt ::= */
   262,  /* (132) indexed_by ::= INDEXED BY nm */
   262,  /* (133) indexed_by ::= NOT INDEXED */
   250,  /* (134) orderby_opt ::= */
   250,  /* (135) orderby_opt ::= ORDER BY sortlist */
   232,  /* (136) sortlist ::= sortlist COMMA expr sortorder nulls */
   232,  /* (137) sortlist ::= expr sortorder nulls */
   220,  /* (138) sortorder ::= ASC */
   220,  /* (139) sortorder ::= DESC */
   220,  /* (140) sortorder ::= */
   267,  /* (141) nulls ::= NULLS FIRST */
   267,  /* (142) nulls ::= NULLS LAST */
   267,  /* (143) nulls ::= */
   248,  /* (144) groupby_opt ::= */
   248,  /* (145) groupby_opt ::= GROUP BY nexprlist */
   249,  /* (146) having_opt ::= */
   249,  /* (147) having_opt ::= HAVING expr */
   251,  /* (148) limit_opt ::= */
   251,  /* (149) limit_opt ::= LIMIT expr */
   251,  /* (150) limit_opt ::= LIMIT expr OFFSET expr */
   251,  /* (151) limit_opt ::= LIMIT expr COMMA expr */
   191,  /* (152) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
   247,  /* (153) where_opt ::= */
   247,  /* (154) where_opt ::= WHERE expr */
   269,  /* (155) where_opt_ret ::= */
   269,  /* (156) where_opt_ret ::= WHERE expr */
   269,  /* (157) where_opt_ret ::= RETURNING selcollist */
   269,  /* (158) where_opt_ret ::= WHERE expr RETURNING selcollist */
   191,  /* (159) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
   270,  /* (160) setlist ::= setlist COMMA nm EQ expr */
   270,  /* (161) setlist ::= setlist COMMA LP idlist RP EQ expr */
   270,  /* (162) setlist ::= nm EQ expr */
   270,  /* (163) setlist ::= LP idlist RP EQ expr */
   191,  /* (164) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
   191,  /* (165) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
   273,  /* (166) upsert ::= */
   273,  /* (167) upsert ::= RETURNING selcollist */
   273,  /* (168) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
   273,  /* (169) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
   273,  /* (170) upsert ::= ON CONFLICT DO NOTHING returning */
   273,  /* (171) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
   274,  /* (172) returning ::= RETURNING selcollist */
   271,  /* (173) insert_cmd ::= INSERT orconf */
   271,  /* (174) insert_cmd ::= REPLACE */
   272,  /* (175) idlist_opt ::= */
   272,  /* (176) idlist_opt ::= LP idlist RP */
   265,  /* (177) idlist ::= idlist COMMA nm */
   265,  /* (178) idlist ::= nm */
   218,  /* (179) expr ::= LP expr RP */
   218,  /* (180) expr ::= ID|INDEXED|JOIN_KW */
   218,  /* (181) expr ::= nm DOT nm */
   218,  /* (182) expr ::= nm DOT nm DOT nm */
   217,  /* (183) term ::= NULL|FLOAT|BLOB */
   217,  /* (184) term ::= STRING */
   217,  /* (185) term ::= INTEGER */
   218,  /* (186) expr ::= VARIABLE */
   218,  /* (187) expr ::= expr COLLATE ID|STRING */
   218,  /* (188) expr ::= CAST LP expr AS typetoken RP */
   218,  /* (189) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
   218,  /* (190) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
   218,  /* (191) expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
   218,  /* (192) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
   218,  /* (193) expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
   218,  /* (194) expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
   217,  /* (195) term ::= CTIME_KW */
   218,  /* (196) expr ::= LP nexprlist COMMA expr RP */
   218,  /* (197) expr ::= expr AND expr */
   218,  /* (198) expr ::= expr OR expr */
   218,  /* (199) expr ::= expr LT|GT|GE|LE expr */
   218,  /* (200) expr ::= expr EQ|NE expr */
   218,  /* (201) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */
   218,  /* (202) expr ::= expr PLUS|MINUS expr */
   218,  /* (203) expr ::= expr STAR|SLASH|REM expr */
   218,  /* (204) expr ::= expr CONCAT expr */
   276,  /* (205) likeop ::= NOT LIKE_KW|MATCH */
   218,  /* (206) expr ::= expr likeop expr */
   218,  /* (207) expr ::= expr likeop expr ESCAPE expr */
   218,  /* (208) expr ::= expr ISNULL|NOTNULL */
   218,  /* (209) expr ::= expr NOT NULL */
   218,  /* (210) expr ::= expr IS expr */
   218,  /* (211) expr ::= expr IS NOT expr */
   218,  /* (212) expr ::= expr IS NOT DISTINCT FROM expr */
   218,  /* (213) expr ::= expr IS DISTINCT FROM expr */
   218,  /* (214) expr ::= NOT expr */
   218,  /* (215) expr ::= BITNOT expr */
   218,  /* (216) expr ::= PLUS|MINUS expr */
   218,  /* (217) expr ::= expr PTR expr */
   277,  /* (218) between_op ::= BETWEEN */
   277,  /* (219) between_op ::= NOT BETWEEN */
   218,  /* (220) expr ::= expr between_op expr AND expr */
   278,  /* (221) in_op ::= IN */
   278,  /* (222) in_op ::= NOT IN */
   218,  /* (223) expr ::= expr in_op LP exprlist RP */
   218,  /* (224) expr ::= LP select RP */
   218,  /* (225) expr ::= expr in_op LP select RP */
   218,  /* (226) expr ::= expr in_op nm dbnm paren_exprlist */
   218,  /* (227) expr ::= EXISTS LP select RP */
   218,  /* (228) expr ::= CASE case_operand case_exprlist case_else END */
   281,  /* (229) case_exprlist ::= case_exprlist WHEN expr THEN expr */
   281,  /* (230) case_exprlist ::= WHEN expr THEN expr */
   282,  /* (231) case_else ::= ELSE expr */
   282,  /* (232) case_else ::= */
   280,  /* (233) case_operand ::= */
   263,  /* (234) exprlist ::= */
   254,  /* (235) nexprlist ::= nexprlist COMMA expr */
   254,  /* (236) nexprlist ::= expr */
   279,  /* (237) paren_exprlist ::= */
   279,  /* (238) paren_exprlist ::= LP exprlist RP */
   191,  /* (239) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */
   283,  /* (240) uniqueflag ::= UNIQUE */
   283,  /* (241) uniqueflag ::= */
   222,  /* (242) eidlist_opt ::= */
   222,  /* (243) eidlist_opt ::= LP eidlist RP */
   233,  /* (244) eidlist ::= eidlist COMMA nm collate sortorder */
   233,  /* (245) eidlist ::= nm collate sortorder */
   284,  /* (246) collate ::= */
   284,  /* (247) collate ::= COLLATE ID|STRING */
   191,  /* (248) cmd ::= DROP INDEX ifexists fullname */
   191,  /* (249) cmd ::= VACUUM vinto */
   191,  /* (250) cmd ::= VACUUM nm vinto */
   285,  /* (251) vinto ::= INTO expr */
   285,  /* (252) vinto ::= */
   191,  /* (253) cmd ::= PRAGMA nm dbnm */
   191,  /* (254) cmd ::= PRAGMA nm dbnm EQ nmnum */
   191,  /* (255) cmd ::= PRAGMA nm dbnm LP nmnum RP */
   191,  /* (256) cmd ::= PRAGMA nm dbnm EQ minus_num */
   191,  /* (257) cmd ::= PRAGMA nm dbnm LP minus_num RP */
   212,  /* (258) plus_num ::= PLUS INTEGER|FLOAT */
   213,  /* (259) minus_num ::= MINUS INTEGER|FLOAT */
   191,  /* (260) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */
   287,  /* (261) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
   289,  /* (262) trigger_time ::= BEFORE|AFTER */
   289,  /* (263) trigger_time ::= INSTEAD OF */
   289,  /* (264) trigger_time ::= */
   290,  /* (265) trigger_event ::= DELETE|INSERT */
   290,  /* (266) trigger_event ::= UPDATE */
   290,  /* (267) trigger_event ::= UPDATE OF idlist */
   292,  /* (268) when_clause ::= */
   292,  /* (269) when_clause ::= WHEN expr */
   288,  /* (270) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
   288,  /* (271) trigger_cmd_list ::= trigger_cmd SEMI */
   294,  /* (272) trnm ::= nm DOT nm */
   295,  /* (273) tridxby ::= INDEXED BY nm */
   295,  /* (274) tridxby ::= NOT INDEXED */
   293,  /* (275) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */
   293,  /* (276) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
   293,  /* (277) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
   293,  /* (278) trigger_cmd ::= scanpt select scanpt */
   218,  /* (279) expr ::= RAISE LP IGNORE RP */
   218,  /* (280) expr ::= RAISE LP raisetype COMMA expr RP */
   237,  /* (281) raisetype ::= ROLLBACK */
   237,  /* (282) raisetype ::= ABORT */
   237,  /* (283) raisetype ::= FAIL */
   191,  /* (284) cmd ::= DROP TRIGGER ifexists fullname */
   191,  /* (285) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
   191,  /* (286) cmd ::= DETACH database_kw_opt expr */
   297,  /* (287) key_opt ::= */
   297,  /* (288) key_opt ::= KEY expr */
   191,  /* (289) cmd ::= REINDEX */
   191,  /* (290) cmd ::= REINDEX nm dbnm */
   191,  /* (291) cmd ::= ANALYZE */
   191,  /* (292) cmd ::= ANALYZE nm dbnm */
   191,  /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */
   191,  /* (294) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */
   191,  /* (295) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
   298,  /* (296) add_column_fullname ::= fullname */
   191,  /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
   191,  /* (298) cmd ::= create_vtab */
   191,  /* (299) cmd ::= create_vtab LP vtabarglist RP */
   300,  /* (300) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
   302,  /* (301) vtabarg ::= */
   303,  /* (302) vtabargtoken ::= ANY */
   303,  /* (303) vtabargtoken ::= lp anylist RP */
   304,  /* (304) lp ::= LP */
   268,  /* (305) with ::= WITH wqlist */
   268,  /* (306) with ::= WITH RECURSIVE wqlist */
   307,  /* (307) wqas ::= AS */
   307,  /* (308) wqas ::= AS MATERIALIZED */
   307,  /* (309) wqas ::= AS NOT MATERIALIZED */
   306,  /* (310) wqitem ::= withnm eidlist_opt wqas LP select RP */
   308,  /* (311) withnm ::= nm */
   242,  /* (312) wqlist ::= wqitem */
   242,  /* (313) wqlist ::= wqlist COMMA wqitem */
   309,  /* (314) windowdefn_list ::= windowdefn_list COMMA windowdefn */
   310,  /* (315) windowdefn ::= nm AS LP window RP */
   311,  /* (316) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
   311,  /* (317) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
   311,  /* (318) window ::= ORDER BY sortlist frame_opt */
   311,  /* (319) window ::= nm ORDER BY sortlist frame_opt */
   311,  /* (320) window ::= nm frame_opt */
   312,  /* (321) frame_opt ::= */
   312,  /* (322) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
   312,  /* (323) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
   316,  /* (324) range_or_rows ::= RANGE|ROWS|GROUPS */
   318,  /* (325) frame_bound_s ::= frame_bound */
   318,  /* (326) frame_bound_s ::= UNBOUNDED PRECEDING */
   319,  /* (327) frame_bound_e ::= frame_bound */
   319,  /* (328) frame_bound_e ::= UNBOUNDED FOLLOWING */
   317,  /* (329) frame_bound ::= expr PRECEDING|FOLLOWING */
   317,  /* (330) frame_bound ::= CURRENT ROW */
   320,  /* (331) frame_exclude_opt ::= */
   320,  /* (332) frame_exclude_opt ::= EXCLUDE frame_exclude */
   321,  /* (333) frame_exclude ::= NO OTHERS */
   321,  /* (334) frame_exclude ::= CURRENT ROW */
   321,  /* (335) frame_exclude ::= GROUP|TIES */
   252,  /* (336) window_clause ::= WINDOW windowdefn_list */
   275,  /* (337) filter_over ::= filter_clause over_clause */
   275,  /* (338) filter_over ::= over_clause */
   275,  /* (339) filter_over ::= filter_clause */
   315,  /* (340) over_clause ::= OVER LP window RP */
   315,  /* (341) over_clause ::= OVER nm */
   314,  /* (342) filter_clause ::= FILTER LP WHERE expr RP */
   217,  /* (343) term ::= QNUMBER */
   186,  /* (344) input ::= cmdlist */
   187,  /* (345) cmdlist ::= cmdlist ecmd */
   187,  /* (346) cmdlist ::= ecmd */
   188,  /* (347) ecmd ::= SEMI */
   188,  /* (348) ecmd ::= cmdx SEMI */
   188,  /* (349) ecmd ::= explain cmdx SEMI */
   193,  /* (350) trans_opt ::= */
   193,  /* (351) trans_opt ::= TRANSACTION */
   193,  /* (352) trans_opt ::= TRANSACTION nm */
   195,  /* (353) savepoint_opt ::= SAVEPOINT */
   195,  /* (354) savepoint_opt ::= */
   191,  /* (355) cmd ::= create_table create_table_args */
   204,  /* (356) table_option_set ::= table_option */
   202,  /* (357) columnlist ::= columnlist COMMA columnname carglist */
   202,  /* (358) columnlist ::= columnname carglist */
   194,  /* (359) nm ::= ID|INDEXED|JOIN_KW */
   194,  /* (360) nm ::= STRING */
   209,  /* (361) typetoken ::= typename */
   210,  /* (362) typename ::= ID|STRING */
   211,  /* (363) signed ::= plus_num */
   211,  /* (364) signed ::= minus_num */
   208,  /* (365) carglist ::= carglist ccons */
   208,  /* (366) carglist ::= */
   216,  /* (367) ccons ::= NULL onconf */
   216,  /* (368) ccons ::= GENERATED ALWAYS AS generated */
   216,  /* (369) ccons ::= AS generated */
   203,  /* (370) conslist_opt ::= COMMA conslist */
   229,  /* (371) conslist ::= conslist tconscomma tcons */
   229,  /* (372) conslist ::= tcons */
   230,  /* (373) tconscomma ::= */
   234,  /* (374) defer_subclause_opt ::= defer_subclause */
   236,  /* (375) resolvetype ::= raisetype */
   240,  /* (376) selectnowith ::= oneselect */
   241,  /* (377) oneselect ::= values */
   256,  /* (378) sclp ::= selcollist COMMA */
   257,  /* (379) as ::= ID|STRING */
   266,  /* (380) indexed_opt ::= indexed_by */
   274,  /* (381) returning ::= */
   218,  /* (382) expr ::= term */
   276,  /* (383) likeop ::= LIKE_KW|MATCH */
   280,  /* (384) case_operand ::= expr */
   263,  /* (385) exprlist ::= nexprlist */
   286,  /* (386) nmnum ::= plus_num */
   286,  /* (387) nmnum ::= nm */
   286,  /* (388) nmnum ::= ON */
   286,  /* (389) nmnum ::= DELETE */
   286,  /* (390) nmnum ::= DEFAULT */
   212,  /* (391) plus_num ::= INTEGER|FLOAT */
   291,  /* (392) foreach_clause ::= */
   291,  /* (393) foreach_clause ::= FOR EACH ROW */
   294,  /* (394) trnm ::= nm */
   295,  /* (395) tridxby ::= */
   296,  /* (396) database_kw_opt ::= DATABASE */
   296,  /* (397) database_kw_opt ::= */
   299,  /* (398) kwcolumn_opt ::= */
   299,  /* (399) kwcolumn_opt ::= COLUMNKW */
   301,  /* (400) vtabarglist ::= vtabarg */
   301,  /* (401) vtabarglist ::= vtabarglist COMMA vtabarg */
   302,  /* (402) vtabarg ::= vtabarg vtabargtoken */
   305,  /* (403) anylist ::= */
   305,  /* (404) anylist ::= anylist LP anylist RP */
   305,  /* (405) anylist ::= anylist ANY */
   268,  /* (406) with ::= */
   309,  /* (407) windowdefn_list ::= windowdefn */
   311,  /* (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 */







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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
177572
177573
177574
177575
177576
177577
177578
177579
177580
177581
177582
177583
177584
177585
177586
177587
177588
      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.yy144);}
        break;
      case 4: /* transtype ::= */
{yymsp[1].minor.yy144 = 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.yy144 = 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 */
{







|


|





|







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
177604
177605
177606
177607

177608

177609
177610
177611
177612
177613
177614
177615
177616
177617
177618
177619
177620
177621
177622
177623
177624
177625
177626
177627
177628
177629
177630
177631
177632
177633
177634
177635
177636
177637
177638
177639
177640
177641
177642
177643
177644
177645
177646
177647
177648
177649
177650
177651
177652
177653
177654
177655
177656
177657
177658
177659
177660
177661
177662
177663
177664
177665
177666
177667
177668
177669
177670
      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.yy144,0,0,yymsp[-2].minor.yy144);
}
        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.yy144 = 0;}
        break;
      case 16: /* ifnotexists ::= IF NOT EXISTS */
{yymsp[-2].minor.yy144 = 1;}
        break;
      case 17: /* temp ::= TEMP */
{yymsp[0].minor.yy144 = 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.yy391,0);
}
        break;
      case 20: /* create_table_args ::= AS select */
{
  sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy555);
  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555);
}
        break;
      case 21: /* table_option_set ::= */
{yymsp[1].minor.yy391 = 0;}
        break;
      case 22: /* table_option_set ::= table_option_set COMMA table_option */
{yylhsminor.yy391 = yymsp[-2].minor.yy391|yymsp[0].minor.yy391;}
  yymsp[-2].minor.yy391 = yylhsminor.yy391;
        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.yy391 = TF_WithoutRowid | TF_NoVisibleRowid;
  }else{
    yymsp[-1].minor.yy391 = 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.yy391 = TF_Strict;
  }else{
    yylhsminor.yy391 = 0;
    sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
  }
}
  yymsp[0].minor.yy391 = yylhsminor.yy391;
        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);







|



>
|
>









|


|


|



|




|
|



|


|
|




|

|







|

|



|







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
177689
177690
177691
177692
177693
177694
177695
177696
177697
177698
177699
177700
177701
177702
177703
177704
177705
177706
177707
177708
177709
177710
177711
177712
177713
177714
177715
177716
177717
177718
177719
177720
177721
177722
177723
177724
177725
177726
177727
177728
177729
177730
177731
177732
177733
177734
177735
177736
177737
177738
177739
177740
177741
177742
177743
177744
177745
177746
177747
177748
177749
177750
177751
177752
177753
177754
177755
177756
177757
177758
177759
177760
177761
177762
177763
177764
177765
177766
177767
177768
177769
177770
177771
177772
177773
177774
177775
177776
177777
177778
177779
177780
177781
177782
177783
177784
177785
177786
177787
177788
177789
177790
177791
177792
177793
177794
177795
177796
177797
177798
177799
177800
177801
177802
177803
177804
177805
177806
177807
177808
177809
177810
177811
177812
177813
177814
177815
177816
177817
177818
177819
177820
177821
177822
177823
177824
177825
177826
177827
177828
177829
177830
177831
177832
177833
177834
177835
177836
177837
177838
177839
177840
177841
177842
177843
177844
177845
177846
177847
177848
177849
177850
177851
177852
177853
177854
177855
177856
177857
177858
177859
177860
177861
177862
177863
177864
177865
177866
177867
177868
177869
177870
177871
177872
177873
177874
177875
177876
177877
177878
177879
177880
177881
177882
177883
177884
177885
177886
177887
177888
177889
177890
177891
177892
177893
177894
177895
177896
177897
177898
177899
177900
177901
177902
177903
177904
177905
177906
177907
177908
177909
177910
177911
177912
177913
177914
177915
177916
177917
177918
177919
177920
177921
177922
177923
177924
177925
177926
177927
177928
177929
177930
177931
177932
177933
177934
177935
177936
177937
177938
177939
177940
177941
177942
177943
177944
177945
177946
177947
177948
177949
177950
177951
177952
177953
177954
177955
177956
177957
177958
177959
177960
177961
177962
177963
177964
177965
177966
177967
177968
177969
177970
177971
177972
177973
177974
177975
177976
177977
177978
177979
177980
177981
177982
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
        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.yy168 = 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);
{pParse->constraintName = yymsp[0].minor.yy0;}
        break;
      case 33: /* ccons ::= DEFAULT scantok term */
{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,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.yy454,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);}
        break;
      case 35: /* ccons ::= DEFAULT PLUS scantok term */
{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy454,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.yy454, 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.yy144);}
        break;
      case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */
{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy144,yymsp[0].minor.yy144,yymsp[-2].minor.yy144);}
        break;
      case 40: /* ccons ::= UNIQUE onconf */
{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy144,0,0,0,0,
                                   SQLITE_IDXTYPE_UNIQUE);}
        break;
      case 41: /* ccons ::= CHECK LP expr RP */
{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy454,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.yy14,yymsp[0].minor.yy144);}
        break;
      case 43: /* ccons ::= defer_subclause */
{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy144);}
        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.yy454,0);}
        break;
      case 46: /* generated ::= LP expr RP ID */
{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy454,&yymsp[0].minor.yy0);}
        break;
      case 48: /* autoinc ::= AUTOINCR */
{yymsp[0].minor.yy144 = 1;}
        break;
      case 49: /* refargs ::= */
{ yymsp[1].minor.yy144 = OE_None*0x0101; /* EV: R-19803-45884 */}
        break;
      case 50: /* refargs ::= refargs refarg */
{ yymsp[-1].minor.yy144 = (yymsp[-1].minor.yy144 & ~yymsp[0].minor.yy383.mask) | yymsp[0].minor.yy383.value; }
        break;
      case 51: /* refarg ::= MATCH nm */
{ yymsp[-1].minor.yy383.value = 0;     yymsp[-1].minor.yy383.mask = 0x000000; }
        break;
      case 52: /* refarg ::= ON INSERT refact */
{ yymsp[-2].minor.yy383.value = 0;     yymsp[-2].minor.yy383.mask = 0x000000; }
        break;
      case 53: /* refarg ::= ON DELETE refact */
{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144;     yymsp[-2].minor.yy383.mask = 0x0000ff; }
        break;
      case 54: /* refarg ::= ON UPDATE refact */
{ yymsp[-2].minor.yy383.value = yymsp[0].minor.yy144<<8;  yymsp[-2].minor.yy383.mask = 0x00ff00; }
        break;
      case 55: /* refact ::= SET NULL */
{ yymsp[-1].minor.yy144 = OE_SetNull;  /* EV: R-33326-45252 */}
        break;
      case 56: /* refact ::= SET DEFAULT */
{ yymsp[-1].minor.yy144 = OE_SetDflt;  /* EV: R-33326-45252 */}
        break;
      case 57: /* refact ::= CASCADE */
{ yymsp[0].minor.yy144 = OE_Cascade;  /* EV: R-33326-45252 */}
        break;
      case 58: /* refact ::= RESTRICT */
{ yymsp[0].minor.yy144 = OE_Restrict; /* EV: R-33326-45252 */}
        break;
      case 59: /* refact ::= NO ACTION */
{ yymsp[-1].minor.yy144 = OE_None;     /* EV: R-33326-45252 */}
        break;
      case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */
{yymsp[-2].minor.yy144 = 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.yy144 = yymsp[0].minor.yy144;}
        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.yy144 = 1;}
        break;
      case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */
{yymsp[-1].minor.yy144 = 0;}
        break;
      case 66: /* tconscomma ::= COMMA */
{pParse->constraintName.n = 0;}
        break;
      case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */
{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy144,yymsp[-2].minor.yy144,0);}
        break;
      case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */
{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy144,0,0,0,0,
                                       SQLITE_IDXTYPE_UNIQUE);}
        break;
      case 70: /* tcons ::= CHECK LP expr RP onconf */
{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy454,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.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy144);
    sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy144);
}
        break;
      case 73: /* onconf ::= */
      case 75: /* orconf ::= */ yytestcase(yyruleno==75);
{yymsp[1].minor.yy144 = OE_Default;}
        break;
      case 74: /* onconf ::= ON CONFLICT resolvetype */
{yymsp[-2].minor.yy144 = yymsp[0].minor.yy144;}
        break;
      case 77: /* resolvetype ::= IGNORE */
{yymsp[0].minor.yy144 = OE_Ignore;}
        break;
      case 78: /* resolvetype ::= REPLACE */
      case 174: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==174);
{yymsp[0].minor.yy144 = OE_Replace;}
        break;
      case 79: /* cmd ::= DROP TABLE ifexists fullname */
{
  sqlite3DropTable(pParse, yymsp[0].minor.yy203, 0, yymsp[-1].minor.yy144);
}
        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.yy14, yymsp[0].minor.yy555, yymsp[-7].minor.yy144, yymsp[-5].minor.yy144);
}
        break;
      case 83: /* cmd ::= DROP VIEW ifexists fullname */
{
  sqlite3DropTable(pParse, yymsp[0].minor.yy203, 1, yymsp[-1].minor.yy144);
}
        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.yy555, &dest);
  }
  sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy555);
}
        break;
      case 85: /* select ::= WITH wqlist selectnowith */
{yymsp[-2].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);}
        break;
      case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */
{yymsp[-3].minor.yy555 = attachWithToSelect(pParse,yymsp[0].minor.yy555,yymsp[-1].minor.yy59);}
        break;
      case 87: /* select ::= selectnowith */
{
  Select *p = yymsp[0].minor.yy555;
  if( p ){
    parserDoubleLinkSelect(pParse, p);
  }
}
        break;
      case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */
{
  Select *pRhs = yymsp[0].minor.yy555;
  Select *pLhs = yymsp[-2].minor.yy555;
  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.yy144;
    pRhs->pPrior = pLhs;
    if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
    pRhs->selFlags &= ~SF_MultiValue;
    if( yymsp[-1].minor.yy144!=TK_ALL ) pParse->hasCompound = 1;
  }else{
    sqlite3SelectDelete(pParse->db, pLhs);
  }
  yymsp[-2].minor.yy555 = pRhs;
}
        break;
      case 89: /* multiselect_op ::= UNION */
      case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91);
{yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-OP*/}
        break;
      case 90: /* multiselect_op ::= UNION ALL */
{yymsp[-1].minor.yy144 = TK_ALL;}
        break;
      case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */
{
  yymsp[-8].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy203,yymsp[-4].minor.yy454,yymsp[-3].minor.yy14,yymsp[-2].minor.yy454,yymsp[-1].minor.yy14,yymsp[-7].minor.yy144,yymsp[0].minor.yy454);
}
        break;
      case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */
{
  yymsp[-9].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy14,yymsp[-6].minor.yy203,yymsp[-5].minor.yy454,yymsp[-4].minor.yy14,yymsp[-3].minor.yy454,yymsp[-1].minor.yy14,yymsp[-8].minor.yy144,yymsp[0].minor.yy454);
  if( yymsp[-9].minor.yy555 ){
    yymsp[-9].minor.yy555->pWinDefn = yymsp[-2].minor.yy211;
  }else{
    sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy211);
  }
}
        break;
      case 94: /* values ::= VALUES LP nexprlist RP */
{
  yymsp[-3].minor.yy555 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0);
}
        break;
      case 95: /* oneselect ::= mvalues */
{
  sqlite3MultiValuesEnd(pParse, yymsp[0].minor.yy555);
}
        break;
      case 96: /* mvalues ::= values COMMA LP nexprlist RP */
      case 97: /* mvalues ::= mvalues COMMA LP nexprlist RP */ yytestcase(yyruleno==97);
{
  yymsp[-4].minor.yy555 = sqlite3MultiValues(pParse, yymsp[-4].minor.yy555, yymsp[-1].minor.yy14);
}
        break;
      case 98: /* distinct ::= DISTINCT */
{yymsp[0].minor.yy144 = SF_Distinct;}
        break;
      case 99: /* distinct ::= ALL */
{yymsp[0].minor.yy144 = 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.yy14 = 0;}
        break;
      case 102: /* selcollist ::= sclp scanpt expr scanpt as */
{
   yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[-2].minor.yy454);
   if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[0].minor.yy0, 1);
   sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy14,yymsp[-3].minor.yy168,yymsp[-1].minor.yy168);
}
        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.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, 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.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, 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.yy203 = 0;}
        break;
      case 108: /* from ::= FROM seltablist */
{
  yymsp[-1].minor.yy203 = yymsp[0].minor.yy203;
  sqlite3SrcListShiftJoinType(pParse,yymsp[-1].minor.yy203);
}
        break;
      case 109: /* stl_prefix ::= seltablist joinop */
{
   if( ALWAYS(yymsp[-1].minor.yy203 && yymsp[-1].minor.yy203->nSrc>0) ) yymsp[-1].minor.yy203->a[yymsp[-1].minor.yy203->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy144;
}
        break;
      case 111: /* seltablist ::= stl_prefix nm dbnm as on_using */
{
  yymsp[-4].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-4].minor.yy203,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
}
        break;
      case 112: /* seltablist ::= stl_prefix nm dbnm as indexed_by on_using */
{
  yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,&yymsp[0].minor.yy269);
  sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-1].minor.yy0);
}
        break;
      case 113: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_using */
{
  yymsp[-7].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-7].minor.yy203,&yymsp[-6].minor.yy0,&yymsp[-5].minor.yy0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
  sqlite3SrcListFuncArgs(pParse, yymsp[-7].minor.yy203, yymsp[-3].minor.yy14);
}
        break;
      case 114: /* seltablist ::= stl_prefix LP select RP as on_using */
{
    yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,yymsp[-3].minor.yy555,&yymsp[0].minor.yy269);
  }
        break;
      case 115: /* seltablist ::= stl_prefix LP seltablist RP as on_using */
{
    if( yymsp[-5].minor.yy203==0 && yymsp[-1].minor.yy0.n==0 && yymsp[0].minor.yy269.pOn==0 && yymsp[0].minor.yy269.pUsing==0 ){
      yymsp[-5].minor.yy203 = yymsp[-3].minor.yy203;
    }else if( ALWAYS(yymsp[-3].minor.yy203!=0) && yymsp[-3].minor.yy203->nSrc==1 ){
      yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,0,&yymsp[0].minor.yy269);
      if( yymsp[-5].minor.yy203 ){
        SrcItem *pNew = &yymsp[-5].minor.yy203->a[yymsp[-5].minor.yy203->nSrc-1];
        SrcItem *pOld = yymsp[-3].minor.yy203->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;







|










|


|


|


|



|














|


|


|



|


|


|





|


|


|


|


|


|


|


|


|


|


|


|


|


|


|




|






|


|


|


|


|



|



|
|




|


|


|



|



|




|




|








|

|



|


|



|







|
|









|



|



|




|


|



|




|
|
|

|





|




|





|



|


|







|



|
|
|






|









|










|



|
|




|




|




|
|




|
|




|




|
|
|
|
|
|
|







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
178058
178059
178060
178061
178062
178063
178064
178065
178066
178067
178068
178069
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
178429
178430
178431
178432
178433
178434
178435
178436
178437
178438
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
          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.yy203);
    }else{
      Select *pSubquery;
      sqlite3SrcListShiftJoinType(pParse,yymsp[-3].minor.yy203);
      pSubquery = sqlite3SelectNew(pParse,0,yymsp[-3].minor.yy203,0,0,0,0,SF_NestedFrom,0);
      yymsp[-5].minor.yy203 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy203,0,0,&yymsp[-1].minor.yy0,pSubquery,&yymsp[0].minor.yy269);
    }
  }
        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.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0);
  if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0);
}
  yymsp[0].minor.yy203 = yylhsminor.yy203;
        break;
      case 119: /* fullname ::= nm DOT nm */
{
  yylhsminor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
  if( IN_RENAME_OBJECT && yylhsminor.yy203 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy203->a[0].zName, &yymsp[0].minor.yy0);
}
  yymsp[-2].minor.yy203 = yylhsminor.yy203;
        break;
      case 120: /* xfullname ::= nm */
{yymsp[0].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/}
        break;
      case 121: /* xfullname ::= nm DOT nm */
{yymsp[-2].minor.yy203 = 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.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/
   if( yymsp[-4].minor.yy203 ) yymsp[-4].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
        break;
      case 123: /* xfullname ::= nm AS nm */
{
   yymsp[-2].minor.yy203 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/
   if( yymsp[-2].minor.yy203 ) yymsp[-2].minor.yy203->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0);
}
        break;
      case 124: /* joinop ::= COMMA|JOIN */
{ yymsp[0].minor.yy144 = JT_INNER; }
        break;
      case 125: /* joinop ::= JOIN_KW JOIN */
{yymsp[-1].minor.yy144 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0);  /*X-overwrites-A*/}
        break;
      case 126: /* joinop ::= JOIN_KW nm JOIN */
{yymsp[-2].minor.yy144 = 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.yy144 = 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.yy269.pOn = yymsp[0].minor.yy454; yymsp[-1].minor.yy269.pUsing = 0;}
        break;
      case 129: /* on_using ::= USING LP idlist RP */
{yymsp[-3].minor.yy269.pOn = 0; yymsp[-3].minor.yy269.pUsing = yymsp[-1].minor.yy132;}
        break;
      case 130: /* on_using ::= */
{yymsp[1].minor.yy269.pOn = 0; yymsp[1].minor.yy269.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.yy14 = yymsp[0].minor.yy14;}
        break;
      case 136: /* sortlist ::= sortlist COMMA expr sortorder nulls */
{
  yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14,yymsp[-2].minor.yy454);
  sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144);
}
        break;
      case 137: /* sortlist ::= expr sortorder nulls */
{
  yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy454); /*A-overwrites-Y*/
  sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy14,yymsp[-1].minor.yy144,yymsp[0].minor.yy144);
}
        break;
      case 138: /* sortorder ::= ASC */
{yymsp[0].minor.yy144 = SQLITE_SO_ASC;}
        break;
      case 139: /* sortorder ::= DESC */
{yymsp[0].minor.yy144 = SQLITE_SO_DESC;}
        break;
      case 140: /* sortorder ::= */
      case 143: /* nulls ::= */ yytestcase(yyruleno==143);
{yymsp[1].minor.yy144 = SQLITE_SO_UNDEFINED;}
        break;
      case 141: /* nulls ::= NULLS FIRST */
{yymsp[-1].minor.yy144 = SQLITE_SO_ASC;}
        break;
      case 142: /* nulls ::= NULLS LAST */
{yymsp[-1].minor.yy144 = 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.yy454 = 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.yy454 = yymsp[0].minor.yy454;}
        break;
      case 149: /* limit_opt ::= LIMIT expr */
{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,0);}
        break;
      case 150: /* limit_opt ::= LIMIT expr OFFSET expr */
{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
        break;
      case 151: /* limit_opt ::= LIMIT expr COMMA expr */
{yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy454,yymsp[-2].minor.yy454);}
        break;
      case 152: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */
{
  sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy203, &yymsp[-1].minor.yy0);
  sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy203,yymsp[0].minor.yy454,0,0);
}
        break;
      case 157: /* where_opt_ret ::= RETURNING selcollist */
{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-1].minor.yy454 = 0;}
        break;
      case 158: /* where_opt_ret ::= WHERE expr RETURNING selcollist */
{sqlite3AddReturning(pParse,yymsp[0].minor.yy14); yymsp[-3].minor.yy454 = yymsp[-2].minor.yy454;}
        break;
      case 159: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */
{
  sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy203, &yymsp[-4].minor.yy0);
  sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy14,"set list");
  if( yymsp[-1].minor.yy203 ){
    SrcList *pFromClause = yymsp[-1].minor.yy203;
    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.yy203 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy203, pFromClause);
  }
  sqlite3Update(pParse,yymsp[-5].minor.yy203,yymsp[-2].minor.yy14,yymsp[0].minor.yy454,yymsp[-6].minor.yy144,0,0,0);
}
        break;
      case 160: /* setlist ::= setlist COMMA nm EQ expr */
{
  yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy454);
  sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, 1);
}
        break;
      case 161: /* setlist ::= setlist COMMA LP idlist RP EQ expr */
{
  yymsp[-6].minor.yy14 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy14, yymsp[-3].minor.yy132, yymsp[0].minor.yy454);
}
        break;
      case 162: /* setlist ::= nm EQ expr */
{
  yylhsminor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy454);
  sqlite3ExprListSetName(pParse, yylhsminor.yy14, &yymsp[-2].minor.yy0, 1);
}
  yymsp[-2].minor.yy14 = yylhsminor.yy14;
        break;
      case 163: /* setlist ::= LP idlist RP EQ expr */
{
  yymsp[-4].minor.yy14 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy132, yymsp[0].minor.yy454);
}
        break;
      case 164: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */
{
  sqlite3Insert(pParse, yymsp[-3].minor.yy203, yymsp[-1].minor.yy555, yymsp[-2].minor.yy132, yymsp[-5].minor.yy144, yymsp[0].minor.yy122);
}
        break;
      case 165: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */
{
  sqlite3Insert(pParse, yymsp[-4].minor.yy203, 0, yymsp[-3].minor.yy132, yymsp[-6].minor.yy144, 0);
}
        break;
      case 166: /* upsert ::= */
{ yymsp[1].minor.yy122 = 0; }
        break;
      case 167: /* upsert ::= RETURNING selcollist */
{ yymsp[-1].minor.yy122 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy14); }
        break;
      case 168: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */
{ yymsp[-11].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy14,yymsp[-6].minor.yy454,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,yymsp[0].minor.yy122);}
        break;
      case 169: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */
{ yymsp[-8].minor.yy122 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy14,yymsp[-3].minor.yy454,0,0,yymsp[0].minor.yy122); }
        break;
      case 170: /* upsert ::= ON CONFLICT DO NOTHING returning */
{ yymsp[-4].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); }
        break;
      case 171: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */
{ yymsp[-7].minor.yy122 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454,0);}
        break;
      case 172: /* returning ::= RETURNING selcollist */
{sqlite3AddReturning(pParse,yymsp[0].minor.yy14);}
        break;
      case 175: /* idlist_opt ::= */
{yymsp[1].minor.yy132 = 0;}
        break;
      case 176: /* idlist_opt ::= LP idlist RP */
{yymsp[-2].minor.yy132 = yymsp[-1].minor.yy132;}
        break;
      case 177: /* idlist ::= idlist COMMA nm */
{yymsp[-2].minor.yy132 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy132,&yymsp[0].minor.yy0);}
        break;
      case 178: /* idlist ::= nm */
{yymsp[0].minor.yy132 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/}
        break;
      case 179: /* expr ::= LP expr RP */
{yymsp[-2].minor.yy454 = yymsp[-1].minor.yy454;}
        break;
      case 180: /* expr ::= ID|INDEXED|JOIN_KW */
{yymsp[0].minor.yy454=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.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
  yymsp[-2].minor.yy454 = yylhsminor.yy454;
        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.yy454 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
  yymsp[-4].minor.yy454 = yylhsminor.yy454;
        break;
      case 183: /* term ::= NULL|FLOAT|BLOB */
      case 184: /* term ::= STRING */ yytestcase(yyruleno==184);
{yymsp[0].minor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/}
        break;
      case 185: /* term ::= INTEGER */
{
  yylhsminor.yy454 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1);
  if( yylhsminor.yy454 ) yylhsminor.yy454->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail);
}
  yymsp[0].minor.yy454 = yylhsminor.yy454;
        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.yy454 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0);
    sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy454, 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.yy454 = 0;
    }else{
      yymsp[0].minor.yy454 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
      if( yymsp[0].minor.yy454 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy454->iTable);
    }
  }
}
        break;
      case 187: /* expr ::= expr COLLATE ID|STRING */
{
  yymsp[-2].minor.yy454 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy454, &yymsp[0].minor.yy0, 1);
}
        break;
      case 188: /* expr ::= CAST LP expr AS typetoken RP */
{
  yymsp[-5].minor.yy454 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1);
  sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy454, yymsp[-3].minor.yy454, 0);
}
        break;
      case 189: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP */
{
  yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy144);
}
  yymsp[-4].minor.yy454 = yylhsminor.yy454;
        break;
      case 190: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP */
{
  yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-4].minor.yy14, &yymsp[-7].minor.yy0, yymsp[-5].minor.yy144);
  sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-1].minor.yy14);
}
  yymsp[-7].minor.yy454 = yylhsminor.yy454;
        break;
      case 191: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP */
{
  yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0);
}
  yymsp[-3].minor.yy454 = yylhsminor.yy454;
        break;
      case 192: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist RP filter_over */
{
  yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy14, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy144);
  sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
}
  yymsp[-5].minor.yy454 = yylhsminor.yy454;
        break;
      case 193: /* expr ::= ID|INDEXED|JOIN_KW LP distinct exprlist ORDER BY sortlist RP filter_over */
{
  yylhsminor.yy454 = sqlite3ExprFunction(pParse, yymsp[-5].minor.yy14, &yymsp[-8].minor.yy0, yymsp[-6].minor.yy144);
  sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
  sqlite3ExprAddFunctionOrderBy(pParse, yylhsminor.yy454, yymsp[-2].minor.yy14);
}
  yymsp[-8].minor.yy454 = yylhsminor.yy454;
        break;
      case 194: /* expr ::= ID|INDEXED|JOIN_KW LP STAR RP filter_over */
{
  yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0);
  sqlite3WindowAttach(pParse, yylhsminor.yy454, yymsp[0].minor.yy211);
}
  yymsp[-4].minor.yy454 = yylhsminor.yy454;
        break;
      case 195: /* term ::= CTIME_KW */
{
  yylhsminor.yy454 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0);
}
  yymsp[0].minor.yy454 = yylhsminor.yy454;
        break;
      case 196: /* expr ::= LP nexprlist COMMA expr RP */
{
  ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454);
  yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
  if( yymsp[-4].minor.yy454 ){
    yymsp[-4].minor.yy454->x.pList = pList;
    if( ALWAYS(pList->nExpr) ){
      yymsp[-4].minor.yy454->flags |= pList->a[0].pExpr->flags & EP_Propagate;
    }
  }else{
    sqlite3ExprListDelete(pParse->db, pList);
  }
}
        break;
      case 197: /* expr ::= expr AND expr */
{yymsp[-2].minor.yy454=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
        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.yy454=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);}
        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.yy454);
  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy454);
  yymsp[-2].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
  if( bNot ) yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy454, 0);
  if( yymsp[-2].minor.yy454 ) yymsp[-2].minor.yy454->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.yy454);
  pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy454);
  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454);
  yymsp[-4].minor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0);
  if( bNot ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
  if( yymsp[-4].minor.yy454 ) yymsp[-4].minor.yy454->flags |= EP_InfixFunc;
}
        break;
      case 208: /* expr ::= expr ISNULL|NOTNULL */
{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy454,0);}
        break;
      case 209: /* expr ::= expr NOT NULL */
{yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy454,0);}
        break;
      case 210: /* expr ::= expr IS expr */
{
  yymsp[-2].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy454,yymsp[0].minor.yy454);
  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-2].minor.yy454, TK_ISNULL);
}
        break;
      case 211: /* expr ::= expr IS NOT expr */
{
  yymsp[-3].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy454,yymsp[0].minor.yy454);
  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-3].minor.yy454, TK_NOTNULL);
}
        break;
      case 212: /* expr ::= expr IS NOT DISTINCT FROM expr */
{
  yymsp[-5].minor.yy454 = sqlite3PExpr(pParse,TK_IS,yymsp[-5].minor.yy454,yymsp[0].minor.yy454);
  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-5].minor.yy454, TK_ISNULL);
}
        break;
      case 213: /* expr ::= expr IS DISTINCT FROM expr */
{
  yymsp[-4].minor.yy454 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-4].minor.yy454,yymsp[0].minor.yy454);
  binaryToUnaryIfNull(pParse, yymsp[0].minor.yy454, yymsp[-4].minor.yy454, TK_NOTNULL);
}
        break;
      case 214: /* expr ::= NOT expr */
      case 215: /* expr ::= BITNOT expr */ yytestcase(yyruleno==215);
{yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy454, 0);/*A-overwrites-B*/}
        break;
      case 216: /* expr ::= PLUS|MINUS expr */
{
  Expr *p = yymsp[0].minor.yy454;
  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.yy454 = p;
  }else{
    yymsp[-1].minor.yy454 = sqlite3PExpr(pParse, op, p, 0);
    /*A-overwrites-B*/
  }
}
        break;
      case 217: /* expr ::= expr PTR expr */
{
  ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy454);
  pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy454);
  yylhsminor.yy454 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0);
}
  yymsp[-2].minor.yy454 = yylhsminor.yy454;
        break;
      case 218: /* between_op ::= BETWEEN */
      case 221: /* in_op ::= IN */ yytestcase(yyruleno==221);
{yymsp[0].minor.yy144 = 0;}
        break;
      case 220: /* expr ::= expr between_op expr AND expr */
{
  ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
  pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy454);
  yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy454, 0);
  if( yymsp[-4].minor.yy454 ){
    yymsp[-4].minor.yy454->x.pList = pList;
  }else{
    sqlite3ExprListDelete(pParse->db, pList);
  }
  if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
}
        break;
      case 223: /* expr ::= expr in_op LP exprlist RP */
{
    if( yymsp[-1].minor.yy14==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.yy454);
      yymsp[-4].minor.yy454 = sqlite3Expr(pParse->db, TK_STRING, yymsp[-3].minor.yy144 ? "true" : "false");
      if( yymsp[-4].minor.yy454 ) sqlite3ExprIdToTrueFalse(yymsp[-4].minor.yy454);
    }else{
      Expr *pRHS = yymsp[-1].minor.yy14->a[0].pExpr;
      if( yymsp[-1].minor.yy14->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && yymsp[-4].minor.yy454->op!=TK_VECTOR ){
        yymsp[-1].minor.yy14->a[0].pExpr = 0;
        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
        pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
        yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy454, pRHS);
      }else if( yymsp[-1].minor.yy14->nExpr==1 && pRHS->op==TK_SELECT ){
        yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
        sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pRHS->x.pSelect);
        pRHS->x.pSelect = 0;
        sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
      }else{
        yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
        if( yymsp[-4].minor.yy454==0 ){
          sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
        }else if( yymsp[-4].minor.yy454->pLeft->op==TK_VECTOR ){
          int nExpr = yymsp[-4].minor.yy454->pLeft->x.pList->nExpr;
          Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy14);
          if( pSelectRHS ){
            parserDoubleLinkSelect(pParse, pSelectRHS);
            sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelectRHS);
          }
        }else{
          yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy14;
          sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454);
        }
      }
      if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
    }
  }
        break;
      case 224: /* expr ::= LP select RP */
{
    yymsp[-2].minor.yy454 = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
    sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy454, yymsp[-1].minor.yy555);
  }
        break;
      case 225: /* expr ::= expr in_op LP select RP */
{
    yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, yymsp[-1].minor.yy555);
    if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 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.yy14 )  sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy14);
    yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy454, 0);
    sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy454, pSelect);
    if( yymsp[-3].minor.yy144 ) yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy454, 0);
  }
        break;
      case 227: /* expr ::= EXISTS LP select RP */
{
    Expr *p;
    p = yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
    sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy555);
  }
        break;
      case 228: /* expr ::= CASE case_operand case_exprlist case_else END */
{
  yymsp[-4].minor.yy454 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy454, 0);
  if( yymsp[-4].minor.yy454 ){
    yymsp[-4].minor.yy454->x.pList = yymsp[-1].minor.yy454 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy454) : yymsp[-2].minor.yy14;
    sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy454);
  }else{
    sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14);
    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454);
  }
}
        break;
      case 229: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */
{
  yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy454);
  yymsp[-4].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[0].minor.yy454);
}
        break;
      case 230: /* case_exprlist ::= WHEN expr THEN expr */
{
  yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy454);
  yymsp[-3].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, yymsp[0].minor.yy454);
}
        break;
      case 235: /* nexprlist ::= nexprlist COMMA expr */
{yymsp[-2].minor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy454);}
        break;
      case 236: /* nexprlist ::= expr */
{yymsp[0].minor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy454); /*A-overwrites-Y*/}
        break;
      case 238: /* paren_exprlist ::= LP exprlist RP */
      case 243: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==243);
{yymsp[-2].minor.yy14 = yymsp[-1].minor.yy14;}
        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.yy14, yymsp[-10].minor.yy144,
                      &yymsp[-11].minor.yy0, yymsp[0].minor.yy454, SQLITE_SO_ASC, yymsp[-8].minor.yy144, 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.yy144 = OE_Abort;}
        break;
      case 241: /* uniqueflag ::= */
{yymsp[1].minor.yy144 = OE_None;}
        break;
      case 244: /* eidlist ::= eidlist COMMA nm collate sortorder */
{
  yymsp[-4].minor.yy14 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy14, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144);
}
        break;
      case 245: /* eidlist ::= nm collate sortorder */
{
  yymsp[-2].minor.yy14 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy144, yymsp[0].minor.yy144); /*A-overwrites-Y*/
}
        break;
      case 248: /* cmd ::= DROP INDEX ifexists fullname */
{sqlite3DropIndex(pParse, yymsp[0].minor.yy203, yymsp[-1].minor.yy144);}
        break;
      case 249: /* cmd ::= VACUUM vinto */
{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy454);}
        break;
      case 250: /* cmd ::= VACUUM nm vinto */
{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy454);}
        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;







|


|
|
|









|
|

|



|
|

|


|


|



|
|




|
|



|


|


|


|


|


|


|









|



|
|




|
|



|


|



|


|


|








|






|


|


|


|



|
|



|


|



|
|
|
|








|

|




|
|




|




|
|

|



|




|




|



|


|


|


|


|


|


|


|


|


|


|


|


|





|

|










|

|



|



|
|

|





|
|








|

|
|






|




|
|




|

|



|
|

|



|

|



|
|

|



|
|
|

|



|
|

|



|

|



|
|
|
|

|







|








|









|
|
|
|
|







|
|
|
|
|
|



|


|



|
|




|
|




|
|




|
|




|



|





|

|






|
|
|

|



|



|
|
|
|
|



|




|








|
|
|

|
|
|
|

|
|
|
|

|

|
|
|
|
|
|


|


|
|


|





|
|




|
|
|






|
|
|
|





|
|




|
|
|
|

|
|





|
|




|
|



|


|



|




|
|







|


|



|




|



|


|


|







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
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
{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.yy427, &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.yy144, yymsp[-4].minor.yy286.a, yymsp[-4].minor.yy286.b, yymsp[-2].minor.yy203, yymsp[0].minor.yy454, yymsp[-10].minor.yy144, yymsp[-8].minor.yy144);
  yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/




}
        break;
      case 262: /* trigger_time ::= BEFORE|AFTER */
{ yymsp[0].minor.yy144 = yymsp[0].major; /*A-overwrites-X*/ }
        break;
      case 263: /* trigger_time ::= INSTEAD OF */
{ yymsp[-1].minor.yy144 = TK_INSTEAD;}
        break;
      case 264: /* trigger_time ::= */
{ yymsp[1].minor.yy144 = TK_BEFORE; }
        break;
      case 265: /* trigger_event ::= DELETE|INSERT */
      case 266: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==266);
{yymsp[0].minor.yy286.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy286.b = 0;}
        break;
      case 267: /* trigger_event ::= UPDATE OF idlist */
{yymsp[-2].minor.yy286.a = TK_UPDATE; yymsp[-2].minor.yy286.b = yymsp[0].minor.yy132;}
        break;
      case 268: /* when_clause ::= */
      case 287: /* key_opt ::= */ yytestcase(yyruleno==287);
{ yymsp[1].minor.yy454 = 0; }
        break;
      case 269: /* when_clause ::= WHEN expr */
      case 288: /* key_opt ::= KEY expr */ yytestcase(yyruleno==288);
{ yymsp[-1].minor.yy454 = yymsp[0].minor.yy454; }
        break;
      case 270: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */
{
  assert( yymsp[-2].minor.yy427!=0 );
  yymsp[-2].minor.yy427->pLast->pNext = yymsp[-1].minor.yy427;
  yymsp[-2].minor.yy427->pLast = yymsp[-1].minor.yy427;
}
        break;
      case 271: /* trigger_cmd_list ::= trigger_cmd SEMI */
{
  assert( yymsp[-1].minor.yy427!=0 );
  yymsp[-1].minor.yy427->pLast = yymsp[-1].minor.yy427;
}
        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 "







|




|

>
>
>
>



|


|


|



|


|



|



|



|
|
|




|
|







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
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
{
  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.yy427 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy203, yymsp[-3].minor.yy14, yymsp[-1].minor.yy454, yymsp[-7].minor.yy144, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy168);}
  yymsp[-8].minor.yy427 = yylhsminor.yy427;
        break;
      case 276: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */
{
   yylhsminor.yy427 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy132,yymsp[-2].minor.yy555,yymsp[-6].minor.yy144,yymsp[-1].minor.yy122,yymsp[-7].minor.yy168,yymsp[0].minor.yy168);/*yylhsminor.yy427-overwrites-yymsp[-6].minor.yy144*/
}
  yymsp[-7].minor.yy427 = yylhsminor.yy427;
        break;
      case 277: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */
{yylhsminor.yy427 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy454, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy168);}
  yymsp[-5].minor.yy427 = yylhsminor.yy427;
        break;
      case 278: /* trigger_cmd ::= scanpt select scanpt */
{yylhsminor.yy427 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy555, yymsp[-2].minor.yy168, yymsp[0].minor.yy168); /*yylhsminor.yy427-overwrites-yymsp[-1].minor.yy555*/}
  yymsp[-2].minor.yy427 = yylhsminor.yy427;
        break;
      case 279: /* expr ::= RAISE LP IGNORE RP */
{
  yymsp[-3].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
  if( yymsp[-3].minor.yy454 ){
    yymsp[-3].minor.yy454->affExpr = OE_Ignore;
  }
}
        break;
      case 280: /* expr ::= RAISE LP raisetype COMMA expr RP */
{
  yymsp[-5].minor.yy454 = sqlite3PExpr(pParse, TK_RAISE, yymsp[-1].minor.yy454, 0);
  if( yymsp[-5].minor.yy454 ) {
    yymsp[-5].minor.yy454->affExpr = (char)yymsp[-3].minor.yy144;
  }
}
        break;
      case 281: /* raisetype ::= ROLLBACK */
{yymsp[0].minor.yy144 = OE_Rollback;}
        break;
      case 283: /* raisetype ::= FAIL */
{yymsp[0].minor.yy144 = OE_Fail;}
        break;
      case 284: /* cmd ::= DROP TRIGGER ifexists fullname */
{
  sqlite3DropTrigger(pParse,yymsp[0].minor.yy203,yymsp[-1].minor.yy144);
}
        break;
      case 285: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */
{
  sqlite3Attach(pParse, yymsp[-3].minor.yy454, yymsp[-1].minor.yy454, yymsp[0].minor.yy454);
}
        break;
      case 286: /* cmd ::= DETACH database_kw_opt expr */
{
  sqlite3Detach(pParse, yymsp[0].minor.yy454);
}
        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.yy203,&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.yy203, &yymsp[0].minor.yy0);
}
        break;
      case 296: /* add_column_fullname ::= fullname */
{
  disableLookaside(pParse);
  sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy203);
}
        break;
      case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
{
  sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy203, &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.yy144);
}
        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.yy59, 1); }
        break;
      case 307: /* wqas ::= AS */
{yymsp[0].minor.yy462 = M10d_Any;}
        break;
      case 308: /* wqas ::= AS MATERIALIZED */
{yymsp[-1].minor.yy462 = M10d_Yes;}
        break;
      case 309: /* wqas ::= AS NOT MATERIALIZED */
{yymsp[-2].minor.yy462 = M10d_No;}
        break;
      case 310: /* wqitem ::= withnm eidlist_opt wqas LP select RP */
{
  yymsp[-5].minor.yy67 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy14, yymsp[-1].minor.yy555, yymsp[-3].minor.yy462); /*A-overwrites-X*/
}
        break;
      case 311: /* withnm ::= nm */
{pParse->bHasWith = 1;}
        break;
      case 312: /* wqlist ::= wqitem */
{
  yymsp[0].minor.yy59 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy67); /*A-overwrites-X*/
}
        break;
      case 313: /* wqlist ::= wqlist COMMA wqitem */
{
  yymsp[-2].minor.yy59 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy59, yymsp[0].minor.yy67);
}
        break;
      case 314: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
{
  assert( yymsp[0].minor.yy211!=0 );
  sqlite3WindowChain(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy211);
  yymsp[0].minor.yy211->pNextWin = yymsp[-2].minor.yy211;
  yylhsminor.yy211 = yymsp[0].minor.yy211;
}
  yymsp[-2].minor.yy211 = yylhsminor.yy211;
        break;
      case 315: /* windowdefn ::= nm AS LP window RP */
{
  if( ALWAYS(yymsp[-1].minor.yy211) ){
    yymsp[-1].minor.yy211->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
  }
  yylhsminor.yy211 = yymsp[-1].minor.yy211;
}
  yymsp[-4].minor.yy211 = yylhsminor.yy211;
        break;
      case 316: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
{
  yymsp[-4].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, 0);
}
        break;
      case 317: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
{
  yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, yymsp[-2].minor.yy14, yymsp[-1].minor.yy14, &yymsp[-5].minor.yy0);
}
  yymsp[-5].minor.yy211 = yylhsminor.yy211;
        break;
      case 318: /* window ::= ORDER BY sortlist frame_opt */
{
  yymsp[-3].minor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, 0);
}
        break;
      case 319: /* window ::= nm ORDER BY sortlist frame_opt */
{
  yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
}
  yymsp[-4].minor.yy211 = yylhsminor.yy211;
        break;
      case 320: /* window ::= nm frame_opt */
{
  yylhsminor.yy211 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy211, 0, 0, &yymsp[-1].minor.yy0);
}
  yymsp[-1].minor.yy211 = yylhsminor.yy211;
        break;
      case 321: /* frame_opt ::= */
{
  yymsp[1].minor.yy211 = 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.yy211 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy144, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy462);
}
  yymsp[-2].minor.yy211 = yylhsminor.yy211;
        break;
      case 323: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
{
  yylhsminor.yy211 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy144, yymsp[-3].minor.yy509.eType, yymsp[-3].minor.yy509.pExpr, yymsp[-1].minor.yy509.eType, yymsp[-1].minor.yy509.pExpr, yymsp[0].minor.yy462);
}
  yymsp[-5].minor.yy211 = yylhsminor.yy211;
        break;
      case 325: /* frame_bound_s ::= frame_bound */
      case 327: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==327);
{yylhsminor.yy509 = yymsp[0].minor.yy509;}
  yymsp[0].minor.yy509 = yylhsminor.yy509;
        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.yy509.eType = yymsp[-1].major; yylhsminor.yy509.pExpr = 0;}
  yymsp[-1].minor.yy509 = yylhsminor.yy509;
        break;
      case 329: /* frame_bound ::= expr PRECEDING|FOLLOWING */
{yylhsminor.yy509.eType = yymsp[0].major; yylhsminor.yy509.pExpr = yymsp[-1].minor.yy454;}
  yymsp[-1].minor.yy509 = yylhsminor.yy509;
        break;
      case 331: /* frame_exclude_opt ::= */
{yymsp[1].minor.yy462 = 0;}
        break;
      case 332: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
{yymsp[-1].minor.yy462 = yymsp[0].minor.yy462;}
        break;
      case 333: /* frame_exclude ::= NO OTHERS */
      case 334: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==334);
{yymsp[-1].minor.yy462 = yymsp[-1].major; /*A-overwrites-X*/}
        break;
      case 335: /* frame_exclude ::= GROUP|TIES */
{yymsp[0].minor.yy462 = yymsp[0].major; /*A-overwrites-X*/}
        break;
      case 336: /* window_clause ::= WINDOW windowdefn_list */
{ yymsp[-1].minor.yy211 = yymsp[0].minor.yy211; }
        break;
      case 337: /* filter_over ::= filter_clause over_clause */
{
  if( yymsp[0].minor.yy211 ){
    yymsp[0].minor.yy211->pFilter = yymsp[-1].minor.yy454;
  }else{
    sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy454);
  }
  yylhsminor.yy211 = yymsp[0].minor.yy211;
}
  yymsp[-1].minor.yy211 = yylhsminor.yy211;
        break;
      case 338: /* filter_over ::= over_clause */
{
  yylhsminor.yy211 = yymsp[0].minor.yy211;
}
  yymsp[0].minor.yy211 = yylhsminor.yy211;
        break;
      case 339: /* filter_over ::= filter_clause */
{
  yylhsminor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  if( yylhsminor.yy211 ){
    yylhsminor.yy211->eFrmType = TK_FILTER;
    yylhsminor.yy211->pFilter = yymsp[0].minor.yy454;
  }else{
    sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy454);
  }
}
  yymsp[0].minor.yy211 = yylhsminor.yy211;
        break;
      case 340: /* over_clause ::= OVER LP window RP */
{
  yymsp[-3].minor.yy211 = yymsp[-1].minor.yy211;
  assert( yymsp[-3].minor.yy211!=0 );
}
        break;
      case 341: /* over_clause ::= OVER nm */
{
  yymsp[-1].minor.yy211 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  if( yymsp[-1].minor.yy211 ){
    yymsp[-1].minor.yy211->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.yy454 = yymsp[-1].minor.yy454; }
        break;
      case 343: /* term ::= QNUMBER */
{
  yylhsminor.yy454=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0);
  sqlite3DequoteNumber(pParse, yylhsminor.yy454);
}
  yymsp[0].minor.yy454 = yylhsminor.yy454;
        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);







|
|



|

|


|
|


|
|



|
|
|





|
|
|




|


|



|




|




|
















|










|





|




|










|












|


|


|


|



|







|




|




|
|
|
|

|



|
|

|

|



|




|

|



|




|

|



|

|



|




|

|



|

|



|
|




|
|


|
|


|


|



|


|


|



|
|

|

|

|



|

|



|
|
|
|

|


|



|
|




|
|
|




|



|
|

|







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
180234
180235
180236
180237
180238
180239
180240
180241
      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_SPACE;   /* IMP: R-22934-25134 */
        return i;
      }else if( z[1]=='>' ){
        *tokenType = TK_PTR;
        return 2 + (z[2]=='>');
      }
      *tokenType = TK_MINUS;
      return 1;







|







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
180270
180271
180272
180273
180274
180275
180276
180277
    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_SPACE;   /* IMP: R-22934-25134 */
      return i;
    }
    case CC_PERCENT: {
      *tokenType = TK_REM;
      return 1;
    }
    case CC_EQ: {







|







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
180599
180600
180601
180602
180603
180604
180605
180606
180607
180608
180609
180610
180611
      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
      );
#else
    if( tokenType>=TK_SPACE ){
      assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL
           || tokenType==TK_QNUMBER
      );
#endif /* SQLITE_OMIT_WINDOWFUNC */
      if( AtomicLoad(&db->u1.isInterrupted) ){
        pParse->rc = SQLITE_INTERRUPT;
        pParse->nErr++;
        break;
      }







|




|







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
181985
181986
181987
181988
181989
181990





181991
181992
181993
181994
181995
181996
181997
181998
181999
182000
182001
182002
182003
182004
182005
182006
182007
182008
182009
182010
182011



182012


182013
182014
182015
182016
182017
182018
182019
182020
182021
182022
182023
182024
182025
182026
182027
182028
182029
182030
182031
182032
182033
182034
182035
182036
182037

/*
** 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 pStart is NULL the
** space for the lookaside memory is obtained from sqlite3_malloc().
** If pStart is not NULL then it is sz*cnt bytes of memory to use for
** the lookaside memory.
*/
static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){





#ifndef SQLITE_OMIT_LOOKASIDE
  void *pStart;
  sqlite3_int64 szAlloc = sz*(sqlite3_int64)cnt;
  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 to be useful.
  */
  sz = ROUNDDOWN8(sz);  /* IMP: R-33038-09382 */
  if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;



  if( cnt<0 ) cnt = 0;


  if( sz==0 || cnt==0 ){
    sz = 0;
    pStart = 0;
  }else if( pBuf==0 ){
    sqlite3BeginBenignMalloc();
    pStart = sqlite3Malloc( szAlloc );  /* IMP: R-61949-35727 */
    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 - sz*nBig)/LOOKASIDE_SMALL;
  }else if( sz>=LOOKASIDE_SMALL*2 ){
    nBig = szAlloc/(LOOKASIDE_SMALL+sz);
    nSm = (szAlloc - sz*nBig)/LOOKASIDE_SMALL;
  }else
#endif /* SQLITE_OMIT_TWOSIZE_LOOKASIDE */
  if( sz>0 ){
    nBig = szAlloc/sz;
    nSm = 0;
  }else{
    nBig = nSm = 0;







|
|
|
|

|
>
>
>
>
>

|
|
|
|












|

|

>
>
>
|
>
>
|




|








|


|







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
182185
182186
182187
182188
182189
182190
182191
182192
182193
182194
182195
182196
182197
182198
182199
182200
182201
182202
182203
182204
182205



182206
182207
182208
182209
182210
182211
182212
      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 */
        u32 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   },



      };
      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*);







|




















>
>
>







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
184083
184084
184085
184086
184087
184088
184089
184090
184091
#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>127
# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127
#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







|
|







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

185163
185164
185165
185166
185167
185168
185169
185170
185171
185172
185173
185174
185175
185176
    goto error_out;
  }

  /* Find the column for which info is requested */
  if( zColumnName==0 ){
    /* Query for existence of table only */
  }else{

    for(iCol=0; iCol<pTab->nCol; iCol++){
      pCol = &pTab->aCol[iCol];
      if( 0==sqlite3StrICmp(pCol->zCnName, zColumnName) ){
        break;
      }
    }
    if( iCol==pTab->nCol ){
      if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){
        iCol = pTab->iPKey;
        pCol = iCol>=0 ? &pTab->aCol[iCol] : 0;
      }else{
        pTab = 0;
        goto error_out;
      }







>
|

<
<
|
<
<







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
185497
185498
185499
185500
185501
185502
185503
185504
185505
185506
185507
185508
185509
185510
185511
185512
185513
185514
185515
185516
185517
185518
185519
185520
185521
      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);
        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);
        sqlite3ShowWhereTerm(0);
      }
#endif
      break;
    }


    /*







<
















<







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
192023
192024
192025
192026
192027
192028
192029
192030
        nDistance = nMaxUndeferred - iPrev;
      }else{
        p1 = pPhrase->doclist.pList;
        p2 = aPoslist;
        nDistance = iPrev - nMaxUndeferred;
      }

      aOut = (char *)sqlite3Fts3MallocZero(nPoslist+FTS3_BUFFER_PADDING);
      if( !aOut ){
        sqlite3_free(aPoslist);
        return SQLITE_NOMEM;
      }

      pPhrase->doclist.pList = aOut;
      assert( p1 && p2 );







|







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
194625
194626
194627
194628
194629
194630
194631
194632
){
  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;
  int 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







|







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
207374
207375
207376
207377
207378
207379
207380
207381
207382
207383

207384
207385
207386
207387
207388
207389
207390
207391
207392
/*
** 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;
  u32 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; }

  pParse->aBlob = aNew;
  pParse->nBlobAlloc = 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







|









>

|







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
208342
208343
208344
208345
208346
208347
208348
208349
208350
208351
208352
** 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;
  if( NEVER(i>pParse->nBlob) ){
    *pSz = 0;
    return 0;
  }
  x = pParse->aBlob[i]>>4;
  if( x<=11 ){
    sz = x;
    n = 1;
  }else if( x==12 ){
    if( i+1>=pParse->nBlob ){
      *pSz = 0;







|
<
<
<







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
208389
208390
208391
208392
208393
208394
208395
208396
208397
    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
  ){
    sz = 0;
    n = 0;
  }
  *pSz = sz;
  return n;
}


/*







|
|







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

208487
208488

208489

208490
208491
208492
208493
208494
208495
208496
          jsonAppendChar(pOut, '0');
        }
      }
      break;
    }
    case JSONB_TEXT:
    case JSONB_TEXTJ: {

      jsonAppendChar(pOut, '"');
      jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz);

      jsonAppendChar(pOut, '"');

      break;
    }
    case JSONB_TEXT5: {
      const char *zIn;
      u32 k;
      u32 sz2 = sz;
      zIn = (const char*)&pParse->aBlob[i+n];







>
|
|
>
|
>







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
209404
209405
209406
209407
209408
209409
209410
209411
    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, 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 ){







|







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
215532
215533

215534
215535
215536
215537
215538
215539
215540
#else
      sqlite3_str_appendf(pOut, " %d", cell.aCoord[jj].i);
#endif
    }
    sqlite3_str_append(pOut, "}", 1);
  }
  errCode = sqlite3_str_errcode(pOut);
  sqlite3_result_text(ctx, sqlite3_str_finish(pOut), -1, sqlite3_free);
  sqlite3_result_error_code(ctx, errCode);

}

/* 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;
**







<

>







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
226326
226327
226328
226329
226330
226331
226332
226333
226334
226335
226336
226337
226338
226339
226340
226341
226342
226343
226344
226345
226346
226347
226348


226349


226350
226351
226352
226353
226354
226355
226356
226357
226358
226359
226360
226361
226362
226363
226364
226365
226366
226367
226368
226369
226370
226371
226372
226373
226374
226375
226376
      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;
}

/* 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.
*/
static int dbpageBegin(sqlite3_vtab *pVtab){
  DbpageTable *pTab = (DbpageTable *)pVtab;
  sqlite3 *db = pTab->db;
  int i;
  for(i=0; i<db->nDb; i++){
    Btree *pBt = db->aDb[i].pBt;
    if( pBt ) (void)sqlite3BtreeBeginTrans(pBt, 1, 0);
  }
  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);


    sqlite3PagerTruncateImage(pPager, pTab->pgnoTrunc);


  }
  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 = {
    0,                            /* iVersion */
    dbpageConnect,                /* xCreate */
    dbpageConnect,                /* xConnect */
    dbpageBestIndex,              /* xBestIndex */
    dbpageDisconnect,             /* xDisconnect */
    dbpageDisconnect,             /* xDestroy */
    dbpageOpen,                   /* xOpen - open a cursor */
    dbpageClose,                  /* xClose - close a cursor */







>
>
>
>
>
>
















>





<
<
<
<


<
<
<
<
<
<











>
>
|
>
>



















|







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
226544

226545
226546
226547
226548

226549
226550
226551
226552
226553
226554
226555
**   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 columns in table zName */

  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 */

  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;
};








|
>




>







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
226952
226953
226954
226955
226956
226957
226958
226959
226960
226961

226962
226963
226964
226965
226966
226967
226968
226969
226970
226971
226972
226973
  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 ){
    assert( pTab->nCol-1==pSession->hook.xCount(pSession->hook.pCtx) );
    h = sessionHashAppendI64(h, iRowid);
  }else{
    assert( *pbNullPK==0 );
    assert( pTab->nCol==pSession->hook.xCount(pSession->hook.pCtx) );
    for(i=0; i<pTab->nCol; i++){
      if( pTab->abPK[i] ){
        int rc;
        int eType;
        sqlite3_value *pVal;


        if( bNew ){
          rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal);
        }else{
          rc = pSession->hook.xOld(pSession->hook.pCtx, i, &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;







>

<



<





>


|

|







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
227311
227312
227313
227314
227315
227316
227317
227318
227319
227320
227321
  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 ); */
        rc = pSession->hook.xNew(pSession->hook.pCtx, iCol, &pVal);
      }else{
        /* assert( db->pPreUpdate->pUnpacked ); */
        rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &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







>








|


|







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
227472
227473
227474
227475
227476
227477
227478
227479
227480
227481
227482
227483
227484
227485
227486
227487
227488
227489
227490
227491
227492
227493
227494
227495
227496
227497
227498

227499

227500
227501
227502
227503
227504
227505
227506
227507
227508
227509
227510
227511
227512
227513
227514
227515
227516
227517
227518
227519
227520
227521
227522
227523
227524
227525
227526
227527
227528
227529
227530
227531
227532
227533
227534

227535
227536
227537

227538
227539
227540
227541
227542
227543
227544
227545
227546
227547
227548
227549
227550
227551
227552
227553
227554

227555


227556
227557
227558
227559
227560
227561
227562
227563
227564
227565
227566
227567

227568
227569
227570
227571
227572
227573
227574
*/
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(
          "SELECT 0, 'tbl',  '', 0, '', 1     UNION ALL "
          "SELECT 1, 'idx',  '', 0, '', 2     UNION ALL "
          "SELECT 2, 'stat', '', 0, '', 0"
      );
    }else if( rc==SQLITE_ERROR ){
      zPragma = sqlite3_mprintf("");
    }else{
      return rc;
    }
  }else{
    zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%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 */

    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(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];
    pAlloc = (u8 *)&azDflt[nDbCol];
    abPK = (u8 *)pAlloc;
    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;

      i++;
    }
    while( SQLITE_ROW==sqlite3_step(pStmt) ){

      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);

      i++;


    }
    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;

  }else{
    sessionFree(pSession, azCol);
  }
  if( pbRowid ) *pbRowid = bRowid;
  sqlite3_finalize(pStmt);
  return rc;
}







>



>














>







>
>









|
|
|







|
















>
|
>








|










|
|














>



>
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
>
|
>
>












>







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
227599

227600
227601
227602
227603
227604
227605
227606
){
  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, 0, &pTab->azCol, &pTab->azDflt, &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;







|
>







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
227642
227643
227644
227645
227646
227647
227648
227649
}

/*
** 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,
      pTab->zName, &nCol, 0, &azCol, &azDflt, &abPK,
      (pSession->bImplicitPK ? &bRowid : 0)
  );
  if( pSession->rc==SQLITE_OK ){
    if( pTab->nCol>nCol || pTab->bRowid!=bRowid ){
      pSession->rc = SQLITE_SCHEMA;
    }else{
      int ii;







>


>






|







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
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
  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, 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;

      sqlite3_value *p = 0;
      pSession->hook.xNew(pSession->hook.pCtx, ii-pTab->bRowid, &p);
      if( p==0 ){
        return SQLITE_NOMEM;
      }

      eType = *pCsr++;
      switch( eType ){
        case SQLITE_NULL:







|



















>

|







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
228102
228103
228104
228105
228106
228107
228108
228109
228110
228111
228112
228113

  /* 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->nCol-pTab->bRowid)<nExpect ){
    if( sessionReinitTable(pSession, pTab) ) return;
    if( sessionUpdateChanges(pSession, pTab) ) return;
  }
  if( (pTab->nCol-pTab->bRowid)!=nExpect ){
    pSession->rc = SQLITE_SCHEMA;
    return;
  }

  /* Grow the hash table if required */
  if( sessionGrowHash(pSession, 0, pTab) ){
    pSession->rc = SQLITE_NOMEM;







|



|







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
228163

228164
228165
228166
228167
228168
228169
228170
228171
228172
228173
228174
228175
228176
228177
      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=0; i<(pTab->nCol-pTab->bRowid); 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, i, &p);
        }else if( pTab->abPK[i] ){
          TESTONLY(int trc = ) pSession->hook.xNew(pSession->hook.pCtx, i, &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);







|
>




|

|







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
228205
228206

228207
228208
228209
228210
228211
228212
228213
228214
228215
228216
228217
      ** 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=0; i<(pTab->nCol-pTab->bRowid); i++){
        sqlite3_value *p = 0;

        if( op!=SQLITE_INSERT ){
          pSession->hook.xOld(pSession->hook.pCtx, i, &p);
        }else if( pTab->abPK[i] ){
          pSession->hook.xNew(pSession->hook.pCtx, i, &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;







|

>

|

|







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
228612

228613
228614
228615
228616
228617
228618
228619
    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, &azCol, 0, &abPK,

          pSession->bImplicitPK ? &bRowid : 0
      );
      if( rc==SQLITE_OK ){
        if( pTo->nCol!=nCol ){
          bMismatch = 1;
        }else{
          int i;







|
>







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

228936
228937
228938

228939
228940
228941
228942
228943
228944
228945
  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++ = '"';

    while( *zIn ){
      if( *zIn=='"' ) *zOut++ = '"';
      *zOut++ = *(zIn++);

    }
    *zOut++ = '"';
    p->nBuf = (int)((u8 *)zOut - p->aBuf);
    p->aBuf[p->nBuf] = 0x00;
  }
}








>
|
|
|
>







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
229189
229190
229191
229192

229193
229194
229195
229196
229197
229198
229199
229200
229201
229202
229203
229204
229205
229206





229207


229208
229209
229210
229211
229212
229213
229214
229215
229216
229217
229218
229219
229220
229221
229222
229223
229224
229225
229226
229227
229228
229229
229230
229231
229232
  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 = "";
  const char *zCols = bRowid ? SESSIONS_ROWID ", *" : "*";
  int nSql = -1;
  int i;


  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
    );
    zCols = "tbl, ?2, stat";
  }else{





    for(i=0; i<nCol; i++){


      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)",
        zCols, (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) ){







<



>












|

>
>
>
>
>

>
>

















|







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

231608
231609
231610
231611
231612
231613
231614
231615
        sApply.azCol = (const char **)zTab;
      }else{
        int nMinCol = 0;
        int i;

        sqlite3changeset_pk(pIter, &abPK, 0);
        rc = sessionTableInfo(0, db, "main", zNew,

            &sApply.nCol, &zTab, &sApply.azCol, 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 ){







>
|







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


231688


231689
231690
231691
231692
231693


231694
231695
231696
231697
231698
231699
231700
      sIter.nCol = nFk;
      res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter);
      if( res!=SQLITE_CHANGESET_OMIT ){
        rc = SQLITE_CONSTRAINT;
      }
    }
  }


  sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0);



  if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){
    if( rc==SQLITE_OK ){
      rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
    }else{


      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 ){







>
>
|
>
>




<
>
>







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
243200
243201

243202
243203
243204

243205
243206
243207
243208
243209
243210
243211
  fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret);
  return ret;
}

/*
** Close the read-only blob handle, if it is open.
*/
static void sqlite3Fts5IndexCloseReader(Fts5Index *p){
  if( p->pReader ){

    sqlite3_blob *pReader = p->pReader;
    p->pReader = 0;
    sqlite3_blob_close(pReader);

  }
}

/*
** Retrieve a record from the %_data table.
**
** If an error occurs, NULL is returned and an error left in the







|

>


|
>







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
243229
243230
243231
243232
243233
243234
243235
243236
      ** 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 ){
        sqlite3Fts5IndexCloseReader(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 ){







|







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
243313
243314
243315




243316
243317
243318
243319
243320
243321
243322
static int fts5IndexPrepareStmt(
  Fts5Index *p,
  sqlite3_stmt **ppStmt,
  char *zSql
){
  if( p->rc==SQLITE_OK ){
    if( zSql ){
      p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
          SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB,
          ppStmt, 0);




    }else{
      p->rc = SQLITE_NOMEM;
    }
  }
  sqlite3_free(zSql);
  return p->rc;
}







|


>
>
>
>







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
247614
247615
247616
247617
247618
247619
247620
247621
  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, 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







|







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
247885
247886
247887
247888
247889
247890
247891
247892
247893


















247894
247895
247896
247897
247898
247899
247900
247901
247902
247903
247904
247905
247906
247907
247908
247909
247910
247911

247912
247913
247914
247915
247916
247917
247918
  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.



*/
static void 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 */



















  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);

}


/*
** Flush the contents of in-memory hash table iHash to a new level-0
** segment on disk. Also update the corresponding structure record.
**







>
>
>

|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


















>







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
247995
247996

247997
247998
247999
248000
248001
248002
248003
248004
248005
248006

248007
248008
248009
248010
248011
248012
248013
            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;
                }
              }
            }








|
|
>








|
|
>







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
248184
248185
248186
248187
248188
248189
248190
248191
      }
      fts5StructureRef(pStruct);
      return pStruct;
    }
    assert( pStruct->aLevel[i].nMerge<=nThis );
  }

  nByte += (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;







|







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
249072


249073
249074
249075
249076
249077
249078
249079

249080
249081
249082
249083
249084
249085
249086
        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)+s.doclist.n+FTS5_DATA_ZERO_PADDING);


    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);
    }


    if( p->rc==SQLITE_OK && s.pTokendata ){
      fts5TokendataIterSortMap(p, s2.pT);
      (*ppIter)->pTokenDataIter = s2.pT;
      s2.pT = 0;
    }
  }








|
>
>







>







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
249128
249129
249130
249131
249132
249133
249134
249135
249136
249137
249138
249139
249140
249141
249142
249143
249144
249145
249146
249147
249148
249149
249150

/*
** Commit data to disk.
*/
static int sqlite3Fts5IndexSync(Fts5Index *p){
  assert( p->rc==SQLITE_OK );
  fts5IndexFlush(p);
  sqlite3Fts5IndexCloseReader(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){
  sqlite3Fts5IndexCloseReader(p);
  fts5IndexDiscardData(p);
  fts5StructureInvalidate(p);
  /* assert( p->rc==SQLITE_OK ); */
  return SQLITE_OK;
}

/*
** 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).
*/







|










|


<
|







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
249371
249372
249373
249374
249375
249376
249377
249378
        if( pIn==0 ) memset(pNew, 0, nByte);
        pRet = pNew;
        pNew->nIterAlloc = nAlloc;
      }
    }
  }
  if( p->rc ){
    sqlite3Fts5IterClose((Fts5IndexIter*)pAppend);
  }else{
    pRet->apIter[pRet->nIter++] = pAppend;
  }
  assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc );

  return pRet;
}







|







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
249584
249585
249586
249587
249588
249589
249590
249591
    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 ){
      sqlite3Fts5IterClose((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--){







|







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
249649
249650
249651
249652
249653
249654
249655
249656
      }
    }

    /* 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 ){
      sqlite3Fts5IterClose((Fts5IndexIter*)pNew);
      break;
    }

    /* Append this iterator to the set and continue. */
    pSet = fts5AppendTokendataIter(p, pSet, pNew);
  }








|







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
249777
249778
249779
249780
249781
249782
249783
249784
249785
249786
          Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
          if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
        }
      }
    }

    if( p->rc ){
      sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
      pRet = 0;
      sqlite3Fts5IndexCloseReader(p);
    }

    *ppIter = (Fts5IndexIter*)pRet;
    sqlite3Fts5BufferFree(&buf);
  }
  return fts5IndexReturn(p);
}







|

|







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
250028
250029
250030
250031
250032
250033
250034
250035
250036
250037
250038
250039
}

/*
** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
*/
static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
  if( pIndexIter ){
    Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
    Fts5Index *pIndex = pIter->pIndex;
    fts5TokendataIterDelete(pIter->pTokenDataIter);
    fts5MultiIterFree(pIter);
    sqlite3Fts5IndexCloseReader(pIndex);
  }
}

/*
** Read and decode the "averages" record from the database.
**
** Parameter anSize must point to an array of size nCol, where nCol is







<
|
<
|
|







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
250562
250563
250564
250565
250566
250567
250568
250569
        cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
      }
    }
    if( rc==SQLITE_OK ){
      rc = sqlite3Fts5IterNext(pIter);
    }
  }
  sqlite3Fts5IterClose(pIter);

  *pCksum = cksum;
  return rc;
}

/*
** Check if buffer z[], size n bytes, contains as series of valid utf-8







|







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
251285
251286
251287
251288
251289
251290
251291
251292
  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 = 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);







|







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
253731
253732
253733
253734
253735
253736
253737
253738
253739
253740
253741
253742
253743
253744
253745
253746
253747
253748
253749
253750
  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 */
  int bUpdateOrDelete = 0;

  /* 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 = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex);
    if( rc!=SQLITE_OK ) return rc;
  }

  pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg;

  /* Put any active cursors into REQUIRE_SEEK state. */
  fts5TripCursors(pTab);







<











|







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
253768
253769
253770
253771
253772
253773
253774
253775
      if( pConfig->bContentlessDelete ){
        fts5SetVtabError(pTab,
            "'delete' may not be used with a contentless_delete=1 table"
        );
        rc = SQLITE_ERROR;
      }else{
        rc = fts5SpecialDelete(pTab, apVal);
        bUpdateOrDelete = 1;
      }
    }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







<







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
253805
253806
253807
253808
253809
253810
253811
253812
        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);
        bUpdateOrDelete = 1;
      }
    }

    /* INSERT or UPDATE */
    else{
      int eType1 = sqlite3_value_numeric_type(apVal[1]);








<







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
253833
253834
253835
253836
253837
253838
253839
253840

      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);
          bUpdateOrDelete = 1;
        }
        fts5StorageInsert(&rc, pTab, apVal, pRowid);
      }

      /* UPDATE */
      else{
        Fts5Storage *pStorage = pTab->pStorage;







<







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
253887
253888
253889
253890
253891
253892
253893
253894
253895
253896
253897
253898
253899
253900
253901
253902
253903
253904
253905
253906
253907
253908
253909
253910
          if( rc==SQLITE_OK ){
            rc = sqlite3Fts5StorageContentInsert(pStorage, 1, apVal, pRowid);
          }
        }else{
          rc = sqlite3Fts5StorageDelete(pStorage, iOld, 0, 1);
          fts5StorageInsert(&rc, pTab, apVal, pRowid);
        }
        bUpdateOrDelete = 1;
        sqlite3Fts5StorageReleaseDeleteRow(pStorage);
      }

    }
  }

  if( rc==SQLITE_OK
   && bUpdateOrDelete
   && pConfig->bSecureDelete
   && pConfig->iVersion==FTS5_CURRENT_VERSION
  ){
    rc = sqlite3Fts5StorageConfigValue(
        pTab->pStorage, "version", 0, FTS5_CURRENT_VERSION_SECUREDELETE
    );
    if( rc==SQLITE_OK ){
      pConfig->iVersion = FTS5_CURRENT_VERSION_SECUREDELETE;
    }
  }

 update_out:
  pTab->p.pConfig->pzErrmsg = 0;
  return rc;
}







<


<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
255424
255425
255426
255427
255428
255429
255430
255431
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: 2024-12-09 20:46:36 e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653", -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







|







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
260024
260025
260026
260027
260028
260029
260030
260031
260032
260033
260034
260035
260036

  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{
    int 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];
    int nDb = (int)strlen(zDb)+1;
    int nTab = (int)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]);
    }







|



|
|







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
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.48.0"
#define SQLITE_VERSION_NUMBER 3048000
#define SQLITE_SOURCE_ID      "2024-12-09 20:46:36 e2bae4143afd07de1ae55a6d2606a3b541a5b94568aa41f6a96e5d1245471653"

/*
** 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







|
|
|







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
1992
1993
1994
1995
1996
1997
1998



1999
2000
2001
2002
2003
2004
2005
** 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 and the second is the number of
** slots allocated to each database connection.)^  ^(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.)^ </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>
**







|

|
|
|
|
|
>
>
>







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


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
#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 argument to the [sqlite3_db_config()] interface.






**
** 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> ^This option takes three additional arguments that determine the
** [lookaside memory allocator] configuration for the [database connection].







** ^The first argument (the third parameter to [sqlite3_db_config()] is a
** pointer to a memory buffer to use for lookaside memory.
** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb
** may be NULL in which case SQLite will allocate the
** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the

** size of each lookaside buffer slot.  ^The third argument is the number of










** slots.  The size of the buffer in the first argument must be greater than
** or equal to the product of the second and third arguments.  The buffer
** must be aligned to an 8-byte boundary.  ^If the second argument to
** SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally
** rounded down to the next smaller multiple of 8.  ^(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 "current value" returned by
** [sqlite3_db_status](D,[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].)^</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].  There should be two additional arguments.

** 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>
**







>
>
|
>
>
>
>
>
>











|
|
>
>
>
>
>
>
>
|

<
|
|
>
|
>
>
>
>
>
>
>
>
>
>
|
|
|
<
|


<
|


|
>
>
>
>
>
>
>
>
>
>




|
>







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
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
2299
2300
2301
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
** 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 should 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 should 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 should 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.  ^The sole argument is 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 this DBCONFIG option 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 this will mean that there are now no

** connections at all to the database. If so, it performs a checkpoint
** operation before closing the connection. This option may be used to

** override this behavior. The first parameter passed to this operation

** is an integer - positive to disable checkpoints-on-close, or zero (the
** default) to enable them, and 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 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,







|





|


















|














|













>
>
>
>
|
|
|
|
|




|
|
>
|
|
>
|
>
|
|
|







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
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
** <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.  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].  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>
**


















































** </dl>



















*/
#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* */







|













|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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



2548
2549
2550
2551
2552
2553
2554
2555
#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_MAX                   1019 /* 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







>
>
>
|







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
10751
10752

10753
10754
10755
10756
10757
10758
10759
** [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 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.







|
|
>







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
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
  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: Upgrade the Schema of a Changeset/Patchset
*/
SQLITE_API int sqlite3changeset_upgrade(
  sqlite3 *db,
  const char *zDb,
  int nIn, const void *pIn,       /* Input changeset */
  int *pnOut, void **ppOut        /* OUT: Inverse of input */
);



/*
** CAPI3REF: Changegroup Handle
**
** A changegroup is an object used to combine two or more
** [changesets] or [patchsets]
*/







<
<
<
<
<
<
<
<
<
<
<
<
<







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
106
107
108
109
110
111
112
113
  color: rgba(24,24,24,0.8);
  border-radius: 0.1em;
}
.fileage tr:hover,
div.filetreeline:hover {
  background-color: #333;
}



.button,
button {
  color: #aaa;
  background-color: #444;
  border-radius: 5px;
  border: 0
}
.button:hover,
button:hover {
  background-color: #FF4500f0;
  color: rgba(24,24,24,0.8);







>
>
>



|







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
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;







|







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
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.
**
** If files are attempted to be added explicitly on the command line which
** 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.
**







|







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
758
759
760
761
762
763
764
765
766
**     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.
**
** The command does not "[[commit]]".  You must run the "[[commit]]" separately
** as 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







<
|







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
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 appoximately 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:







|







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
220
221
222
223

224
225
226
227
228
229
230
** 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;
  Stmt q;
  int cnt = 0;
  int lastGood = -1;
  int lastBad = -1;


  if( zDesc!=0 ){
    blob_init(&log, 0, 0);
    while( zDesc[0]=='y' || zDesc[0]=='n' || zDesc[0]=='s' ){
      int i;
      char c;
      int rid;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


















<



>







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
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
  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 */
     ");"
  );
  db_prepare(&q, "INSERT OR IGNORE INTO bilog(seq,stat,rid)"
                 " VALUES(:seq,:stat,:rid)");
  while( blob_token(&log, &id) ){
    int rid;
    db_bind_int(&q, ":seq", ++cnt);
    if( blob_str(&id)[0]=='s' ){
      rid = atoi(blob_str(&id)+1);
      db_bind_text(&q, ":stat", "SKIP");
      db_bind_int(&q, ":rid", rid);
    }else{
      rid = atoi(blob_str(&id));
      if( rid>0 ){
        db_bind_text(&q, ":stat","GOOD");
        db_bind_int(&q, ":rid", rid);
        lastGood = rid;
      }else{
        db_bind_text(&q, ":stat", "BAD");
        db_bind_int(&q, ":rid", -rid);
        lastBad = -rid;
      }
    }
    db_step(&q);
    db_reset(&q);
  }
  if( iCurrent>0 ){
    db_bind_int(&q, ":seq", ++cnt);
    db_bind_text(&q, ":stat", "CURRENT");
    db_bind_int(&q, ":rid", iCurrent);
    db_step(&q);
    db_reset(&q);
  }
  if( bDetail && lastGood>0 && lastBad>0 ){
    PathNode *p;
    p = path_shortest(lastGood, lastBad, bisect_option("direct-only"),0, 0);
    while( p ){
      db_bind_null(&q, ":seq");
      db_bind_null(&q, ":stat");
      db_bind_int(&q, ":rid", p->rid);
      db_step(&q);
      db_reset(&q);
      p = p->u.pTo;
    }
    path_reset();
  }
  db_finalize(&q);

  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







|
<


|


|
<



|
<


<
|



<
<


<
|
<
<
<





<
<
|
<
<




|
>







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
548
549
550
551


552
553
554
555
556
557
558
**       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
**
**       Like "fossil ui" except start on a timeline that shows only the
**       check-ins that are part of the current bisect.


**
** > fossil bisect undo
**
**       Undo the most recent "good", "bad", or "skip" command.
*/
void bisect_cmd(void){
  int n;







|


|
>
>







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

728
729

730



731
732
733
734
735
736
737
738
739
740
741
742
    }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";

    newArgv[4] = 0;
    g.argv = newArgv;

    g.argc = 4;



    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");
  }
}







>




>
|
|
>
|
>
>
>












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
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 participate
**          --users N        List up to N users partipiating
**
**        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,







|
|







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
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_AUTHENICATION",
    "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",







|







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
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_against_disk(0, &DCfg, diffFiles, &prompt);
      for( i=0; diffFiles[i].zName; ++i ){
        fossil_free(diffFiles[i].zName);
      }
      fossil_free(diffFiles);
    }else{
      diff_against_disk(0, &DCfg, 0, &prompt);
    }
  }
  prompt_for_user_comment(pComment, &prompt);
  blob_reset(&prompt);
}

/*







|





|







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
2691
2692
2693
2694
2695
2696
2697
2698
      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);
  }

  hasChanges = unsaved_changes(useHash ? CKSIG_HASH : 0);
  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







<







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
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
** 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;
  Blob manifest;
  Blob taglist;
  int flg;

  flg = db_get_manifest_setting();

  if( flg & MFESTFLG_RAW ){
    blob_zero(&manifest);
    content_get(vid, &manifest);
    sterilize_manifest(&manifest, CFTYPE_MANIFEST);
    zManFile = mprintf("%smanifest", g.zLocalRoot);
    blob_write_to_file(&manifest, zManFile);
    free(zManFile);

  }else{
    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){
      zManFile = mprintf("%smanifest", g.zLocalRoot);
      file_delete(zManFile);
      free(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
212
213
214
215
216
217
218
219
    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_zero(&taglist);
    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'") ){







|







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
41
42






43

44
45
46
47
48
49
50















51

52
53
54
55
56
57
58
** 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);
  zIn = mprintf("in-%z", zRand);
  blob_write_to_file(pIn, zOut);






  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);















    blob_read_from_file(pOut, zIn, ExtFILE);

  }else{
    if( pOut!=pIn ){
      blob_copy(pOut, pIn);
    }
  }
  file_delete(zOut);
  file_delete(zIn);







>







<

>
>
>
>
>
>
|
>







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>







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
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
      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
){
  if( g.fTimeFormat==0 ){
    if( db_get_int("timeline-utc", 1) ){
      g.fTimeFormat = 1;
    }else{
      g.fTimeFormat = 2;
    }
  }
  if( g.fTimeFormat==1 ){
    sqlite3_result_text(context, "0 seconds", -1, SQLITE_STATIC);
  }else{
    sqlite3_result_text(context, "localtime", -1, SQLITE_STATIC);
  }
}

/*







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>















|
<
<
<
<
<
<
<







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
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
**         SELECT julianday(:user_input,fromLocal());
*/
void db_fromlocal_function(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  if( g.fTimeFormat==0 ){
    if( db_get_int("timeline-utc", 1) ){
      g.fTimeFormat = 1;
    }else{
      g.fTimeFormat = 2;
    }
  }
  if( g.fTimeFormat==1 ){
    sqlite3_result_text(context, "0 seconds", -1, SQLITE_STATIC);
  }else{
    sqlite3_result_text(context, "utc", -1, SQLITE_STATIC);
  }
}

/*







|
<
<
<
<
<
<
<







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
1529

1530
1531

1532
1533

1534
1535

1536
1537

1538
1539

1540
1541

1542
1543
1544
1545
1546
1547
1548
1549

/*
** 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, 0,

                          db_checkin_mtime_function, 0, 0);
  sqlite3_create_function(db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0,

                          db_sym2rid_function, 0, 0);
  sqlite3_create_function(db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0,

                          db_sym2rid_function, 0, 0);
  sqlite3_create_function(db, "now", 0, SQLITE_UTF8, 0,

                          db_now_function, 0, 0);
  sqlite3_create_function(db, "toLocal", 0, SQLITE_UTF8, 0,

                          db_tolocal_function, 0, 0);
  sqlite3_create_function(db, "fromLocal", 0, SQLITE_UTF8, 0,

                          db_fromlocal_function, 0, 0);
  sqlite3_create_function(db, "hextoblob", 1, SQLITE_UTF8, 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,







|
>
|
|
>
|
|
>
|
|
>

|
>
|
|
>
|
|
>
|







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
2110
2111
2112
2113
2114
2115
2116
2117
  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_zero(&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));







|







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
4566
4567
4568
4569
4570
4571
4572
4573
** 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.  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.







|







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
4832

4833
4834
4835
4836
4837
4838
4839
** 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"

*/
/*
** 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.
*/







|
>







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
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
.settings-icon:hover {
  border: 1px outset rgba(127,127,127,1);
}
body.fossil-dark-style .settings-icon {
  filter: invert(100%);
}

input[type="checkbox"].diff-toggle {
  float: right;
}

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;
}







<
<
<
<







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
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
    double rLimitMtime = 0.0;
    if( ridBackTo ){
      rLimitMtime = db_double(0.0,
         "SELECT mtime FROM event WHERE objid=%d",
         ridBackTo);
    }
    db_multi_exec(
      "WITH RECURSIVE "
      "  parent(pid,cid,isCP) AS ("
      "    SELECT plink.pid, plink.cid, 0 AS xisCP FROM plink"
      "    UNION ALL"
      "    SELECT parentid, childid, 1 FROM cherrypick WHERE NOT isExclude"
      "  ),"
      "  ancestor(rid, mtime, isCP) AS ("
      "    SELECT %d, mtime, 0 FROM event WHERE objid=%d "
      "    UNION "
      "    SELECT parent.pid, event.mtime, parent.isCP"
      "      FROM ancestor, parent, event"
      "     WHERE parent.cid=ancestor.rid"
      "       AND event.objid=parent.pid"
      "       AND NOT ancestor.isCP"
      "       AND (event.mtime>=%.17g OR parent.pid=%d)"
      "     ORDER BY mtime DESC LIMIT %d"
      "  )"
      "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);
    }
  }
}







|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<







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
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
void compute_descendants(int rid, int N){
  if( !N ){
     N = -1;
  }else if( N<0 ){
     N = -N;
  }
  db_multi_exec(
    "WITH RECURSIVE"
    "  dx(rid,mtime) AS ("
    "     SELECT %d, 0"
    "     UNION"
    "     SELECT plink.cid, plink.mtime FROM dx, plink"
    "      WHERE plink.pid=dx.rid"
    "      ORDER BY 2"
    "  )"
    "INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
    rid, N
  );
}

/*
** COMMAND: descendants*







|
|
|
|
|
|
|
|







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
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

#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;
  Stmt ins;

  Stmt q;
  int rid;

  bag_init(&seen);
  bag_init(&pending);
  db_prepare(&ins, "INSERT OR IGNORE INTO \"%w\" VALUES(:rid)", 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);
    db_bind_int(&ins, ":rid", mid);
    db_step(&ins);
    db_reset(&ins);
  }
  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 ){
      db_bind_int(&ins, ":rid", mid);
      db_step(&ins);
      db_reset(&ins);
    }
  }
  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);
      db_bind_int(&ins, ":rid", mid);
      db_step(&ins);
      db_reset(&ins);
    }
    db_reset(&q);
  }
  db_finalize(&q);

  db_finalize(&ins);
  bag_clear(&seen);
  bag_clear(&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



115

116
117
118
119
120
121
122
  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]



  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]}
  
  







>
>
>
|
>







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
808
809
810

811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
    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.  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_against_disk(
  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 */








|
|
|
>








|



|







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
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
    blob_reset(&fname);
  }
  db_finalize(&q);
  db_end_transaction(1);  /* ROLLBACK */
}

/*
** Run a diff between the undo buffer and 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_against_undo(
  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);







|








|







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
1280


1281
1282
1283
1284
1285
1286
1287
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
**   --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           Select VERSION as source for the diff


**   -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                      Diff against the "undo" buffer
**   --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 */


  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");
  }
  g.diffCnt[0] = g.diffCnt[1] = g.diffCnt[2] = 0;
  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);
  }
  diff_options(&DCfg, isGDiff, 0);
  determine_exec_relative_option(1);










  verify_all_options();

  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);







|
>
>













|
















>











|










|


<











<

>
>
>
>
>
>
>
>
>
>

>







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


1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
      " 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( againstUndo ){
    if( db_lget_int("undo_available",0)==0 ){
      fossil_print("No undo or redo is available\n");
      return;
    }
    diff_against_undo(&DCfg, pFileDir);
  }else if( zTo==0 ){
    diff_against_disk(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







>
>
|




|

|







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
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
  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;
    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();
    }

  }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();
    }

  }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();







|












>















>







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
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.
**
** In 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:







|







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
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853

  @ <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;
    int nRows = 0;
    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);
      ++nRows;
      @ <tr>
      @ <td><a href='%R/setup_uedit?id=%d(iUid)'>%h(zUser)</a></td>
      @ <td>(%h(zCap))</td>
      @ </tr>
    }
    db_finalize(&q);
    @ </tbody></table>







<










<







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
11






12
13
14
15
16

17





18
19
20





21








22



23






















24
25
26
27
28
29
30
/**
   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;
  const isFdiff = !!document.querySelector('body.fdiff');






  const addToggle = function(diffElem){
    const sib = diffElem.previousElementSibling,
          btn = sib ? D.addClass(D.checkbox(true), 'diff-toggle') : 0;
    if(!sib) return;
    if(isFdiff) sib.parentElement.insertBefore(

                  D.append(D.div(),btn),sib.nextElementSibling);





    else D.append(sib,btn);
    btn.addEventListener('click', function(){
      diffElem.classList.toggle('hidden');





    }, false);








  };



  document.querySelectorAll('table.diff').forEach(addToggle);






















});

window.fossil.onPageLoad(function(){
  const F = window.fossil, D = F.dom;
  const Diff = F.diff = {
    e:{/*certain cached DOM elements*/},
    config: {




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





>
>
>

|
>
>
>
>
>
>


|

<
>
|
>
>
>
>
>
|
|
|
>
>
>
>
>

>
>
>
>
>
>
>
>

>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
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
  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 */;
  const potentialParents = [ /* possible parents for the checkbox */
    /* 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 */ 'body.vinfo div.sectionmenu.info-changes-menu'
  ];
  while( potentialParents.length ){
    if( (eToggleParent = document.querySelector(potentialParents.pop())) ){

      break;
    }
  }
  const keySbsScroll = 'sync-diff-scroll' /* F.storage key */;
  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, "Sync side-by-side scrolling")
    ));
    cbSync.addEventListener('change', function(e){
      F.storage.set(keySbsScroll, e.target.checked);
    });
  }
  const useSync = cbSync ? ()=>cbSync.checked : ()=>F.storage.getBool(keySbsScroll,true);








|
<
<
<
<
<
<
<
<
<
<
|
>
|
<
<
|










|







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

92

93
94
95
96
97
98
99
  */
  dom.label = function(forElem, text){
    const rc = document.createElement('label');
    if(forElem){
      if(forElem instanceof HTMLElement){
        forElem = this.attr(forElem, 'id');
      }

      dom.attr(rc, 'for', forElem);

    }
    if(text) this.append(rc, text);
    return rc;
  };
  /**
     Returns an IMG element with an optional src
     attribute value.







>
|
>







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
500




501
502
503
504
505
506
507
** 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, const char *zLeftBranch, u32 tmFlags){




  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;







|
>
>
>
>







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
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
        pRoot->aiRiser[iFrom] = -1;
      }
    }
  }

  /*
  ** Compute the rail mapping that tries to put the branch named
  ** zLeftBranch at the left margin.  Other branches that merge
  ** with zLeftBranch 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 ){

    /* 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
    */
    u8 aPriority[GR_MAX_RAIL];

    memset(aPriority, 0, p->mxRail+1);
    if( zLeftBranch ){
      char *zLeft = persistBranchName(p, zLeftBranch);
      for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
        if( pRow->zBranch==zLeft ){


          aPriority[pRow->iRail] |= 4;

          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;

      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," %d", aPriority[i]);



    fprintf(stderr,"\n");
#endif

    j = 0;

    for(i=0; i<=p->mxRail; i++){

      if( aPriority[i]>=4 ) 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++;
    }







|
|










>











|
>
|
|
<

|
>
>
|
>














>













|
>
>
>




>
|
>
|
>
>







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
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 valud 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){







|







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
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
  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 */
){
  @ <p>


  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).
    }

    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 ){







|
>
>


















>







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
444
445
446

447


448
449
450
451
452
453
454
455
456
457
      @ %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);
      }else{ 
        @ &nbsp;&nbsp;
        @ %z(href("%R/fdiff?v1=%!S&v2=%!S",zOld,zNew))[diff]</a>

      }


    }
  }
  @ </p>
}

/*
** Generate javascript to enhance HTML diffs.
*/
void append_diff_javascript(int diffType){
  if( diffType==0 ) return;







>

|
<

>

>
>


<







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&nbsp;Diff</a>
  }
  if( diffType!=2 ){
    @ %z(chref("button","%R?diff=2%s",zW))Side-by-Side&nbsp;Diff</a>
  }
  if( diffType!=0 ){
    if( *zW ){
      @ %z(chref("button","%R?diff=%d",diffType))\
      @ Show&nbsp;Whitespace&nbsp;Changes</a>
    }else{
      @ %z(chref("button","%R?diff=%d&w",diffType))Ignore&nbsp;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&nbsp;Diff</a>
  }
  if( diffType!=2 ){
    @ %z(chref("button","%R?diff=2&exbase=%h%s",zExBase,zW))\
    @ Side-by-Side&nbsp;Diff</a>
  }
  if( diffType!=0 ){
    if( *zW ){
      @ %z(chref("button","%R?diff=%d&exbase=%h",diffType,zExBase))\
      @ Show&nbsp;Whitespace&nbsp;Changes</a>
    }else{
      @ %z(chref("button","%R?diff=%d&exbase=%h&w",diffType,zExBase))\
      @ Ignore&nbsp;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
633
634
635
636
637
638
639
640
  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 *zPageHide = "ci"; /* Page that hides 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");







<







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
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
  @ </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!=0 ){
    @ %z(chref("button","%R/%s/%T?diff=0",zPageHide,zName))\
    @ Hide&nbsp;Diffs</a>
  }
  if( diffType!=1 ){
    @ %z(chref("button","%R/%s/%T?diff=1%s",zPage,zName,zW))\
    @ Unified&nbsp;Diffs</a>
  }
  if( diffType!=2 ){
    @ %z(chref("button","%R/%s/%T?diff=2%s",zPage,zName,zW))\
    @ Side-by-Side&nbsp;Diffs</a>
  }
  if( diffType!=0 ){
    if( *zW ){
      @ %z(chref("button","%R/%s/%T",zPage,zName))
      @ Show&nbsp;Whitespace&nbsp;Changes</a>
    }else{
      @ %z(chref("button","%R/%s/%T?w",zPage,zName))







<
<
<
<


|



|







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&nbsp;Diff</a>
  }
  if( diffType!=2 ){
    @ %z(chref("button","%R/%s/%T?diff=2%s",zPage,zName,zW))\
    @ Side-by-Side&nbsp;Diff</a>
  }
  if( diffType!=0 ){
    if( *zW ){
      @ %z(chref("button","%R/%s/%T",zPage,zName))
      @ Show&nbsp;Whitespace&nbsp;Changes</a>
    }else{
      @ %z(chref("button","%R/%s/%T?w",zPage,zName))
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
    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!=0 ){
    style_submenu_element("Hide Diff", "%R/vdiff?diff=0&%b%b", &qp, &qpGlob);
  }
  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);
  }







<
<
<







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
1673
1674
1675
1676
1677
1678
1679
1680
      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
    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
      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
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

/*
** 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
  /* 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
  if( iFrom<1 || iTo<iFrom ){
    ajax_route_error(500, "Invalid line range from=%d, to=%d.",
                     iFrom, iTo);
    return;
  }
  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++;
  }







>
>
>
>
>
>















>




















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

<
<
<
|

<







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>&nbsp;</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>&nbsp;%S(zUuid)&nbsp;</td>
    }else{
      @ <td>&nbsp;%z(href("%R/info/%!S",zUuid))%S(zUuid)</a>&nbsp;</td>
    }
    if( g.perm.Admin ){
      int rcvid = db_column_int(&q,5);
      if( rcvid<=0 ){
        @ <td>&nbsp;
      }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>&nbsp;
    }
    if( isPriv || isPhantom ){
      if( isPriv==0 ){
        @ <td>phantom</td>
      }else if( isPhantom==0 ){
        @ <td>private</td>
      }else{
        @ <td>private,phantom</td>
      }
    }else{
      @ <td>&nbsp;
    }
    @ </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
1639
1640
1641
1642
1643
1644
1645
1646
  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 valud 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;







|







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
2045

2046

2047

2048
2049
2050
2051
2052
2053



2054

2055
2056
2057
2058
2059
2060
2061
  /* 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 to

    ** the home page identified by the "index-page" setting in the repository

    ** CONFIG table, to "/index" if there no "index-page" setting. */

#ifdef FOSSIL_ENABLE_JSON
    if(g.json.isJsonMode){
      json_err(FSL_JSON_E_RESOURCE_NOT_FOUND,NULL,1);
      fossil_exit(0);
    }
#endif



    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.
  */







|
>
|
>
|
>






>
>
>
|
>







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
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
    g.useLocalauth = 1;
    allowRepoList = 1;
  }
  if( !zRemote ){
    find_server_repository(findServerArg, fCreate);
  }
  if( zInitPage==0 ){
    if( isUiCmd && g.localOpen ){
      zInitPage = "timeline?c=current";
    }else{
      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]==']' ){







<
<
<
|
<







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
651
652
653
654
655
656
657
658
659
                 -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 \
                 -DSQLITE_ENABLE_DBSTAT_VTAB \
                 -DSQLITE_ENABLE_FTS5 \
                 -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.







>


|
|







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
676
677
678
679
680
681
682
683
684
                -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 \
                -DSQLITE_ENABLE_DBSTAT_VTAB \
                -DSQLITE_ENABLE_FTS5 \
                -DSQLITE_ENABLE_STMTVTAB \
                -DSQLITE_HAVE_ZLIB \
                -DSQLITE_ENABLE_DBPAGE_VTAB \
                -DSQLITE_TRUSTED_SCHEMA=0 \
                -DHAVE_USLEEP \
                -Dmain=sqlite3_shell \
                -DSQLITE_SHELL_IS_UTF8=1 \







>


|
|







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
323


324
325
326
327
328
329

330

331
332
333
334
335
336
337
/*
** 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 ) return;


  for(i=34; 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-", 25)==0 ){

      n = i+1;
      break;
    }
  }
  *pn = n;
  return;
}







|
>
>
|





>
|
>







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(&regexp, 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(&regexp, 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
1168
1169
1170
1171
1172
1173
1174
1175
  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( !dryRunFlag ) 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 ){







|







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
1426
1427
1428
1429
1430
1431
1432
1433
  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 ){
      undo_save(zName);
      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);







>

<







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
1507
1508
1509
1510
1511
1512
1513
1514
        /* fnr  */ zName
      ); 
    }else{
      i64 sz;
      const char *zErrMsg = 0;
      int nc = 0;

      if( !dryRunFlag ) 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);







|







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
1594
1595
1596
1597
1598
1599
1600
1601
      ridv = 0;
      nc = 1;
      zErrMsg = "local edits lost";
      zFullPath = mprintf("%s/%s", g.zLocalRoot, zName);
      sz = file_size(zFullPath, ExtFILE);
      fossil_free(zFullPath);
    }
    if( !dryRunFlag ) 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);







|







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
1641
1642
1643
1644
1645
1646
1647
1648
1649
  );
  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( !dryRunFlag ) undo_save(zOldName);
    if( !dryRunFlag ) 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;"







|
|







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
1741
1742
1743
1744
1745
1746
1747
1748
    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 ){
      undo_save(zName);
      vfile_to_disk(0, idm, 0, 0);
    }
  }
  db_finalize(&q);

  /* Report on conflicts
  */







>

<







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
1800
1801
1802
1803
  }else{
    vmerge_insert(0, mid);
  }
  if( bMultiMerge && nConflict==0 ){
    nMerge++;
    goto merge_next_child;
  }
  if( !dryRunFlag ) undo_finish();

  db_end_transaction(dryRunFlag);
}







|



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
98
99
100
101
102
103
104
105
106
107





108
109
110
111
112
113
114

proc colType {c} {
  regexp {[a-z]+} $c type
  return $type
}

proc readMerge {args} {
  global fossilcmd ncontext current_file
  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 {[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\""







|









>
>
>
>
>







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
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
**
** 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[20];
  static const char aPunct[] = { 0, 0, '-', '-', ' ', ':', ':' };
  int n = (int)strlen(zIn);
  int i, j;


  /* Only three forms allowed:


  **   (1)  YYYYMMDD
  **   (2)  YYYYMMDDHHMM
  **   (3)  YYYYMMDDHHMMSS


  */




  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 ) return 0;

  /* Expand the date */
  for(i=j=0; zIn[i]; i++){
    if( i>=4 && (i%2)==0 ){
      zEDate[j++] = aPunct[i/2];
    }
    zEDate[j++] = zIn[i];
  }







  zEDate[j] = 0;

  /* Check for reasonable date values.
  ** Offset references:
  **    YYYY-MM-DD HH:MM:SS
  **    0123456789 12345678
  */







|



>

|
>
>
|
|
|
>
>

>
>
>
>
|
>
>



|


|





>
>
>
>
>
>
>







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
116
117
118
119
120
121
122
123
    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 ){
    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;
}








|







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
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
** 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");
  }
  if( !privOnly && !phantomOnly && mx>n && P("s")==0 ){
    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>
    }


    @ </ul>
    style_finish_page();
    return;
  }
  if( phantomOnly || privOnly || mx>n ){
    style_submenu_element("Index", "bloblist");
  }
  if( privOnly ){

    zRange = mprintf("IN private");
  }else if( phantomOnly ){

    zRange = mprintf("IN phantom");







  }else{
    zRange = mprintf("BETWEEN %d AND %d", s, s+n-1);
  }
  describe_artifacts(zRange);
  fossil_free(zRange);
  db_prepare(&q,

    "SELECT rid, uuid, summary, isPrivate, type='phantom', rcvid, ref"

    "  FROM description ORDER BY rid"


  );
  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( 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>&nbsp;%z(href("%R/info/%!S",zUuid))%S(zUuid)</a>&nbsp;</td>
    if( g.perm.Admin ){
      int rcvid = db_column_int(&q,5);
      if( rcvid<=0 ){
        @ <td>&nbsp;
      }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>&nbsp;
    }







>









>
>









>
>
>
>
>
>






>










|







>
>








>


>

>
>
>
>
>
>
>






>
|
>
|
>
>









<
|
<
<
<






|
>












|
<
|
|
|
<







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>&nbsp;%z(href("%R/info/%!S",zUuid))%S(zUuid)</a>&nbsp;</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>&nbsp;
    }
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>&nbsp;
  @ <th>Hash
  @ <th>Date&nbsp;Received
  @ <th>Size
  @ <th>Compressed&nbsp;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>&nbsp;
    }
    @ <td align="right">%,lld(sz)
    @ <td align="right">%,lld(szC)
    if( g.perm.Admin ){
      if( zUser ){
        @ <td>%h(zUser)
      }else{
        @ <td>&nbsp;
      }
      if( zIp ){
        @ <td>%h(zIp)
      }else{
        @ <td>&nbsp;
      }
    }
    @ </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
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
*/
static void mkdeltaFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zFile;
  Blob x, y;
  int rid;
  char *aOut;
  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;
  }
  aOut = sqlite3_malloc64(sz+70);
  if( aOut==0 ){
    sqlite3_result_error_nomem(context);
    blob_reset(&y);
    blob_reset(&x);
    return;
  }
  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), aOut);

  blob_reset(&x);
  blob_reset(&y);
  blob_init(&x, aOut, nOut);
  blob_compress(&x, &x);
  sqlite3_result_blob64(context, blob_buffer(&x), blob_size(&x),
                        SQLITE_TRANSIENT);
  blob_reset(&x);
}


/*
** Generate a binary patch file and store it into the file
** named zOut.  Or if zOut is NULL, write it into out.
**







|

<




















<
<
<
|
|
<
<









|
>


<
|
|

|







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
392
393
394
395
396
397
398
399

  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", 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));







|







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
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
        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 ){
        blob_appendf(&cmd, " merge %s\n", db_column_text(&q,1));

      }else{
        blob_appendf(&cmd, " merge --%s %s\n", zType, db_column_text(&q,1));

      }

      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);



































  }

  /* 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 ){







>









|
>

|
>

>
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
147
148
149
150
151
152
153
154
** 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/$";
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 },







|







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
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 FTS4 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:
**







|







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
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:  The command only search 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







|







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
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 FTS4 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,







|







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
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_AUTHENITICATION 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.
  }








|







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
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 not NULL or 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
){
  @ <tr><td valign="top" align="right">
  if( zLink && zLink[0] ){
    @ <a href="%s(zLink)"><nobr>%h(zTitle)</nobr></a>
  }else{
    @ %h(zTitle)
  }
  @ </td><td width="5"></td><td valign="top">%h(zDesc)</td></tr>
}



/*
** WEBPAGE: setup
**







|






|





|

|







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










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
** 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">










  setup_menu_entry("Admin Log", "admin_log",
    "The admin log records configuration changes to the repository.\n"
    "The admin log is stored in the \"admin_log\" table of the repository.\n"
  );

  setup_menu_entry("Artifact Log", "rcvfromlist",
    "The artifact log records when new content is added to the repository.\n"
    "The time and date and origin of the new content is entered into the\n"
    "Log.  The artifact log is always on and is stored in the \"rcvfrom\"\n"








    "table of the repository.\n"

  );




  blob_appendf(&desc,
    "The error log is 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,"The error log is disabled for this repository.");




  }else{








    blob_appendf(&desc,"In this repository, the error log is in the file"
       "named \"%s\".", g.zErrlog);

  }
  setup_menu_entry("Error Log", "errorlog", blob_str(&desc));
  blob_reset(&desc);

  setup_menu_entry("Panic Log", "paniclog",


    "The panic log is a filtering of the Error Log that shows only the\n"
    "most important messages - assertion faults, segmentation faults, and\n"
    "similar malfunctions."
  );


  setup_menu_entry("User Log", "user_log",
    "The user log is a record of login attempts.  The user log is stored\n"
    "in the \"accesslog\" table of the respository.\n"

  );

  setup_menu_entry("Hack Log", "hacklog",
    "All 418 hack attempts"
  );

  setup_menu_entry("Non-Hack Log", "hacklog?not",
    "All log messages that are not hack attempts"
  );


  @ </table>
  style_finish_page();
}

/*
** Generate a checkbox for an attribute.







>










>
>
>
>
>
>
>
>
>
>
|
|
|
|
>

|
<
|
>
>
>
>
>
>
>
>
|
>
|
>
>
|
>

|




>
>
>
|
>
>
>
>
|
>
>
>
>
>
>
>
>
|

>

|


<
>
>
|
<
<
|
>

|
<
|
>

<
|
|

<
|
|

<







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>
  @ &mdash;&mdash;
  @ <i>The remaining links are subsets of the Error Log</i>


  @ &mdash;&mdash;
  @ </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
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
  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;

#if 0  /* Removed 2021-01-26 */
  const struct {
    const char *zTitle;
    const char *zProperty;
  } aExtra[] = {
    { "Documentation",  "sitemap-docidx" },
    { "Download",       "sitemap-download" },
    { "License",        "sitemap-license" },
    { "Contact",        "sitemap-contact" },
  };
#endif

  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>
  }

#if 0  /* Removed 2021-01-26  */
  for(i=0; i<sizeof(aExtra)/sizeof(aExtra[0]); i++){
    char *z = db_get(aExtra[i].zProperty,0);
    if( z==0 || z[0]==0 ) continue;
    if( !inSublist ){
      @ <ul>
      inSublist = 1;
    }
    if( z[0]=='/' ){
      @ <li>%z(href("%R%s",z))%s(aExtra[i].zTitle)</a></li>
    }else{
      @ <li>%z(href("%s",z))%s(aExtra[i].zTitle)</a></li>
    }
  }
#endif

  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);







<
<
<
<
<
<
<
<
<
<
<
<



















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159



160
161
162
163
164
165
166
        }
      }
    }
    Th_Free(g.interp, azExtra);
  }
  if( (e&1)!=0 ) goto end_of_sitemap;

#if 0  /* Removed on 2021-02-11.  Make a sitemap-extra entry if you */
       /* really want this */
  if( srchFlags & SRCH_DOC ){
    if( !inSublist ){
      @ <ul>
      inSublist = 1;
    }
    @ <li>%z(href("%R/docsrch"))Documentation Search</a></li>
  }
#endif

  if( inSublist ){
    @ </ul>
    inSublist = 0;
  }
  @ </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>







<
<
<
<
<
<
<
<
<
<
<





>
>
>







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
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&n=%d&y=%s",
                 zTimeframe, nCount,
                 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);
      }







|
|







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
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&n=%d&y=%s",
               zYear, zWeek, nCount,
               statsReportTimelineYFlag);
    if( zUserName ){
      cgi_printf("&u=%t",zUserName);
    }
    cgi_printf("'>%s</a></td>",zWeek);

    cgi_printf("<td>%d</td>",nCount);







|
|







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
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 */
  const char *zLeftBranch, /* Strive to put this branch on the left margin */
  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;







|







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
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, zLeftBranch, tmFlags);
    if( pGraph->nErr ){
      graph_free(pGraph);
      pGraph = 0;
    }else{
      @ <tr class="timelineBottom" id="btm-%d(iTableId)">\
      @ <td></td><td></td><td></td></tr>
    }







|







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
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
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
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
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
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549

1550
1551
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
1577
1578
*/
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"
      " WHERE mlink.fnid=filename.fnid 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);
}

/*
** Tag match expression type code.
*/
typedef enum {
  MS_EXACT,   /* Matches a single tag by exact string comparison. */
  MS_GLOB,    /* Matches tags against a list of GLOB patterns. */
  MS_LIKE,    /* Matches tags against a list of LIKE patterns. */
  MS_REGEXP,  /* Matches tags against a list of regular expressions. */
  MS_BRLIST,  /* Same as REGEXP, except the regular expression is a list
              ** of branch names */
} MatchStyle;

/*
** 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 tag match SQL expression.
**
** 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.
*/
static const char *tagMatchExpression(
  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(&regexp, 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;
}

/*
** 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){
  static char zEDate[20];
  static const char aPunct[] = { 0, 0, '-', '-', ' ', ':', ':' };
  int n = (int)strlen(zIn);
  int i, j;

  /* Only three forms allowed:

  **   (1)  YYYYMMDD
  **   (2)  YYYYMM
  **   (3)  YYYYWW
  */






  if( n!=8 && n!=6 ) return zIn;

  /* Every character must be a digit */
  for(i=0; fossil_isdigit(zIn[i]); i++){}
  if( i!=n ) return zIn;

  /* Expand the date */
  for(i=j=0; zIn[i]; i++){
    if( i>=4 && (i%2)==0 ){
      zEDate[j++] = aPunct[i/2];
    }
    zEDate[j++] = zIn[i];
  }
  zEDate[j] = 0;

  /* It looks like this may be a date.  Return it with punctuation added. */
  return zEDate;
}




































/*
** 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







|
|
>











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








|
|
<



|
>




>
>
>
>
>
>



|



|
<
|
<







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720


/*
** 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=HASHLIST      Show all check-ins in the comma-separated HASHLIST
**                    in addition to check-ins specified by t= or r=
**    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







|
|


|




|
|







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
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
**    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           Show check-ins related to TAG, equivalent to t=TAG&rel
**    tl=TAGLIST      Shorthand for t=TAGLIST&ms=brlist
**    rl=TAGLIST      Shorthand for r=TAGLIST&ms=brlist


**    rel             Show related check-ins as well as those matching t=TAG
**    mionly          Limit rel to show ancestors but not descendants
**    nowiki          Do not show wiki associated with branch or tag
**    ms=MATCHSTYLE   Set tag match style to EXACT, GLOB, LIKE, 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       Show family (immediate parents and children) of CHECKIN
**    from=CHECKIN    Path 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



**    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=YYYY-MM      Show only events for the given year/month
**    yw=YYYY-WW      Show only events for the given week of the given year
**    yw=YYYY-MM-DD   Show events for the week that includes the given day
**    ymd=YYYY-MM-DD  Show only events on the given day. The use "ymd=now"
**                    to see all changes for the current week.


**    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 text
**
** 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,







|
|
|
>
>

|

|
>



|








|
|






>
>
>

|
|

|







|
|
|
|
|
>
>








|







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
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
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
    );
  }

  /* 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 ){
      zTagName = z;
      zMatchStyle = "brlist";
    }
    if( (z = P("rl"))!=0 ){
      zBrName = z;
      related = 1;











      zMatchStyle = "brlist";

    }
  }

  /* Convert r=TAG to t=TAG&rel in order to populate the UI style widgets. */
  if( zBrName && !related ){
    cgi_delete_query_parameter("r");
    cgi_set_query_parameter("t", zBrName);  (void)P("t");
    cgi_set_query_parameter("rel", "1");
    zTagName = zBrName;
    related = 1;
    zType = "ci";
  }

  /* Ignore empty tag query strings. */
  if( zTagName && !*zTagName ){
    zTagName = 0;
  }

  /* Finish preliminary processing of tag match queries. */

  if( zTagName ){
    zType = "ci";
    /* Interpet the tag style string. */
    if( fossil_stricmp(zMatchStyle, "glob")==0 ){
      matchStyle = MS_GLOB;
    }else if( fossil_stricmp(zMatchStyle, "like")==0 ){
      matchStyle = MS_LIKE;
    }else if( fossil_stricmp(zMatchStyle, "regexp")==0 ){
      matchStyle = MS_REGEXP;
    }else if( fossil_stricmp(zMatchStyle, "brlist")==0 ){
      matchStyle = MS_BRLIST;
    }else{
      /* 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 = tagMatchExpression(matchStyle, zTagName, &zMatchDesc, &zError);
  }

  if( zMark && zMark[0]==0 ){
    if( zAfter ) zMark = zAfter;
    if( zBefore ) zMark = zBefore;
    if( zCirca ) zMark = zCirca;
  }







>

|
<
<
|
|
|
>
>
>
>
>
>
>
>
>
>
>
|
>




|




|









>


<
<
|
<
<
<
<
<
<
<











|







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
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
  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"
      "  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)=="
      "           (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
      "   GROUP BY pid"
      "   HAVING count(*)>1;\n"
      "INSERT OR IGNORE INTO rnfork(rid)"
      "  SELECT cid FROM plink\n"
      "   WHERE (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
      "           (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
      "   GROUP BY cid"
      "   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"
      "     AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
      "           (SELECT value FROM tagxref WHERE tagid=%d AND rid=pid)\n"
      " UNION "
      "  SELECT pid FROM plink\n"
      "   WHERE cid IN rnfork"
      "     AND (SELECT value FROM tagxref WHERE tagid=%d AND rid=cid)=="
      "           (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) ){







>

















|








|
|
|

|

|
|
|






|
|
|
|

|
|
|







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
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
    /* 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{
      if( path_common_ancestor(me_rid, you_rid) ){

        p = path_first();
      }






      zFrom = P("me");
      zTo = P("you");



    }
    blob_init(&ins, 0, 0);
    db_multi_exec(
      "CREATE TABLE IF NOT EXISTS temp.pathnode(x INTEGER PRIMARY KEY);"
    );
    if( p ){

      blob_init(&ins, 0, 0);
      blob_append_sql(&ins, "INSERT INTO pathnode(x) VALUES(%d)", p->rid);
      p = p->u.pTo;
      while( p ){





        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 || P("mionly") ){
      db_multi_exec(
        "CREATE TABLE IF NOT EXISTS temp.related(x INTEGER PRIMARY KEY);"
        "INSERT OR IGNORE INTO related(x)"
        "  SELECT pid FROM plink WHERE cid IN pathnode AND NOT isprim;"
      );
      if( P("mionly")==0 ){
        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( P("mionly")==0 ){
          db_multi_exec(
            "INSERT OR IGNORE INTO related(x)"
            "  SELECT childid FROM cherrypick WHERE parentid IN pathnode;"
          );
        }












      }
      db_multi_exec("INSERT OR IGNORE INTO pathnode SELECT x FROM related");
    }

    blob_append_sql(&sql, " AND event.objid IN pathnode");
    if( zChng && zChng[0] ){
      db_multi_exec(
        "DELETE FROM pathnode "
        " WHERE NOT EXISTS(SELECT 1 FROM mlink, filename"
                          " WHERE mlink.mid=x"
                          "   AND mlink.fnid=filename.fnid 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);







>
>






>
>


>
>




|
>


>
>
>
>
>
>
|
|
>
>
>



|


>




>
>
>
>
>
|
>






|

|

|

|


|





|

|


|


>
>
>
>
>
>
>
>
>
>
>
>



>



|
|
|
|
>







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
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
    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 ){
      Stmt s;
      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);
        }
      }



      db_prepare(&s,
        "WITH RECURSIVE"
        "  dx(rid,mtime) AS ("
        "     SELECT %d, 0"
        "     UNION"
        "     SELECT plink.cid, plink.mtime FROM dx, plink"
        "      WHERE plink.pid=dx.rid"
        "        AND (:stop>=8e99 OR plink.mtime<=:stop)"
        "      ORDER BY 2"
        "  )"
        "INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
        d_rid, nEntry<=0 ? -1 : nEntry+1
      );
      db_bind_double(&s, ":stop", rStopTime);
      db_step(&s);
      db_finalize(&s);
      /* compute_descendants(d_rid, nEntry==0 ? 0 : 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");







>







<















>
>
>
|
|
<
|
|
|
|
|
|
|

|

<
<
<
<







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
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
    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 ");
    }
    if( renameOnly ){
      blob_append_sql(&cond, " AND event.objid IN rnfile ");
    }
    if( forkOnly ){
      blob_append_sql(&cond, " AND event.objid IN rnfork ");
    }
    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 ");
    }
    if( bisectLocal || zBisect!=0 ){
      blob_append_sql(&cond, " AND event.objid IN (SELECT rid FROM bilog) ");
    }
    if( zYearMonth ){
      char *zNext;


      zYearMonth = timeline_expand_datetime(zYearMonth);
      if( strlen(zYearMonth)>7 ){
        zYearMonth = mprintf("%.7s", zYearMonth);
      }
      if( db_int(0,"SELECT julianday('%q-01') IS NULL", zYearMonth) ){
        zYearMonth = db_text(0, "SELECT strftime('%%Y-%%m','now');");
      }
      zNext = db_text(0, "SELECT strftime('%%Y-%%m','%q-01','+1 month');",
                      zYearMonth);
      if( db_int(0,
          "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
          " WHERE blob.rid=event.objid AND mtime>=julianday('%q-01')%s)",

          zNext, blob_sql_text(&cond))
      ){


        zNewerButton = fossil_strdup(url_render(&url, "ym", zNext, 0, 0));
        zNewerButtonLabel = "Following month";
      }
      fossil_free(zNext);
      zNext = db_text(0, "SELECT strftime('%%Y-%%m','%q-01','-1 month');",
                      zYearMonth);

      if( db_int(0,
          "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
          " WHERE blob.rid=event.objid AND mtime<julianday('%q-01')%s)",

          zYearMonth, blob_sql_text(&cond))
      ){


        zOlderButton = fossil_strdup(url_render(&url, "ym", zNext, 0, 0));
        zOlderButtonLabel = "Previous month";
      }
      fossil_free(zNext);

      blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%m',event.mtime) ",


                      zYearMonth);
      nEntry = -1;


    }
    else if( zYearWeek ){
      char *z, *zNext;


      zYearWeek = timeline_expand_datetime(zYearWeek);
      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')");
        }
      }
      zNext = db_text(0, "SELECT date(%Q,'+7 day');", zYearWeekStart);
      if( db_int(0,
          "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
          " WHERE blob.rid=event.objid AND mtime>=julianday(%Q)%s)",

          zNext, blob_sql_text(&cond))
      ){


        zNewerButton = fossil_strdup(url_render(&url, "yw", zNext, 0, 0));
        zNewerButtonLabel = "Following week";





































      }





















      fossil_free(zNext);
      zNext = db_text(0, "SELECT date(%Q,'-7 days');", zYearWeekStart);

      if( db_int(0,
          "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
          " WHERE blob.rid=event.objid AND mtime<julianday(%Q)%s)",

          zYearWeekStart, blob_sql_text(&cond))
      ){




        zOlderButton = fossil_strdup(url_render(&url, "yw", zNext, 0, 0));
        zOlderButtonLabel = "Previous week";
      }
      fossil_free(zNext);

      blob_append_sql(&cond, " AND %Q=strftime('%%Y-%%W',event.mtime) ",


                   zYearWeek);
      nEntry = -1;






    }
    else if( zDay ){
      char *zNext;




      zDay = timeline_expand_datetime(zDay);
      zDay = db_text(0, "SELECT date(%Q)", zDay);
      if( zDay==0 || zDay[0]==0 ){
        zDay = db_text(0, "SELECT date('now')");
      }
      zNext = db_text(0, "SELECT date(%Q,'+1 day');", zDay);

      if( db_int(0,
          "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
          " WHERE blob.rid=event.objid AND mtime>=julianday(%Q)%s)",

          zNext, blob_sql_text(&cond))
      ){


        zNewerButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
        zNewerButtonLabel = "Following day";
      }
      fossil_free(zNext);
      zNext = db_text(0, "SELECT date(%Q,'-1 day');", zDay);

      if( db_int(0,
          "SELECT EXISTS (SELECT 1 FROM event CROSS JOIN blob"
          " WHERE blob.rid=event.objid AND mtime<julianday(%Q)%s)",

          zDay, blob_sql_text(&cond))
      ){


        zOlderButton = fossil_strdup(url_render(&url, "ymd", zNext, 0, 0));
        zOlderButtonLabel = "Previous day";
      }
      fossil_free(zNext);

      blob_append_sql(&cond, " AND %Q=date(event.mtime) ",


                   zDay);
      nEntry = -1;



    }
    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;







|


|


|







|


|



>
>
|
<
|
<



|
<


|
>
|

>
>


<
|
<
<
>


|
>
|

>
>


<
|
>
|
>
>
|

>
>



>
>
|




















|


|
>
|

>
>


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
|

|
>
|

>
>
>
>
|
|
<
|
>
|
>
>
|

>
>
>
>
>
>



>
>
>
>
|




<
>


|
>
|

>
>


<
|
<
>


|
>
|

>
>


<
|
>
|
>
>
|

>
>
>







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
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
2741
2742
2743
2744
2745
2746
2747
      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"
        " SELECT tagxref.rid FROM tagxref NATURAL JOIN tag"

        " WHERE %s AND tagtype>0", 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);
      }
      if( P("x")!=0 ){
        char *zX = fossil_strdup(P("x"));
        int ii;
        int ridX;
        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;
          ridX = name_to_rid(zX);
          db_multi_exec(
            "INSERT OR IGNORE INTO selected_nodes(rid) VALUES(%d)", ridX);
          zX[ii] = c;
          zX += ii;
        }
      }
      if( !related ){
        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"
          " SELECT pid FROM selected_nodes CROSS JOIN plink"
          " WHERE selected_nodes.rid=plink.cid;"
        );
        if( P("mionly")==0 ){
          db_multi_exec(
            "INSERT OR IGNORE INTO related_nodes"
            " SELECT cid FROM selected_nodes CROSS JOIN plink"
            " WHERE selected_nodes.rid=plink.pid;"
          );
          if( showCherrypicks ){
            db_multi_exec(
              "INSERT OR IGNORE INTO related_nodes"
              " SELECT childid FROM selected_nodes CROSS JOIN cherrypick"
              " WHERE selected_nodes.rid=cherrypick.parentid;"
            );
          }
        }
        if( showCherrypicks ){
          db_multi_exec(
            "INSERT OR IGNORE INTO related_nodes"
            " SELECT parentid FROM selected_nodes CROSS JOIN cherrypick"
            " WHERE selected_nodes.rid=cherrypick.childid;"
          );
        }
        if( (tmFlags & TIMELINE_UNHIDE)==0 ){
          db_multi_exec(
            "DELETE FROM related_nodes WHERE rid IN "

            " (SELECT related_nodes.rid FROM related_nodes, tagxref"

            " WHERE tagid=%d AND tagtype>0 AND tagxref.rid=related_nodes.rid)",
            TAG_HIDDEN
          );
        }
      }
    }
    if( (zType[0]=='w' && !g.perm.RdWiki)
     || (zType[0]=='t' && !g.perm.RdTkt)







|
|
>
|








<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|














|
|
|

|

|
|
|



|
|
|





|
|
|




|
>
|
>
|







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
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
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
    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"
           " ORDER BY event.mtime ASC", rAfter-ONE_SECOND, rBefore+ONE_SECOND);
        nEntry = -1;
      }else{
        blob_append_sql(&sql,
           " AND event.mtime>=%.17g  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 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 ORDER BY event.mtime ASC", rCirca);
      if( nEntry>0 ){
        blob_append_sql(&sql2," LIMIT %d", (nEntry+1)/2);
      }
      if( PB("showsql") ){
         @ <pre>%h(blob_sql_text(&sql2))</pre>
      }
      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 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-01",
                   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 ){







|




|






|







|



<
<
<







|












|







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
3015

3016

3017
3018
3019
3020
3021
3022
3023
      if( advancedMenu ){
        style_submenu_entry("t", "Tag Filter:", -8, 0);
        style_submenu_multichoice("ms", count(azMatchStyles)/2,azMatchStyles,0);
      }
    }
    blob_zero(&cond);
  }
  if( PB("showsql") ){

    @ <pre>%h(blob_sql_text(&sql))</pre>

  }
  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"));







|
>
|
>







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














3074
3075


3076
3077
3078
3079
3080
3081


3082
3083
3084
3085
3086
3087
3088
  }

  if( zNewerButton ){
    @ %z(chref("button","%s",zNewerButton))%h(zNewerButtonLabel)\
    @ &nbsp;&uarr;</a>
  }
  cgi_check_for_malice();














  www_print_timeline(&q, tmFlags, zThisUser, zThisTag, zBrName,
                     selectedRid, secondaryRid, 0);


  db_finalize(&q);
  if( zOlderButton ){
    @ %z(chref("button","%s",zOlderButton))%h(zOlderButtonLabel)\
    @ &nbsp;&darr;</a>
  }
  document_emit_js(/*handles pikchrs rendered above*/);


  style_finish_page();
}

/*
** Translate a timeline entry into the printable format by
** converting every %-substitutions as follows:
**







>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>






>
>







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)\
    @ &nbsp;&uarr;</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)\
    @ &nbsp;&darr;</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
3760
3761
3762
3763
3764
3765
3766
3767
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 ){
    zToday = timeline_expand_datetime(zToday);
    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);







>










|







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
519
520
521
522
523
524
525
526
527
528
529
530
531
532



533
534
535
536
537
538
539
            zNext = db_changes() ? file_dirname(zDir) : 0;
            fossil_free(zDir);
            zDir = zNext;
          }
        }
      }
    }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){
      /* Merge the changes in the current tree into the target version */
      Blob r, t, v;
      int rc;

      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{



        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 ){







<
<
<
<










>
>
>







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
576
577
578
579
580


581
582
583
584
585
586
587
          }
          fossil_print("\n");
          nConflict++;
          zOp = "ERROR";
          zErrMsg = "cannot merge binary file";
          nc = 1;
        }
      }
      if( nameChng && !dryRunFlag ) file_delete(zFullPath);
      blob_reset(&v);
      blob_reset(&t);
      blob_reset(&r);


    }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);







<
<
|
|
|
>
>







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

895



896
897
898
899
900
901
902
**
** 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();

  undo_begin();



  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);







>













>







>
















>
|
>
>
>







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
992
993
994
995
996
997
998
999
    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{
        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;"







|







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
1019
1020
1021
1022
1023
1024
1025
1026
        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);

      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);







|







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
1045
1046
1047
1048
1049
1050
1051
         mtime, rvChnged, rvPerm==PERM_EXE, rvPerm==PERM_LNK, zFile, zFile
      );
    }
    blob_reset(&record);
    free(zFull);
  }
  db_finalize(&q);
  undo_finish();
  db_end_transaction(0);

  /* Deallocate parsed manifest structures. */
  manifest_destroy(pRvManifest);
  manifest_destroy(pCoManifest);
}







|






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
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
  }

  /*
  ** 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 ){
    assert( g.zRepositoryName && g.zRepositoryName[0] );
    sqlite3_snprintf(sizeof(zCmd), zCmd, "%s--in %s\n--out %s\n--ipaddr %s\n%s",
      get_utf8_bom(0), zRequestFName, zReplyFName, zIp, g.zRepositoryName
    );
  }else{
    sqlite3_snprintf(sizeof(zCmd), zCmd, "%s--in %s\n--out %s\n--ipaddr %s",
      get_utf8_bom(0), zRequestFName, zReplyFName, zIp
    );
  }
  fossil_free(zIp);
  aux = fossil_fopen(zCmdFName, "wb");
  if( aux==0 ) goto end_request;
  fwrite(zCmd, 1, strlen(zCmd), aux);

  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");







>
>
>

>
>
>
>
>
>

|
<
<
<
<
<
<
<

<
<
<
<







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
1986
1987
1988
1989
1990
1991
1992
1993
){
  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;          /* 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 */







|







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

2454


2455
2456
2457
2458
2459
2460
2461
      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);


        }
      }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







>
|
>
>







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
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
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 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 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 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 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 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 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







|








|








|








|








|








|







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
151
152
153
154
155
156
157
158
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 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







|







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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
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 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 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
} {







|








|







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
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
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 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 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
} {







|








|







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
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
merge-test 44 {
  2 3 4 5 6 7 8
} {
  6 7 8
} {
  2 3 4
} {
  MINE: 6 7 8 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 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
} {







|








|







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
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
merge-test 54 {
  2 3 4 5 6 7 8
} {
  2 3 4
} {
  6 7 8
} {
  MINE: 2 3 4 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 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
} {







|








|







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
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
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 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 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
} {







|








|







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
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
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 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 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
} {







|








|







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
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
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 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 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
} {







|








|







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
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
merge-test 94 {
  2 3 4 5 6 7 8
} {
  2 3 4
} {
  2b 3b 4b 5b 6 7 8
} {
  MINE: 2 3 4 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 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
} {







|








|







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
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
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 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 COM: 9 YOURS: 9b END
} -expectError

###############################################################################

test_cleanup







|








|





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
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
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 = 2 3 4c 5c 6c 7 8 < 9
} {
  1 > 2 3 4c 5c 6c 7 8 = 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 = 2 3 4c 5c 6c 7 8 <
} {
  > 2 3 4c 5c 6c 7 8 = 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







|

|



















|

|







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
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







|







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
#!/usr/bin/bash

########################################################################
# 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 is ${thatDir}/emsdk_env.sh and is also set by the
# configure process.
EMSDK_HOME="@EMSDK_HOME@"
EMSDK_ENV="@EMSDK_ENV@"



emcc=$(which emcc 2>/dev/null)


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 folks, 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}" ]; then
    if [ -f "${EMSDK_HOME}/emsdk_env.sh" ]; then
      EMSDK_ENV="${EMSDK_HOME}/emsdk_env.sh"
    else
      echo "EMSDK_ENV is not set. Expecting configure script to set it." 1>&2
      exit 2
    fi
  fi

  if [ ! -f "${EMSDK_ENV}" ]; then
    echo "emsdk_env script not found: $EMSDK_ENV" 1>&2
    exit 3
  fi

  # $EMSDK is part of the state set by emsdk_env.sh.
  if [ x = "x${EMSDK}" ]; then



    source "${EMSDK_ENV}" >/dev/null 2>&1 || {
      # ^^^ unfortunately outputs lots of noise to stderr
      rc=$?
      echo "Error sourcing ${EMSDK_ENV}"
      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." 1>&2
    exit 4
  fi
fi

exec emcc "$@"
|
>










|


|
>

>
|
>



|
|
|






|

|

|




|
|





>
>
>
|
<

|



|

|




|
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
246
247
248
249
250
251
252
253
254
  -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
  -DSQLITE_ENABLE_DBSTAT_VTAB
  -DSQLITE_ENABLE_FTS5
  -DSQLITE_ENABLE_STMTVTAB
  -DSQLITE_HAVE_ZLIB
  -DSQLITE_ENABLE_DBPAGE_VTAB
  -DSQLITE_TRUSTED_SCHEMA=0
  -DHAVE_USLEEP
}
#lappend SQLITE_OPTIONS -DSQLITE_ENABLE_FTS3=1







>


|
|







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
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
  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] && 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 && 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( 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 && 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{







|









|












|

















|







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
176
177
178
179
180
181
182
183
      */
      const char *zNewline = "\\n";
      int indent;
      int nC;
      int nParam;
      char c;
      i++;
      if( 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;
        }







|







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
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_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -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_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_FTS5 -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 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)\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 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







|

|



|

|


















|







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
1014
1015
$(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 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







|

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
2523
2524
2525
2526
2527
2528
2529
2530
2531
                 -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 \
                 -DSQLITE_ENABLE_DBSTAT_VTAB \
                 -DSQLITE_ENABLE_FTS5 \
                 -DSQLITE_ENABLE_STMTVTAB \
                 -DSQLITE_HAVE_ZLIB \
                 -DSQLITE_ENABLE_DBPAGE_VTAB \
                 -DSQLITE_TRUSTED_SCHEMA=0 \
                 -DHAVE_USLEEP \
                 -DSQLITE_WIN32_NO_ANSI \
                 $(MINGW_OPTIONS) \







>


|
|







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
2551
2552
2553
2554
2555
2556
2557
2558
2559
                 -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 \
                 -DSQLITE_ENABLE_DBSTAT_VTAB \
                 -DSQLITE_ENABLE_FTS5 \
                 -DSQLITE_ENABLE_STMTVTAB \
                 -DSQLITE_HAVE_ZLIB \
                 -DSQLITE_ENABLE_DBPAGE_VTAB \
                 -DSQLITE_TRUSTED_SCHEMA=0 \
                 -DHAVE_USLEEP \
                 -Dmain=sqlite3_shell \
                 -DSQLITE_SHELL_IS_UTF8=1 \







>


|
|







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
318
319
320
321
322
323
324
325
326
                 /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 \
                 /DSQLITE_ENABLE_DBSTAT_VTAB \
                 /DSQLITE_ENABLE_FTS5 \
                 /DSQLITE_ENABLE_STMTVTAB \
                 /DSQLITE_HAVE_ZLIB \
                 /DSQLITE_ENABLE_DBPAGE_VTAB \
                 /DSQLITE_TRUSTED_SCHEMA=0 \
                 /DHAVE_USLEEP \
                 /DSQLITE_WIN32_NO_ANSI








>


|
|







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
343
344
345
346
347
348
349
350
351
                /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 \
                /DSQLITE_ENABLE_DBSTAT_VTAB \
                /DSQLITE_ENABLE_FTS5 \
                /DSQLITE_ENABLE_STMTVTAB \
                /DSQLITE_HAVE_ZLIB \
                /DSQLITE_ENABLE_DBPAGE_VTAB \
                /DSQLITE_TRUSTED_SCHEMA=0 \
                /DHAVE_USLEEP \
                /Dmain=sqlite3_shell \
                /DSQLITE_SHELL_IS_UTF8=1 \







>


|
|







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
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
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).

**Important:** Do not confuse that screen with Admin → Email-Server,
which sets up a different subsystem within Fossil. That feature is
related to this document's topic, but it is currently incomplete, so we
do not cover it at this time.

<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 Postfix, Exim, or Sendmail server on the
machine running your Fossil instance(s), and you aren't using Fossil's

`chroot` feature 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







<
<
<
<
<
















|
|
>
|







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
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
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>

There is limited support for building under MinGW's native Windows port
of GNU Make instead by defining the <tt>USE_WINDOWS=1</tt> variable, but
it's better to build under MSYS, Cygwin, or WSL on Windows since this
mode doesn't take care of cases such as the "openssl" target, which
depends on <tt>sed</tt>. We've gone as far down this path as is
practical short of breaking cross-compilation under Linux, macOS, and so
forth, as we'd have to do to make everything work under
<tt>cmd.exe</tt>.

Unless you're building under MSYS where commands like "<tt>gcc</tt>"
give MinGW's GCC and not some other version, you will need to make minor
edits to win/Makefile.mingw to configure the cross-compilation
environment. It should suffice to switch to one of the predefined
<tt>PREFIX</tt> values, causing the build to be done using
"<tt>x86_64-w64-mingw32-gcc</tt>" for example, yielding a 64-bit native
Windows binary.

To enable the native [./th1.md#tclEval | Tcl integration feature], use a
command line like the following (all on one line):

<b>make -f win/Makefile.mingw FOSSIL_ENABLE_TCL=1 FOSSIL_ENABLE_TCL_STUBS=1 FOSSIL_ENABLE_TCL_PRIVATE_STUBS=1</b>


Alternatively, running <b>./configure</b> under MSYS should give a






suitable top-level Makefile. However, options passed to configure that are




not applicable on Windows may cause the configuration or compilation to fail

(e.g. fusefs, internal-sqlite, etc).




<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.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|

>
|
>
>
>
>
>
>
|
>
>
>
>
|
>
|
>
>
>







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














































5






6
7
8
9
10
11
12
<title>Change Log</title>

<h2 id='v2_26'>Changes for version 2.26 (pending)</h2>















































  *  <i>(pending)</i>







<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




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>







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
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
# 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, once it's done everything that requires root access. Most commonly,
you run Fossil as root to allow it to bind to TCP port 80 for HTTP
service, since normal users are restricted to ports 1024 and up on OSes
where this behavior occurs.

Fossil uses the owner of the Fossil repository file as its new user
ID when dropping root privileges.

When this happens, Fossil needs to have all of its dependencies inside
the chroot jail in order to continue work.  There are several things you

typically need in order to make things work properly:

*   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 in order to protect the host OS. You can make it

bypass the jail part of this by passing <tt>--nojail</tt> to <tt>fossil server</tt>,

but you cannot make it skip the dropping of root privileges, on purpose.



[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





|
|
|
<


|

|
|
>
|















|
>
|
>
|
>








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
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 optimimizations 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:








|







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
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 %Q" 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.








|







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
45

46
47
48
49
50

51
52
53
54
55
56
57
58
59
<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.

For some reason, the current version of PowerShell included with Windows

chokes on the conversion when the in-flight repository size exceeds
available memory. We do not know why it buffers the entire stream
emitted by "<tt>git fast-export</tt>" before sending it along to Fossil,
but we've seen the problem recur on multiple machines.


While one workaround is to fall back to <tt>cmd.exe</tt> — which doesn't
seem to be affected by this problem — 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>








|
>
|
|
<
|

>
|
|







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
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 2017-07-25
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/site.cgi]

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 8192</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


|




|
















|







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
73
74
75
76
77
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
<a href="http://www.linode.com/">Linode 4096</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].







>











|




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
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

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),
this has been fixed.  Commands like

  * "[fossil server](/help?cmd=server)"
  * "[fossil ui](/help?cmd=ui)", and
  * "[fossil http](/help?cmd=http)"

now all handle server-mode SSL/TLS encryption natively.  It is now possible
to run a secure Fossil server without having to put Fossil behind an encrypting
web server or reverse proxy.  Hence, it is now possible to stand up a complete
Fossil project website on an inexpensive VPS with no added software other than
Fossil itself and something like [certbot](https://certbot.eff.org) for
obtaining a CA-signed certificate.

## 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

The --cert option is what tells Fossil to use TLS encryption.
Normally, the argument to --cert is the name of a file containing
the certificate (the "fullchain.pem" file) for the website.  In this
example, the magic name "unsafe-builtin" is used, which causes Fossil
to use a self-signed cert rather than a real cert obtained from a
[Certificate Authority](https://en.wikipedia.org/wiki/Certificate_authority)

or "CA".  As the name implies, this self-signed cert is not secure and
should only be used for testing.  Your web-browser will complain bitterly 
and will refuse to display the pages using the "unsafe-builtin" cert.


Firefox will allow you to click an "I know the risks" button and continue.
Other web browsers will stubornly refuse to display the page, under the theory



that weak encryption is worse than no encryption at all.  Continue reading



to see how to solve this.



## About Certs


Certs are based on public-key or asymmetric cryptography.  To create a cert,








you first create a new "key pair" consisting of a public key and a private key.
The public key can be freely shared with the world, but you must keep the
private key secret.  If anyone gains access to your private key then he will be
able to impersonate you and break into your system.





To obtain a cert, you send your public key and the name of the domain you


want to protect to a certificate authority.  The CA then digitally signs
the combination of those two things using their own private key and sends
the signed combination back to you.  The CA's digital signature of your




public key and domain name is the cert.









SSL/TLS servers need two things in order to prove their identity to clients:




  1.  The cert that was signed by a CA
  2.  The private key




The SSL/TLS servers send the cert to each client, so that the client
can verify it.  But the private key is kept strictly private and is never
shared with anyone.


## How To Tell Fossil About Your Cert And Private Key


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](/info/c2a7b14c3f541edb96?ln=89-116) 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.  The 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.



If you have a single 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
at /home/www and drop all root privileges.









### Keeping The Cert And Private Key In Separate Files







If you do not want to combine your cert and private key into a single

big PEM file, you can keep them separate using the --pkey option to






Fossil.









    fossil server --port 443 --cert fullchain.pem --pkey privkey.pem /home/www/myproject.fossil




































## The ACME Protocol






The [ACME Protocol][2] is used to prove to a CA that you control a
website.  CAs require proof that you control a domain before they
will issue a cert for that domain.  The usual means of dealing
with ACME is to run the separate [certbot](https://certbot.eff.org) tool.

Here is, in a nutshell, what certbot will do to obtain your cert:

  1.  Certbot 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.  To do this (or, one common
      way of doing this, at least) the CA sends a secret token back to
      certbot through a secure backchannel, and instructs certbot to make
      that token accessible on the (unencrypted, ordinary "http:") web site
      for the domain in a particular file under the ".well-known" subdirectory.


  3.  Certbot puts the token where the CA requested it, then notifies the
      CA that it is there.


  4.  The CA accesses the token to confirm that you do indeed control the


      website.  It then creates the cert and sends it back to certbot.



  5.  Certbot stores your cert and deletes the ".well-known" token.



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, and
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 the --acme option is specified and 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, then you can concatenate that
cert with your private key and run Fossil in SSL/TLS mode as shown above.


[2]: https://en.wikipedia.org/wiki/Automated_Certificate_Management_Environment








|





|
<
<
<
<
|

|


|



<
<
<
|
|
|
>
|
|
|
>
>
|
|
>
>
>
|
>
>
>
|
>
>

|

>
|
>
>
>
>
>
>
>
>
|
<
<
<
>
>
>

>
|
>
>
|
<
|
>
>
>
>
|
>
>
>
>
>
>
>
>

|
>
>
>

<
|
>
>
>

<
<
<
>

|

>
|

|
|


|




















|


>
>
|

|







|
|

>
>
>
>
>
>
>
>
|
>

>
>
>
>
>
|
>
|
>
>
>
>
>
>
|
>
>
>
>

>
>
>
>
|
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>

<
<
<
|
>


|


|
|
|
<
<
|

>
|
|
>

|
>
>
|

>
>
|
>
>


|



>
|


















|
|
>


>
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 CAs 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.