Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a7cfbebb0 | |||
| db05c66a16 | |||
| 71475478a1 | |||
| c8edf07ca7 | |||
| d9bc2bb638 | |||
| 3c39f1f5d6 | |||
| dac0d0b310 | |||
| 4a972bc1b8 | |||
| 8aa9135f2c | |||
| fcd65efcf1 | |||
| c013fa50db | |||
| 1321ea5010 | |||
| 87ebadbf4e | |||
| cc902fd25e | |||
| 306a8dcf3e | |||
| 838d2d3078 | |||
| 1d5a12e6a5 | |||
| f9eff9052d | |||
| 58b08d7702 | |||
| 27095fc4a5 | |||
| 7766c9943e | |||
| 789da35848 | |||
| 8d4edd0d67 | |||
| 5804da0218 | |||
| d55ab84451 | |||
| 889ce8ee90 | |||
| 3a39c44c21 | |||
| 20728a599e |
+8
-3
@@ -117,6 +117,11 @@ HAVE_TCL = @HAVE_TCL@
|
||||
#
|
||||
TCLSH_CMD = @TCLSH_CMD@
|
||||
|
||||
# Additional options when running tests using testrunner.tcl
|
||||
# This is usually either blank, or else --status
|
||||
#
|
||||
TSTRNNR_OPTS = @TSTRNNR_OPTS@
|
||||
|
||||
# Where do we want to install the tcl plugin
|
||||
#
|
||||
TCLLIBDIR = @TCLLIBDIR@
|
||||
@@ -1363,10 +1368,10 @@ testrunner: testfixture$(TEXE)
|
||||
devtest: srctree-check testfixture$(TEXE) fuzztest testrunner
|
||||
|
||||
mdevtest: srctree-check has_tclsh85
|
||||
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest
|
||||
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest $(TSTRNNR_OPTS)
|
||||
|
||||
sdevtest: has_tclsh85
|
||||
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest
|
||||
$(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest $(TSTRNNR_OPTS)
|
||||
|
||||
# Validate that various generated files in the source tree
|
||||
# are up-to-date.
|
||||
@@ -1377,7 +1382,7 @@ srctree-check: $(TOP)/tool/srctree-check.tcl
|
||||
# Testing for a release
|
||||
#
|
||||
releasetest: srctree-check testfixture$(TEXE)
|
||||
./testfixture$(TEXE) $(TOP)/test/testrunner.tcl release
|
||||
./testfixture$(TEXE) $(TOP)/test/testrunner.tcl release $(TSTRNNR_OPTS)
|
||||
|
||||
# Minimal testing that runs in less than 3 minutes
|
||||
#
|
||||
|
||||
@@ -793,6 +793,7 @@ HAVE_WASI_SDK
|
||||
RELEASE
|
||||
VERSION
|
||||
program_prefix
|
||||
TSTRNNR_OPTS
|
||||
TCLLIBDIR
|
||||
HAVE_TCL
|
||||
TCL_STUB_LIB_SPEC
|
||||
@@ -889,6 +890,7 @@ enable_largefile
|
||||
with_tclsh
|
||||
with_tcl
|
||||
enable_tcl
|
||||
enable_test_status
|
||||
with_wasi_sdk
|
||||
enable_threadsafe
|
||||
enable_releasemode
|
||||
@@ -1546,6 +1548,7 @@ Optional Features:
|
||||
--disable-largefile omit support for large files
|
||||
--disable-tcl omit building accessory programs that require
|
||||
TCL-dev
|
||||
--enable-test-status Full-screen status of tests
|
||||
--disable-threadsafe Disable mutexing
|
||||
--enable-releasemode Support libtool link to release mode
|
||||
--enable-tempstore Use an in-ram database for temporary tables
|
||||
@@ -3939,13 +3942,13 @@ if ${lt_cv_nm_interface+:} false; then :
|
||||
else
|
||||
lt_cv_nm_interface="BSD nm"
|
||||
echo "int some_variable = 0;" > conftest.$ac_ext
|
||||
(eval echo "\"\$as_me:3942: $ac_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:3945: $ac_compile\"" >&5)
|
||||
(eval "$ac_compile" 2>conftest.err)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:3945: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval echo "\"\$as_me:3948: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
|
||||
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
|
||||
cat conftest.err >&5
|
||||
(eval echo "\"\$as_me:3948: output\"" >&5)
|
||||
(eval echo "\"\$as_me:3951: output\"" >&5)
|
||||
cat conftest.out >&5
|
||||
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
|
||||
lt_cv_nm_interface="MS dumpbin"
|
||||
@@ -5151,7 +5154,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
*-*-irix6*)
|
||||
# Find out which ABI we are using.
|
||||
echo '#line 5154 "configure"' > conftest.$ac_ext
|
||||
echo '#line 5157 "configure"' > conftest.$ac_ext
|
||||
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
|
||||
(eval $ac_compile) 2>&5
|
||||
ac_status=$?
|
||||
@@ -6676,11 +6679,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:6679: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:6682: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:6683: \$? = $ac_status" >&5
|
||||
echo "$as_me:6686: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@@ -7015,11 +7018,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7018: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7021: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>conftest.err)
|
||||
ac_status=$?
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:7022: \$? = $ac_status" >&5
|
||||
echo "$as_me:7025: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s "$ac_outfile"; then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
# So say no if there are warnings other than the usual output.
|
||||
@@ -7120,11 +7123,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7123: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7126: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7127: \$? = $ac_status" >&5
|
||||
echo "$as_me:7130: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@@ -7175,11 +7178,11 @@ else
|
||||
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
|
||||
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
|
||||
-e 's:$: $lt_compiler_flag:'`
|
||||
(eval echo "\"\$as_me:7178: $lt_compile\"" >&5)
|
||||
(eval echo "\"\$as_me:7181: $lt_compile\"" >&5)
|
||||
(eval "$lt_compile" 2>out/conftest.err)
|
||||
ac_status=$?
|
||||
cat out/conftest.err >&5
|
||||
echo "$as_me:7182: \$? = $ac_status" >&5
|
||||
echo "$as_me:7185: \$? = $ac_status" >&5
|
||||
if (exit $ac_status) && test -s out/conftest2.$ac_objext
|
||||
then
|
||||
# The compiler can only warn and ignore the option if not recognized
|
||||
@@ -9555,7 +9558,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 9558 "configure"
|
||||
#line 9561 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -9651,7 +9654,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 9654 "configure"
|
||||
#line 9657 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -10484,6 +10487,23 @@ if test "x${TCLLIBDIR+set}" != "xset" ; then
|
||||
TCLLIBDIR="${TCLLIBDIR}/sqlite3"
|
||||
fi
|
||||
|
||||
#########
|
||||
# Set up options for running tests.
|
||||
#
|
||||
# Check whether --enable-test-status was given.
|
||||
if test "${enable_test_status+set}" = set; then :
|
||||
enableval=$enable_test_status; use_vt100=$enableval
|
||||
else
|
||||
use_vt100=no
|
||||
fi
|
||||
|
||||
if test $use_vt100 != no; then
|
||||
TSTRNNR_OPTS=--status
|
||||
else
|
||||
TSTRNNR_OPTS=
|
||||
fi
|
||||
|
||||
|
||||
|
||||
#########
|
||||
# Set up an appropriate program prefix
|
||||
|
||||
@@ -227,6 +227,18 @@ if test "x${TCLLIBDIR+set}" != "xset" ; then
|
||||
TCLLIBDIR="${TCLLIBDIR}/sqlite3"
|
||||
fi
|
||||
|
||||
#########
|
||||
# Set up options for running tests.
|
||||
#
|
||||
AC_ARG_ENABLE(test-status, AS_HELP_STRING([--enable-test-status],[Full-screen status of tests]),
|
||||
[use_vt100=$enableval],[use_vt100=no])
|
||||
if test $use_vt100 != no; then
|
||||
TSTRNNR_OPTS=--status
|
||||
else
|
||||
TSTRNNR_OPTS=
|
||||
fi
|
||||
AC_SUBST(TSTRNNR_OPTS)
|
||||
|
||||
|
||||
#########
|
||||
# Set up an appropriate program prefix
|
||||
|
||||
+82
-2
@@ -595,6 +595,86 @@ oPutbUtf8(const char *cBuf, int nAccept){
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Flush the given output stream. Return non-zero for success, else 0.
|
||||
*/
|
||||
#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE)
|
||||
SQLITE_INTERNAL_LINKAGE int
|
||||
fFlushBuffer(FILE *pfOut){
|
||||
# if CIO_WIN_WC_XLATE && !defined(SHELL_OMIT_FIO_DUPE)
|
||||
return FlushFileBuffers(handleOfFile(pfOut))? 1 : 0;
|
||||
# else
|
||||
return fflush(pfOut);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIO_WIN_WC_XLATE \
|
||||
&& !defined(SHELL_OMIT_FIO_DUPE) \
|
||||
&& defined(SQLITE_USE_ONLY_WIN32)
|
||||
static struct FileAltIds {
|
||||
int fd;
|
||||
HANDLE fh;
|
||||
} altIdsOfFile(FILE *pf){
|
||||
struct FileAltIds rv = { _fileno(pf) };
|
||||
union { intptr_t osfh; HANDLE fh; } fid = {
|
||||
(rv.fd>=0)? _get_osfhandle(rv.fd) : (intptr_t)INVALID_HANDLE_VALUE
|
||||
};
|
||||
rv.fh = fid.fh;
|
||||
return rv;
|
||||
}
|
||||
|
||||
SQLITE_INTERNAL_LINKAGE size_t
|
||||
cfWrite(const void *buf, size_t osz, size_t ocnt, FILE *pf){
|
||||
size_t rv = 0;
|
||||
struct FileAltIds fai = altIdsOfFile(pf);
|
||||
int fmode = _setmode(fai.fd, _O_BINARY);
|
||||
_setmode(fai.fd, fmode);
|
||||
while( rv < ocnt ){
|
||||
size_t nbo = osz;
|
||||
while( nbo > 0 ){
|
||||
DWORD dwno = (nbo>(1L<<24))? 1L<<24 : (DWORD)nbo;
|
||||
BOOL wrc = TRUE;
|
||||
BOOL genCR = (fmode & _O_TEXT)!=0;
|
||||
if( genCR ){
|
||||
const char *pnl = (const char*)memchr(buf, '\n', nbo);
|
||||
if( pnl ) nbo = pnl - (const char*)buf;
|
||||
else genCR = 0;
|
||||
}
|
||||
if( dwno>0 ) wrc = WriteFile(fai.fh, buf, dwno, 0,0);
|
||||
if( genCR && wrc ){
|
||||
wrc = WriteFile(fai.fh, "\r\n", 2, 0,0);
|
||||
++dwno; /* Skip over the LF */
|
||||
}
|
||||
if( !wrc ) return rv;
|
||||
buf = (const char*)buf + dwno;
|
||||
nbo += dwno;
|
||||
}
|
||||
++rv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
SQLITE_INTERNAL_LINKAGE char *
|
||||
cfGets(char *cBuf, int n, FILE *pf){
|
||||
int nci = 0;
|
||||
struct FileAltIds fai = altIdsOfFile(pf);
|
||||
int fmode = _setmode(fai.fd, _O_BINARY);
|
||||
BOOL eatCR = (fmode & _O_TEXT)!=0;
|
||||
_setmode(fai.fd, fmode);
|
||||
while( nci < n-1 ){
|
||||
DWORD nr;
|
||||
if( !ReadFile(fai.fh, cBuf+nci, 1, &nr, 0) || nr==0 ) break;
|
||||
if( nr>0 && (!eatCR || cBuf[nci]!='\r') ) nci += nr;
|
||||
}
|
||||
if( nci < n ) cBuf[nci] = 0;
|
||||
return (nci>0)? cBuf : 0;
|
||||
}
|
||||
# else
|
||||
# define cfWrite(b,os,no,f) fwrite(b,os,no,f)
|
||||
# define cfGets(b,n,f) fgets(b,n,f)
|
||||
# endif
|
||||
|
||||
# ifdef CONSIO_EPUTB
|
||||
SQLITE_INTERNAL_LINKAGE int
|
||||
ePutbUtf8(const char *cBuf, int nAccept){
|
||||
@@ -606,7 +686,7 @@ ePutbUtf8(const char *cBuf, int nAccept){
|
||||
return conZstrEmit(ppst, cBuf, nAccept);
|
||||
}else {
|
||||
# endif
|
||||
return (int)fwrite(cBuf, 1, nAccept, pfErr);
|
||||
return (int)cfWrite(cBuf, 1, nAccept, pfErr);
|
||||
# if CIO_WIN_WC_XLATE
|
||||
}
|
||||
# endif
|
||||
@@ -672,7 +752,7 @@ SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn){
|
||||
# endif
|
||||
}else{
|
||||
# endif
|
||||
return fgets(cBuf, ncMax, pfIn);
|
||||
return cfGets(cBuf, ncMax, pfIn);
|
||||
# if CIO_WIN_WC_XLATE
|
||||
}
|
||||
# endif
|
||||
|
||||
+11
-4
@@ -176,12 +176,19 @@ SQLITE_INTERNAL_LINKAGE int
|
||||
ePutbUtf8(const char *cBuf, int nAccept);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Flush the given output stream. Return non-zero for success, else 0.
|
||||
*/
|
||||
#if !defined(SQLITE_CIO_NO_FLUSH) && !defined(SQLITE_CIO_NO_SETMODE)
|
||||
SQLITE_INTERNAL_LINKAGE int
|
||||
fFlushBuffer(FILE *pfOut);
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Collect input like fgets(...) with special provisions for input
|
||||
** from the console on platforms that require same. Defers to the
|
||||
** C library fgets() when input is not from the console. Newline
|
||||
** translation may be done as set by set{Binary,Text}Mode(). As a
|
||||
** convenience, pfIn==NULL is treated as stdin.
|
||||
** from the console on such platforms as require same. Newline
|
||||
** translation may be done as set by set{Binary,Text}Mode().
|
||||
** As a convenience, pfIn==NULL is treated as stdin.
|
||||
*/
|
||||
SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn);
|
||||
/* Like fGetsUtf8 except stream is always the designated input. */
|
||||
|
||||
@@ -82,7 +82,7 @@ proc get_struct_docs {data names} {
|
||||
set current_doc ""
|
||||
}
|
||||
set subject n/a
|
||||
regexp {^ *([[:alpha:]]*)} $line -> subject
|
||||
regexp {^ *([[:alnum:]_]*)} $line -> subject
|
||||
if {[lsearch $names $subject]>=0} {
|
||||
set current_header $subject
|
||||
} else {
|
||||
|
||||
+10
-9
@@ -379,9 +379,9 @@ struct Fts5ExtensionApi {
|
||||
/* Below this point are iVersion>=4 only */
|
||||
int (*xColumnLocale)(Fts5Context*, int iCol, const char **pz, int *pn);
|
||||
int (*xTokenize_v2)(Fts5Context*,
|
||||
const char *pText, int nText, /* Text to tokenize */
|
||||
const char *pLoc, int nLoc, /* Locale to pass to tokenizer */
|
||||
void *pCtx, /* Context passed to xToken() */
|
||||
const char *pText, int nText, /* Text to tokenize */
|
||||
const char *pLocale, int nLocale, /* Locale to pass to tokenizer */
|
||||
void *pCtx, /* Context passed to xToken() */
|
||||
int (*xToken)(void*, int, const char*, int, int, int) /* Callback */
|
||||
);
|
||||
};
|
||||
@@ -493,18 +493,19 @@ struct Fts5ExtensionApi {
|
||||
**
|
||||
** FTS5_TOKENIZER
|
||||
**
|
||||
** There is also an fts5_tokenizer object. This is an older version of
|
||||
** fts5_tokenizer_v2. It is similar except that:
|
||||
** There is also an fts5_tokenizer object. This is an older, deprecated,
|
||||
** version of fts5_tokenizer_v2. It is similar except that:
|
||||
**
|
||||
** <ul>
|
||||
** <li> There is no "iVersion" field, and
|
||||
** <li> The xTokenize() method does not take a locale argument.
|
||||
** </ul>
|
||||
**
|
||||
** fts5_tokenizer tokenizers should be registered with the xCreateTokenizer()
|
||||
** function, instead of xCreateTokenizer_v2(). Tokenizers implementations
|
||||
** registered using either API may be retrieved using both xFindTokenizer()
|
||||
** and xFindTokenizer_v2().
|
||||
** Legacy fts5_tokenizer tokenizers must be registered using the
|
||||
** legacy xCreateTokenizer() function, instead of xCreateTokenizer_v2().
|
||||
**
|
||||
** Tokenizer implementations registered using either API may be retrieved
|
||||
** using both xFindTokenizer() and xFindTokenizer_v2().
|
||||
**
|
||||
** SYNONYM SUPPORT
|
||||
**
|
||||
|
||||
+51
-3
@@ -746,6 +746,53 @@ static void fts5Bm25Function(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of fts5_get_locale() function.
|
||||
*/
|
||||
static void fts5GetLocaleFunction(
|
||||
const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
|
||||
Fts5Context *pFts, /* First arg to pass to pApi functions */
|
||||
sqlite3_context *pCtx, /* Context for returning result/error */
|
||||
int nVal, /* Number of values in apVal[] array */
|
||||
sqlite3_value **apVal /* Array of trailing arguments */
|
||||
){
|
||||
int iCol = 0;
|
||||
int eType = 0;
|
||||
int rc = SQLITE_OK;
|
||||
const char *zLocale = 0;
|
||||
int nLocale = 0;
|
||||
|
||||
/* xColumnLocale() must be available */
|
||||
assert( pApi->iVersion>=4 );
|
||||
|
||||
if( nVal!=1 ){
|
||||
const char *z = "wrong number of arguments to function fts5_get_locale()";
|
||||
sqlite3_result_error(pCtx, z, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
eType = sqlite3_value_numeric_type(apVal[0]);
|
||||
if( eType!=SQLITE_INTEGER ){
|
||||
const char *z = "non-integer argument passed to function fts5_get_locale()";
|
||||
sqlite3_result_error(pCtx, z, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
iCol = sqlite3_value_int(apVal[0]);
|
||||
if( iCol<0 || iCol>=pApi->xColumnCount(pFts) ){
|
||||
sqlite3_result_error_code(pCtx, SQLITE_RANGE);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = pApi->xColumnLocale(pFts, iCol, &zLocale, &nLocale);
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_result_error_code(pCtx, rc);
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_result_text(pCtx, zLocale, nLocale, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
int sqlite3Fts5AuxInit(fts5_api *pApi){
|
||||
struct Builtin {
|
||||
const char *zFunc; /* Function name (nul-terminated) */
|
||||
@@ -753,9 +800,10 @@ int sqlite3Fts5AuxInit(fts5_api *pApi){
|
||||
fts5_extension_function xFunc;/* Callback function */
|
||||
void (*xDestroy)(void*); /* Destructor function */
|
||||
} aBuiltin [] = {
|
||||
{ "snippet", 0, fts5SnippetFunction, 0 },
|
||||
{ "highlight", 0, fts5HighlightFunction, 0 },
|
||||
{ "bm25", 0, fts5Bm25Function, 0 },
|
||||
{ "snippet", 0, fts5SnippetFunction, 0 },
|
||||
{ "highlight", 0, fts5HighlightFunction, 0 },
|
||||
{ "bm25", 0, fts5Bm25Function, 0 },
|
||||
{ "fts5_get_locale", 0, fts5GetLocaleFunction, 0 },
|
||||
};
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
int i; /* To iterate through builtin functions */
|
||||
|
||||
+14
-12
@@ -3267,7 +3267,9 @@ static int fts5NewTokenizerModule(
|
||||
*/
|
||||
typedef struct Fts5VtoVTokenizer Fts5VtoVTokenizer;
|
||||
struct Fts5VtoVTokenizer {
|
||||
Fts5TokenizerModule *pMod;
|
||||
int bV2Native; /* True if v2 native tokenizer */
|
||||
fts5_tokenizer x1; /* Tokenizer functions */
|
||||
fts5_tokenizer_v2 x2; /* V2 tokenizer functions */
|
||||
Fts5Tokenizer *pReal;
|
||||
};
|
||||
|
||||
@@ -3287,7 +3289,9 @@ static int fts5VtoVCreate(
|
||||
|
||||
pNew = (Fts5VtoVTokenizer*)sqlite3Fts5MallocZero(&rc, sizeof(*pNew));
|
||||
if( rc==SQLITE_OK ){
|
||||
pNew->pMod = pMod;
|
||||
pNew->x1 = pMod->x1;
|
||||
pNew->x2 = pMod->x2;
|
||||
pNew->bV2Native = pMod->bV2Native;
|
||||
if( pMod->bV2Native ){
|
||||
rc = pMod->x2.xCreate(pMod->pUserData, azArg, nArg, &pNew->pReal);
|
||||
}else{
|
||||
@@ -3309,11 +3313,10 @@ static int fts5VtoVCreate(
|
||||
static void fts5VtoVDelete(Fts5Tokenizer *pTok){
|
||||
Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
|
||||
if( p ){
|
||||
Fts5TokenizerModule *pMod = p->pMod;
|
||||
if( pMod->bV2Native ){
|
||||
pMod->x2.xDelete(p->pReal);
|
||||
if( p->bV2Native ){
|
||||
p->x2.xDelete(p->pReal);
|
||||
}else{
|
||||
pMod->x1.xDelete(p->pReal);
|
||||
p->x1.xDelete(p->pReal);
|
||||
}
|
||||
sqlite3_free(p);
|
||||
}
|
||||
@@ -3331,9 +3334,8 @@ static int fts5V1toV2Tokenize(
|
||||
int (*xToken)(void*, int, const char*, int, int, int)
|
||||
){
|
||||
Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
|
||||
Fts5TokenizerModule *pMod = p->pMod;
|
||||
assert( pMod->bV2Native );
|
||||
return pMod->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
|
||||
assert( p->bV2Native );
|
||||
return p->x2.xTokenize(p->pReal, pCtx, flags, pText, nText, 0, 0, xToken);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3348,9 +3350,9 @@ static int fts5V2toV1Tokenize(
|
||||
int (*xToken)(void*, int, const char*, int, int, int)
|
||||
){
|
||||
Fts5VtoVTokenizer *p = (Fts5VtoVTokenizer*)pTok;
|
||||
Fts5TokenizerModule *pMod = p->pMod;
|
||||
assert( pMod->bV2Native==0 );
|
||||
return pMod->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
|
||||
assert( p->bV2Native==0 );
|
||||
UNUSED_PARAM2(pLocale,nLocale);
|
||||
return p->x1.xTokenize(p->pReal, pCtx, flags, pText, nText, xToken);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+96
-15
@@ -96,14 +96,14 @@ static int SQLITE_TCLAPI f5tDbAndApi(
|
||||
|
||||
rc = sqlite3_prepare_v2(db, "SELECT fts5(?1)", -1, &pStmt, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
sqlite3_bind_pointer(pStmt, 1, (void*)&pApi, "fts5_api_ptr", 0);
|
||||
sqlite3_step(pStmt);
|
||||
|
||||
if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ static int SQLITE_TCLAPI xF5tApi(
|
||||
CASE(12, "xSetAuxdata") {
|
||||
F5tAuxData *pData = (F5tAuxData*)sqlite3_malloc(sizeof(F5tAuxData));
|
||||
if( pData==0 ){
|
||||
Tcl_AppendResult(interp, "out of memory", 0);
|
||||
Tcl_AppendResult(interp, "out of memory", (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
pData->pObj = objv[2];
|
||||
@@ -452,7 +452,7 @@ static int SQLITE_TCLAPI xF5tApi(
|
||||
|
||||
rc = p->pApi->xPhraseFirst(p->pFts, iPhrase, &iter, &iCol, &iOff);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
|
||||
Tcl_AppendResult(interp, sqlite3ErrName(rc), (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for( ;iCol>=0; p->pApi->xPhraseNext(p->pFts, &iter, &iCol, &iOff) ){
|
||||
@@ -683,7 +683,7 @@ static int SQLITE_TCLAPI f5tCreateFunction(
|
||||
pApi, zName, (void*)pCtx, xF5tFunction, xF5tDestroy
|
||||
);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -750,7 +750,7 @@ static int SQLITE_TCLAPI f5tTokenize(
|
||||
if( objc==5 ){
|
||||
char *zOpt = Tcl_GetString(objv[1]);
|
||||
if( strcmp("-subst", zOpt) ){
|
||||
Tcl_AppendResult(interp, "unrecognized option: ", zOpt, 0);
|
||||
Tcl_AppendResult(interp, "unrecognized option: ", zOpt, (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -759,7 +759,7 @@ static int SQLITE_TCLAPI f5tTokenize(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( nArg==0 ){
|
||||
Tcl_AppendResult(interp, "no such tokenizer: ", 0);
|
||||
Tcl_AppendResult(interp, "no such tokenizer: ", (char*)0);
|
||||
Tcl_Free((void*)azArg);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -767,13 +767,13 @@ static int SQLITE_TCLAPI f5tTokenize(
|
||||
|
||||
rc = pApi->xFindTokenizer(pApi, azArg[0], &pUserdata, &tokenizer);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "no such tokenizer: ", azArg[0], 0);
|
||||
Tcl_AppendResult(interp, "no such tokenizer: ", azArg[0], (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
rc = tokenizer.xCreate(pUserdata, &azArg[1], (int)(nArg-1), &pTok);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error in tokenizer.xCreate()", 0);
|
||||
Tcl_AppendResult(interp, "error in tokenizer.xCreate()", (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -787,7 +787,7 @@ static int SQLITE_TCLAPI f5tTokenize(
|
||||
);
|
||||
tokenizer.xDelete(pTok);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error in tokenizer.xTokenize()", 0);
|
||||
Tcl_AppendResult(interp, "error in tokenizer.xTokenize()", (char*)0);
|
||||
Tcl_DecrRefCount(pRet);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1049,7 +1049,7 @@ static int SQLITE_TCLAPI f5tTokenizerLocale(
|
||||
|
||||
if( p->xToken==0 ){
|
||||
Tcl_AppendResult(interp,
|
||||
"sqlite3_fts5_locale may only be used by tokenizer callback", 0
|
||||
"sqlite3_fts5_locale may only be used by tokenizer callback", (char*)0
|
||||
);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1098,7 +1098,7 @@ static int SQLITE_TCLAPI f5tTokenizerReturn(
|
||||
|
||||
if( p->xToken==0 ){
|
||||
Tcl_AppendResult(interp,
|
||||
"sqlite3_fts5_token may only be used by tokenizer callback", 0
|
||||
"sqlite3_fts5_token may only be used by tokenizer callback", (char*)0
|
||||
);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1250,7 +1250,7 @@ static int SQLITE_TCLAPI f5tCreateTokenizer(
|
||||
Tcl_AppendResult(interp, (
|
||||
bV2 ? "error in fts5_api.xCreateTokenizer_v2()"
|
||||
: "error in fts5_api.xCreateTokenizer()"
|
||||
), 0);
|
||||
), (char*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1540,12 +1540,92 @@ static int SQLITE_TCLAPI f5tRegisterOriginText(
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), 0);
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), (void*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is used to DROP an fts5 table. It works even if the data
|
||||
** structures fts5 stores within the database are corrupt, which sometimes
|
||||
** prevents a straight "DROP TABLE" command from succeeding.
|
||||
**
|
||||
** The first parameter is the database handle to use for the DROP TABLE
|
||||
** operation. The second is the name of the database to drop the fts5 table
|
||||
** from (i.e. "main", "temp" or the name of an attached database). The
|
||||
** third parameter is the name of the fts5 table to drop.
|
||||
**
|
||||
** SQLITE_OK is returned if the table is successfully dropped. Or, if an
|
||||
** error occurs, an SQLite error code.
|
||||
*/
|
||||
static int sqlite3_fts5_drop_corrupt_table(
|
||||
sqlite3 *db, /* Database handle */
|
||||
const char *zDb, /* Database name ("main", "temp" etc.) */
|
||||
const char *zTab /* Name of fts5 table to drop */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
int bDef = 0;
|
||||
|
||||
rc = sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, -1, &bDef);
|
||||
if( rc==SQLITE_OK ){
|
||||
char *zScript = sqlite3_mprintf(
|
||||
"DELETE FROM %Q.'%q_data';"
|
||||
"DELETE FROM %Q.'%q_config';"
|
||||
"INSERT INTO %Q.'%q_data' VALUES(10, X'0000000000');"
|
||||
"INSERT INTO %Q.'%q_config' VALUES('version', 4);"
|
||||
"DROP TABLE %Q.'%q';",
|
||||
zDb, zTab, zDb, zTab, zDb, zTab, zDb, zTab, zDb, zTab
|
||||
);
|
||||
|
||||
if( zScript==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
if( bDef ) sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, 0, 0);
|
||||
rc = sqlite3_exec(db, zScript, 0, 0, 0);
|
||||
if( bDef ) sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, 1, 0);
|
||||
sqlite3_free(zScript);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3_fts5_drop_corrupt_table DB DATABASE TABLE
|
||||
**
|
||||
** Description...
|
||||
*/
|
||||
static int SQLITE_TCLAPI f5tDropCorruptTable(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
sqlite3 *db = 0;
|
||||
const char *zDb = 0;
|
||||
const char *zTab = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
if( objc!=4 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "DB DATABASE TABLE");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if( f5tDbPointer(interp, objv[1], &db) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
zDb = Tcl_GetString(objv[2]);
|
||||
zTab = Tcl_GetString(objv[3]);
|
||||
|
||||
rc = sqlite3_fts5_drop_corrupt_table(db, zDb, zTab);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_AppendResult(interp, "error: ", sqlite3_errmsg(db), (void*)0);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Entry point.
|
||||
*/
|
||||
@@ -1564,7 +1644,8 @@ int Fts5tcl_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_fts5_token_hash", f5tTokenHash, 0 },
|
||||
{ "sqlite3_fts5_register_matchinfo", f5tRegisterMatchinfo, 0 },
|
||||
{ "sqlite3_fts5_register_fts5tokenize", f5tRegisterTok, 0 },
|
||||
{ "sqlite3_fts5_register_origintext",f5tRegisterOriginText, 0 }
|
||||
{ "sqlite3_fts5_register_origintext",f5tRegisterOriginText, 0 },
|
||||
{ "sqlite3_fts5_drop_corrupt_table", f5tDropCorruptTable, 0 }
|
||||
};
|
||||
int i;
|
||||
F5tTokenizerContext *pContext;
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
# 2024 Aug 28
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] fts5_common.tcl]
|
||||
set testprefix fts5corrupt8
|
||||
|
||||
# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
|
||||
ifcapable !fts5 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
}
|
||||
|
||||
do_execsql_test 1.1 {
|
||||
UPDATE t1_data SET block='hello world' WHERE id=10
|
||||
}
|
||||
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
|
||||
do_catchsql_test 1.2 {
|
||||
SELECT * FROM t1
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
do_catchsql_test 1.3 {
|
||||
DROP TABLE t1
|
||||
} {1 {vtable constructor failed: t1}}
|
||||
do_test 1.4 {
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
} {0}
|
||||
do_test 1.5 {
|
||||
sqlite3_fts5_drop_corrupt_table db main t1
|
||||
} {}
|
||||
do_test 1.6 {
|
||||
sqlite3_db_config db DEFENSIVE -1
|
||||
} {0}
|
||||
do_execsql_test 1.7 {
|
||||
SELECT * FROM sqlite_schema
|
||||
}
|
||||
|
||||
do_execsql_test 2.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
}
|
||||
do_execsql_test 2.1 {
|
||||
UPDATE t1_config SET v=555 WHERE k='version'
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_catchsql_test 2.2 {
|
||||
SELECT * FROM t1
|
||||
} {1 {invalid fts5 file format (found 555, expected 4 or 5) - run 'rebuild'}}
|
||||
do_catchsql_test 2.3 {
|
||||
DROP TABLE t1
|
||||
} {1 {invalid fts5 file format (found 555, expected 4 or 5) - run 'rebuild'}}
|
||||
do_test 2.4 {
|
||||
sqlite3_fts5_drop_corrupt_table db main t1
|
||||
} {}
|
||||
do_execsql_test 2.5 {
|
||||
SELECT * FROM sqlite_schema
|
||||
}
|
||||
|
||||
do_execsql_test 3.0 {
|
||||
CREATE VIRTUAL TABLE t1 USING fts5(x);
|
||||
}
|
||||
do_execsql_test 3.1 {
|
||||
DELETE FROM t1_config;
|
||||
}
|
||||
db close
|
||||
sqlite3 db test.db
|
||||
do_catchsql_test 3.2 {
|
||||
SELECT * FROM t1
|
||||
} {1 {invalid fts5 file format (found 0, expected 4 or 5) - run 'rebuild'}}
|
||||
do_catchsql_test 3.3 {
|
||||
DROP TABLE t1
|
||||
} {1 {invalid fts5 file format (found 0, expected 4 or 5) - run 'rebuild'}}
|
||||
|
||||
|
||||
do_test 3.4 {
|
||||
sqlite3_db_config db DEFENSIVE 1
|
||||
} {1}
|
||||
do_test 3.5 {
|
||||
sqlite3_fts5_drop_corrupt_table db main t1
|
||||
} {}
|
||||
do_test 3.6 {
|
||||
sqlite3_db_config db DEFENSIVE -1
|
||||
} {1}
|
||||
do_execsql_test 3.7 {
|
||||
SELECT * FROM sqlite_schema
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -231,6 +231,30 @@ do_faultsim_test 9.2 -faults oom* -prep {
|
||||
faultsim_test_result {0 1}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
|
||||
do_execsql_test 10.0 {
|
||||
CREATE VIRTUAL TABLE ft USING fts5(x, locale=1);
|
||||
INSERT INTO ft VALUES(fts5_locale('hello', 'one two three i ii iii'));
|
||||
INSERT INTO ft VALUES('four five six iv v vi');
|
||||
INSERT INTO ft VALUES('eight nine ten viii ix x');
|
||||
} {}
|
||||
|
||||
do_execsql_test 10.1 {
|
||||
SELECT fts5_get_locale(ft, 0) FROM ft WHERE x MATCH 'one AND two AND three'
|
||||
} {hello}
|
||||
|
||||
faultsim_save_and_close
|
||||
do_faultsim_test 10 -faults oom* -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
execsql {
|
||||
SELECT fts5_get_locale(ft, 0) FROM ft WHERE x MATCH 'one AND two AND three'
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 hello}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -572,5 +572,96 @@ do_test 12.0 {
|
||||
} msg] $msg
|
||||
} {1 {error in fts5_api.xCreateTokenizer_v2()}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Tests for auxiliary function fts5_get_locale().
|
||||
#
|
||||
reset_db
|
||||
|
||||
# Check that if the table does not support locale=1, fts5_get_locale()
|
||||
# always returns NULL.
|
||||
do_execsql_test 13.1.0 {
|
||||
CREATE VIRTUAL TABLE nolocale USING fts5(a, b);
|
||||
INSERT INTO nolocale VALUES('one two three', 'four five six');
|
||||
INSERT INTO nolocale VALUES('three two one', 'seven eight nine');
|
||||
}
|
||||
do_execsql_test 13.1.1 {
|
||||
SELECT fts5_get_locale(nolocale, 0) IS NULL FROM nolocale;
|
||||
} {1 1}
|
||||
do_execsql_test 13.1.2 {
|
||||
SELECT fts5_get_locale(nolocale, 1) IS NULL FROM nolocale('one + two');
|
||||
} {1}
|
||||
do_execsql_test 13.1.3 {
|
||||
SELECT fts5_get_locale(nolocale, 0) IS NULL FROM nolocale('one AND two');
|
||||
} {1 1}
|
||||
do_execsql_test 13.1.4 {
|
||||
SELECT
|
||||
fts5_get_locale(nolocale, 1) IS NULL
|
||||
FROM nolocale('three AND two') ORDER BY rank
|
||||
} {1 1}
|
||||
do_catchsql_test 13.1.5 {
|
||||
SELECT fts5_get_locale(nolocale, 2) IS NULL FROM nolocale('three AND two');
|
||||
} {1 {column index out of range}}
|
||||
do_catchsql_test 13.1.6 {
|
||||
SELECT fts5_get_locale(nolocale, -1) IS NULL FROM nolocale('three AND two');
|
||||
} {1 {column index out of range}}
|
||||
do_catchsql_test 13.1.7 {
|
||||
SELECT fts5_get_locale(nolocale) IS NULL FROM nolocale('three AND two');
|
||||
} {1 {wrong number of arguments to function fts5_get_locale()}}
|
||||
do_catchsql_test 13.1.8 {
|
||||
SELECT fts5_get_locale(nolocale, 0, 0) IS NULL FROM nolocale('three AND two');
|
||||
} {1 {wrong number of arguments to function fts5_get_locale()}}
|
||||
do_catchsql_test 13.1.9 {
|
||||
SELECT fts5_get_locale(nolocale, 'text') FROM nolocale('three AND two');
|
||||
} {1 {non-integer argument passed to function fts5_get_locale()}}
|
||||
|
||||
|
||||
# Check that if the table does support locale=1, fts5_get_locale()
|
||||
# returns the locale of the identified row/column.
|
||||
do_execsql_test 13.2.0 {
|
||||
CREATE VIRTUAL TABLE ft USING fts5(a, b, locale=1);
|
||||
INSERT INTO ft VALUES(
|
||||
fts5_locale('th_TH', 'one two three'), 'four five six seven'
|
||||
);
|
||||
INSERT INTO ft VALUES(
|
||||
'three two one', fts5_locale('en_AU', 'seven eight nine')
|
||||
);
|
||||
}
|
||||
|
||||
do_execsql_test 13.2.1 {
|
||||
SELECT quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1)) FROM ft
|
||||
} { 'th_TH' NULL NULL 'en_AU' }
|
||||
do_execsql_test 13.2.2 {
|
||||
SELECT
|
||||
quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1))
|
||||
FROM ft('one AND three')
|
||||
} { 'th_TH' NULL NULL 'en_AU' }
|
||||
do_execsql_test 13.2.3 {
|
||||
SELECT
|
||||
quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1))
|
||||
FROM ft('one AND three') ORDER BY rank
|
||||
} { NULL 'en_AU' 'th_TH' NULL }
|
||||
do_execsql_test 13.2.4 {
|
||||
SELECT
|
||||
quote(fts5_get_locale(ft, 0)), quote(fts5_get_locale(ft, 1))
|
||||
FROM ft('one AND three') ORDER BY rowid
|
||||
} { 'th_TH' NULL NULL 'en_AU' }
|
||||
|
||||
do_execsql_test 13.2.5 {
|
||||
SELECT
|
||||
quote(fts5_get_locale(ft, '0')), quote(fts5_get_locale(ft, 1))
|
||||
FROM ft('one AND three') ORDER BY rowid
|
||||
} { 'th_TH' NULL NULL 'en_AU' }
|
||||
|
||||
do_catchsql_test 13.2.6 {
|
||||
SELECT
|
||||
quote(fts5_get_locale(ft, '0.0')), quote(fts5_get_locale(ft, 1))
|
||||
FROM ft('one AND three') ORDER BY rowid
|
||||
} {1 {non-integer argument passed to function fts5_get_locale()}}
|
||||
do_catchsql_test 13.2.7 {
|
||||
SELECT
|
||||
quote(fts5_get_locale(ft, 0.0)), quote(fts5_get_locale(ft, 1))
|
||||
FROM ft('one AND three') ORDER BY rowid
|
||||
} {1 {non-integer argument passed to function fts5_get_locale()}}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
+223
-31
@@ -90,6 +90,26 @@
|
||||
** and a very large cost if either start or stop are unavailable. This
|
||||
** encourages the query planner to order joins such that the bounds of the
|
||||
** series are well-defined.
|
||||
**
|
||||
** Update on 2024-08-22:
|
||||
** xBestIndex now also looks for equality and inequality constraints against
|
||||
** the value column and uses those constraints as additional bounds against
|
||||
** the sequence range. Thus, a query like this:
|
||||
**
|
||||
** SELECT value FROM generate_series($SA,$EA)
|
||||
** WHERE value BETWEEN $SB AND $EB;
|
||||
**
|
||||
** Is logically the same as:
|
||||
**
|
||||
** SELECT value FROM generate_series(max($SA,$SB),min($EA,$EB));
|
||||
**
|
||||
** Constraints on the value column can server as substitutes for constraints
|
||||
** on the hidden start and stop columns. So, the following two queries
|
||||
** are equivalent:
|
||||
**
|
||||
** SELECT value FROM generate_series($S,$E);
|
||||
** SELECT value FROM generate_series WHERE value BETWEEN $S and $E;
|
||||
**
|
||||
*/
|
||||
#include "sqlite3ext.h"
|
||||
SQLITE_EXTENSION_INIT1
|
||||
@@ -131,8 +151,10 @@ static sqlite3_int64 genSeqMember(
|
||||
typedef unsigned char u8;
|
||||
|
||||
typedef struct SequenceSpec {
|
||||
sqlite3_int64 iBase; /* Starting value ("start") */
|
||||
sqlite3_int64 iTerm; /* Given terminal value ("stop") */
|
||||
sqlite3_int64 iOBase; /* Original starting value ("start") */
|
||||
sqlite3_int64 iOTerm; /* Original terminal value ("stop") */
|
||||
sqlite3_int64 iBase; /* Starting value to actually use */
|
||||
sqlite3_int64 iTerm; /* Terminal value to actually use */
|
||||
sqlite3_int64 iStep; /* Increment ("step") */
|
||||
sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */
|
||||
sqlite3_uint64 uSeqIndexNow; /* Current index during generation */
|
||||
@@ -325,9 +347,9 @@ static int seriesColumn(
|
||||
series_cursor *pCur = (series_cursor*)cur;
|
||||
sqlite3_int64 x = 0;
|
||||
switch( i ){
|
||||
case SERIES_COLUMN_START: x = pCur->ss.iBase; break;
|
||||
case SERIES_COLUMN_STOP: x = pCur->ss.iTerm; break;
|
||||
case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break;
|
||||
case SERIES_COLUMN_START: x = pCur->ss.iOBase; break;
|
||||
case SERIES_COLUMN_STOP: x = pCur->ss.iOTerm; break;
|
||||
case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break;
|
||||
default: x = pCur->ss.iValueNow; break;
|
||||
}
|
||||
sqlite3_result_int64(ctx, x);
|
||||
@@ -335,7 +357,9 @@ static int seriesColumn(
|
||||
}
|
||||
|
||||
#ifndef LARGEST_UINT64
|
||||
#define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
|
||||
#define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32))
|
||||
#define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -376,13 +400,18 @@ static int seriesEof(sqlite3_vtab_cursor *cur){
|
||||
** parameter. (idxStr is not used in this implementation.) idxNum
|
||||
** is a bitmask showing which constraints are available:
|
||||
**
|
||||
** 0x01: start=VALUE
|
||||
** 0x02: stop=VALUE
|
||||
** 0x04: step=VALUE
|
||||
** 0x08: descending order
|
||||
** 0x10: ascending order
|
||||
** 0x20: LIMIT VALUE
|
||||
** 0x40: OFFSET VALUE
|
||||
** 0x0001: start=VALUE
|
||||
** 0x0002: stop=VALUE
|
||||
** 0x0004: step=VALUE
|
||||
** 0x0008: descending order
|
||||
** 0x0010: ascending order
|
||||
** 0x0020: LIMIT VALUE
|
||||
** 0x0040: OFFSET VALUE
|
||||
** 0x0080: value=VALUE
|
||||
** 0x0100: value>=VALUE
|
||||
** 0x0200: value>VALUE
|
||||
** 0x1000: value<=VALUE
|
||||
** 0x2000: value<VALUE
|
||||
**
|
||||
** This routine should initialize the cursor and position it so that it
|
||||
** is pointing at the first row, or pointing off the end of the table
|
||||
@@ -395,6 +424,12 @@ static int seriesFilter(
|
||||
){
|
||||
series_cursor *pCur = (series_cursor *)pVtabCursor;
|
||||
int i = 0;
|
||||
int returnNoRows = 0;
|
||||
sqlite3_int64 iMin = SMALLEST_INT64;
|
||||
sqlite3_int64 iMax = LARGEST_INT64;
|
||||
sqlite3_int64 iLimit = 0;
|
||||
sqlite3_int64 iOffset = 0;
|
||||
|
||||
(void)idxStrUnused;
|
||||
if( idxNum & 0x01 ){
|
||||
pCur->ss.iBase = sqlite3_value_int64(argv[i++]);
|
||||
@@ -416,16 +451,98 @@ static int seriesFilter(
|
||||
}else{
|
||||
pCur->ss.iStep = 1;
|
||||
}
|
||||
|
||||
/* If there are constraints on the value column but there are
|
||||
** no constraints on the start, stop, and step columns, then
|
||||
** initialize the default range to be the entire range of 64-bit signed
|
||||
** integers. This range will contracted by the value column constraints
|
||||
** further below.
|
||||
*/
|
||||
if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){
|
||||
pCur->ss.iBase = SMALLEST_INT64;
|
||||
}
|
||||
if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){
|
||||
pCur->ss.iTerm = LARGEST_INT64;
|
||||
}
|
||||
pCur->ss.iOBase = pCur->ss.iBase;
|
||||
pCur->ss.iOTerm = pCur->ss.iTerm;
|
||||
|
||||
/* Extract the LIMIT and OFFSET values, but do not apply them yet.
|
||||
** The range must first be constrained by the limits on value.
|
||||
*/
|
||||
if( idxNum & 0x20 ){
|
||||
sqlite3_int64 iLimit = sqlite3_value_int64(argv[i++]);
|
||||
sqlite3_int64 iTerm;
|
||||
iLimit = sqlite3_value_int64(argv[i++]);
|
||||
if( idxNum & 0x40 ){
|
||||
sqlite3_int64 iOffset = sqlite3_value_int64(argv[i++]);
|
||||
if( iOffset>0 ){
|
||||
pCur->ss.iBase += pCur->ss.iStep*iOffset;
|
||||
iOffset = sqlite3_value_int64(argv[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
if( idxNum & 0x3380 ){
|
||||
/* Extract the maximum range of output values determined by
|
||||
** constraints on the "value" column.
|
||||
*/
|
||||
if( idxNum & 0x0080 ){
|
||||
iMin = iMax = sqlite3_value_int64(argv[i++]);
|
||||
}else{
|
||||
if( idxNum & 0x0300 ){
|
||||
iMin = sqlite3_value_int64(argv[i++]);
|
||||
if( idxNum & 0x0200 ){
|
||||
if( iMin==LARGEST_INT64 ){
|
||||
returnNoRows = 1;
|
||||
}else{
|
||||
iMin++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( idxNum & 0x3000 ){
|
||||
iMax = sqlite3_value_int64(argv[i++]);
|
||||
if( idxNum & 0x2000 ){
|
||||
if( iMax==SMALLEST_INT64 ){
|
||||
returnNoRows = 1;
|
||||
}else{
|
||||
iMax--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( iMin>iMax ){
|
||||
returnNoRows = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to reduce the range of values to be generated based on
|
||||
** constraints on the "value" column.
|
||||
*/
|
||||
if( pCur->ss.iStep>0 ){
|
||||
sqlite3_int64 szStep = pCur->ss.iStep;
|
||||
if( pCur->ss.iBase<iMin ){
|
||||
sqlite3_uint64 d = iMin - pCur->ss.iBase;
|
||||
pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep;
|
||||
}
|
||||
if( pCur->ss.iTerm>iMax ){
|
||||
sqlite3_uint64 d = pCur->ss.iTerm - iMax;
|
||||
pCur->ss.iTerm -= ((d+szStep-1)/szStep)*szStep;
|
||||
}
|
||||
}else{
|
||||
sqlite3_int64 szStep = -pCur->ss.iStep;
|
||||
assert( szStep>0 );
|
||||
if( pCur->ss.iBase>iMax ){
|
||||
sqlite3_uint64 d = pCur->ss.iBase - iMax;
|
||||
pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep;
|
||||
}
|
||||
if( pCur->ss.iTerm<iMin ){
|
||||
sqlite3_uint64 d = iMin - pCur->ss.iTerm;
|
||||
pCur->ss.iTerm += ((d+szStep-1)/szStep)*szStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Apply LIMIT and OFFSET constraints, if any */
|
||||
if( idxNum & 0x20 ){
|
||||
if( iOffset>0 ){
|
||||
pCur->ss.iBase += pCur->ss.iStep*iOffset;
|
||||
}
|
||||
if( iLimit>=0 ){
|
||||
sqlite3_int64 iTerm;
|
||||
iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep;
|
||||
if( pCur->ss.iStep<0 ){
|
||||
if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm;
|
||||
@@ -434,16 +551,21 @@ static int seriesFilter(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(i=0; i<argc; i++){
|
||||
if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
|
||||
/* If any of the constraints have a NULL value, then return no rows.
|
||||
** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */
|
||||
pCur->ss.iBase = 1;
|
||||
pCur->ss.iTerm = 0;
|
||||
pCur->ss.iStep = 1;
|
||||
returnNoRows = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( returnNoRows ){
|
||||
pCur->ss.iBase = 1;
|
||||
pCur->ss.iTerm = 0;
|
||||
pCur->ss.iStep = 1;
|
||||
}
|
||||
if( idxNum & 0x08 ){
|
||||
pCur->ss.isReversing = pCur->ss.iStep > 0;
|
||||
}else{
|
||||
@@ -464,13 +586,35 @@ static int seriesFilter(
|
||||
**
|
||||
** The query plan is represented by bits in idxNum:
|
||||
**
|
||||
** 0x01 start = $value -- constraint exists
|
||||
** 0x02 stop = $value -- constraint exists
|
||||
** 0x04 step = $value -- constraint exists
|
||||
** 0x08 output is in descending order
|
||||
** 0x10 output is in ascending order
|
||||
** 0x20 LIMIT $value -- constraint exists
|
||||
** 0x40 OFFSET $value -- constraint exists
|
||||
** 0x0001 start = $num
|
||||
** 0x0002 stop = $num
|
||||
** 0x0004 step = $num
|
||||
** 0x0008 output is in descending order
|
||||
** 0x0010 output is in ascending order
|
||||
** 0x0020 LIMIT $num
|
||||
** 0x0040 OFFSET $num
|
||||
** 0x0080 value = $num
|
||||
** 0x0100 value >= $num
|
||||
** 0x0200 value > $num
|
||||
** 0x1000 value <= $num
|
||||
** 0x2000 value < $num
|
||||
**
|
||||
** Only one of 0x0100 or 0x0200 will be returned. Similarly, only
|
||||
** one of 0x1000 or 0x2000 will be returned. If the 0x0080 is set, then
|
||||
** none of the 0xff00 bits will be set.
|
||||
**
|
||||
** The order of parameters passed to xFilter is as follows:
|
||||
**
|
||||
** * The argument to start= if bit 0x0001 is in the idxNum mask
|
||||
** * The argument to stop= if bit 0x0002 is in the idxNum mask
|
||||
** * The argument to step= if bit 0x0004 is in the idxNum mask
|
||||
** * The argument to LIMIT if bit 0x0020 is in the idxNum mask
|
||||
** * The argument to OFFSET if bit 0x0040 is in the idxNum mask
|
||||
** * The argument to value=, or value>= or value> if any of
|
||||
** bits 0x0380 are in the idxNum mask
|
||||
** * The argument to value<= or value< if either of bits 0x3000
|
||||
** are in the mask
|
||||
**
|
||||
*/
|
||||
static int seriesBestIndex(
|
||||
sqlite3_vtab *pVTab,
|
||||
@@ -483,7 +627,9 @@ static int seriesBestIndex(
|
||||
#endif
|
||||
int unusableMask = 0; /* Mask of unusable constraints */
|
||||
int nArg = 0; /* Number of arguments that seriesFilter() expects */
|
||||
int aIdx[5]; /* Constraints on start, stop, step, LIMIT, OFFSET */
|
||||
int aIdx[7]; /* Constraints on start, stop, step, LIMIT, OFFSET,
|
||||
** and value. aIdx[5] covers value=, value>=, and
|
||||
** value>, aIdx[6] covers value<= and value< */
|
||||
const struct sqlite3_index_constraint *pConstraint;
|
||||
|
||||
/* This implementation assumes that the start, stop, and step columns
|
||||
@@ -491,7 +637,7 @@ static int seriesBestIndex(
|
||||
assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 );
|
||||
assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 );
|
||||
|
||||
aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = -1;
|
||||
aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = aIdx[5] = aIdx[6] = -1;
|
||||
pConstraint = pIdxInfo->aConstraint;
|
||||
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
|
||||
int iCol; /* 0 for start, 1 for stop, 2 for step */
|
||||
@@ -512,7 +658,50 @@ static int seriesBestIndex(
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if( pConstraint->iColumn<SERIES_COLUMN_START ) continue;
|
||||
if( pConstraint->iColumn==SERIES_COLUMN_VALUE ){
|
||||
switch( op ){
|
||||
case SQLITE_INDEX_CONSTRAINT_EQ:
|
||||
case SQLITE_INDEX_CONSTRAINT_IS: {
|
||||
idxNum |= 0x0080;
|
||||
idxNum &= ~0x3300;
|
||||
aIdx[5] = i;
|
||||
aIdx[6] = -1;
|
||||
bStartSeen = 1;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_GE: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x0100;
|
||||
idxNum &= ~0x0200;
|
||||
aIdx[5] = i;
|
||||
bStartSeen = 1;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_GT: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x0200;
|
||||
idxNum &= ~0x0100;
|
||||
aIdx[5] = i;
|
||||
bStartSeen = 1;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_LE: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x1000;
|
||||
idxNum &= ~0x2000;
|
||||
aIdx[6] = i;
|
||||
break;
|
||||
}
|
||||
case SQLITE_INDEX_CONSTRAINT_LT: {
|
||||
if( idxNum & 0x0080 ) break;
|
||||
idxNum |= 0x2000;
|
||||
idxNum &= ~0x1000;
|
||||
aIdx[6] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
iCol = pConstraint->iColumn - SERIES_COLUMN_START;
|
||||
assert( iCol>=0 && iCol<=2 );
|
||||
iMask = 1 << iCol;
|
||||
@@ -534,7 +723,7 @@ static int seriesBestIndex(
|
||||
idxNum &= ~0x60;
|
||||
aIdx[4] = 0;
|
||||
}
|
||||
for(i=0; i<5; i++){
|
||||
for(i=0; i<7; i++){
|
||||
if( (j = aIdx[i])>=0 ){
|
||||
pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg;
|
||||
pIdxInfo->aConstraintUsage[j].omit =
|
||||
@@ -582,6 +771,9 @@ static int seriesBestIndex(
|
||||
pIdxInfo->estimatedRows = 2147483647;
|
||||
}
|
||||
pIdxInfo->idxNum = idxNum;
|
||||
#ifdef SQLITE_INDEX_SCAN_HEX
|
||||
pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_HEX;
|
||||
#endif
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
C Add\sthe\snew\sSQLITE_TESTCTRL_OPTGET\sthat\sretrieves\sthe\scurrent\soptimization\nsetting.\s\sUse\sthis\sin\sthe\sCLI\sto\sprovide\ssymbolic\sfine-grain\scontrol\nover\soptimization\ssettings\susing\sthe\s".testctrl\sopt"\sdot-command.
|
||||
D 2024-08-21T18:57:55.594
|
||||
C Fix\stypo\sin\sthe\sprevious\scheck-in.\s\sEnsure\sthat\s--status\sheader\slines\sdo\snot\noverflow\sand\swrap.
|
||||
D 2024-08-27T19:48:19.164
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
F Makefile.in 209e9c64edf499b0ea7a15448699101c01d15828af35a3439d32fc25fdf1b787
|
||||
F Makefile.in 101cb90f75c16ca3f8e7088364322441f9b01d6fdcef4a9c7f5fdcf78a3601a4
|
||||
F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6
|
||||
F Makefile.msc 6c3fe8b6ce60e73f34a148c957d78b4648745c8d30e792423aa1a8d8bf12d065
|
||||
F README.md 3d47ef5758e2de29d6f4e1aca714d51424baba86c8b561fef330f6ef2dc9282c
|
||||
@@ -35,8 +35,8 @@ F autoconf/tea/win/nmakehlp.c b01f822eabbe1ed2b64e70882d97d48402b42d2689a1ea0034
|
||||
F autoconf/tea/win/rules.vc 7b3bb2ef32ade0f3f14d951231811678722725e3bca240dd9727ae0dfe10f6a5
|
||||
F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6
|
||||
F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559
|
||||
F configure 956e132a3e2481e5016e9ecaa0a2bdd9df95c1d923fa4fb2aa2cf9f0b3a54ad9 x
|
||||
F configure.ac fd9ff064b142682964971fec3d867235e51e1f6de30a031e33f683b7699338ff
|
||||
F configure 49523f0a070b583cea040d26eff53a65fb0893eca4663b1343a4d5a9a964da53 x
|
||||
F configure.ac a100ebf7a07f5dedd319ef547dd467d1676ed059b85a7877aa9c44ac309f7000
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
|
||||
F doc/compile-for-windows.md e8635eea9153dcd6a51fd2740666ebc4492b3813cb1ac31cd8e99150df91762d
|
||||
@@ -53,8 +53,8 @@ F ext/README.md fd5f78013b0a2bc6f0067afb19e6ad040e89a10179b4f6f03eee58fac5f169bd
|
||||
F ext/async/README.txt e12275968f6fde133a80e04387d0e839b0c51f91
|
||||
F ext/async/sqlite3async.c 6f247666b495c477628dd19364d279c78ea48cd90c72d9f9b98ad1aff3294f94
|
||||
F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a
|
||||
F ext/consio/console_io.c b4885dfea71ed583315de8f0792a29d5fc7c7460b4a26c0aebe5cda5da8b38f8 x
|
||||
F ext/consio/console_io.h 0548b83d7c4b7270ad544a67f2bb90cebc519637fa39b1838df4744cf0d87646
|
||||
F ext/consio/console_io.c 6e02dea912a49f55785b0027fe77960aafee6c236307c23f82ec86a69f1a2001 x
|
||||
F ext/consio/console_io.h b5ebe34aa15b357621ebbea3d3f2e2b24750d4280b5802516409e23947fd9ee5
|
||||
F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3
|
||||
F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4
|
||||
F ext/expert/expert1.test 661f873fd451127edf822ef0d520088faa319135f6a15bd10be6801ac284ac9b
|
||||
@@ -91,18 +91,18 @@ F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
|
||||
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
|
||||
F ext/fts3/unicode/mkunicode.tcl 63db9624ccf70d4887836c320eda93ab552f21008f3be7ede551eac3ead62baa
|
||||
F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
|
||||
F ext/fts5/extract_api_docs.tcl 1db7f85f4d84b7b6f33336155d5053fafc3c8debd074422d8003c8f7fa4d0fdb
|
||||
F ext/fts5/fts5.h c65fc7799a4cd6774628da4fa9408955623e504d7369ab5b89c4413fdfe11eb5
|
||||
F ext/fts5/extract_api_docs.tcl 009cf59c77afa86d137b0cca3e3b1a5efbe2264faa2df233f9a7aa8563926d15
|
||||
F ext/fts5/fts5.h efaaac0df3d3bc740383044c144b582f47921aafa21d7b10eb98f42c24c740b0
|
||||
F ext/fts5/fts5Int.h 26a71a09cefa4ef6b4516b204ed48da3e1380970a19b3482eea7c5d805655360
|
||||
F ext/fts5/fts5_aux.c 12cd2512f869217c38b70c31de5b5f741812734fafa80f55b32ea9bbd96e2152
|
||||
F ext/fts5/fts5_aux.c 65a0468dd177d6093aa9ae1622e6d86b0136b8d267c62c0ad6493ad1e9a3d759
|
||||
F ext/fts5/fts5_buffer.c 0eec58bff585f1a44ea9147eae5da2447292080ea435957f7488c70673cb6f09
|
||||
F ext/fts5/fts5_config.c 353d2a0d12678cae6ab5b9ce54aed8dac0825667b69248b5a4ed81cbefc109ea
|
||||
F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33
|
||||
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
|
||||
F ext/fts5/fts5_index.c eb9a0dda3bc6ef969a6be8d2746af56856e67251810ddba08622b45be8477abe
|
||||
F ext/fts5/fts5_main.c 5ea7ab0c9967594e73b7dd0ad737595922a14f175aa4b486dc2992a3e3138b68
|
||||
F ext/fts5/fts5_main.c 0dbe241c50b62e24a229a176d66d580e359b3c32cb0970c39bb6dd6b86e125d5
|
||||
F ext/fts5/fts5_storage.c 9a9b880be12901f1962ae2a5a7e1b74348b3099a1e728764e419f75d98e3e612
|
||||
F ext/fts5/fts5_tcl.c 1dcf08028141c40a32634bdcf2d5601622ce4edc48f82ac4ce0cbe0a92a6961d
|
||||
F ext/fts5/fts5_tcl.c 4db9258a7882c5eac0da4433042132aaf15b87dd1e1636c7a6ca203abd2c8bfe
|
||||
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
|
||||
F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b
|
||||
F ext/fts5/fts5_tokenize.c ae9c4fa93174ef06ffc138bd4280a1c37f7e13624d3d2706aad4b80573f23c41
|
||||
@@ -153,6 +153,7 @@ F ext/fts5/test/fts5corrupt4.test dc08d19f5b8943e95a7778a7d8da592042504faf18dd93
|
||||
F ext/fts5/test/fts5corrupt5.test 11b47126f5772cc37b67e3e8b2ed05895c4d07c05338bc07e4eea225bfe32c76
|
||||
F ext/fts5/test/fts5corrupt6.test 2d72db743db7b5d9c9a6d0cfef24d799ed1aa5e8192b66c40e871a37ed9eed06
|
||||
F ext/fts5/test/fts5corrupt7.test 4e830875c33b9ea3c4cf1ba71e692b63893cbb4faae8c69b1071889dc26e211c
|
||||
F ext/fts5/test/fts5corrupt8.test f78b6de9e4327e16ba7a7958b1ce576f9b5d886b4b97690f90b7f3cf654da458
|
||||
F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7
|
||||
F ext/fts5/test/fts5detail.test 54015e9c43ec4ba542cfb93268abdf280e0300f350efd08ee411284b03595cc4
|
||||
F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11
|
||||
@@ -177,7 +178,7 @@ F ext/fts5/test/fts5faultE.test 844586ce71dab4be85bb86880e87b624d089f851654cd22e
|
||||
F ext/fts5/test/fts5faultF.test 4abef99f86e99d9f0c6460dd68c586a766b6b9f1f660ada55bf2e8266bd1bbc1
|
||||
F ext/fts5/test/fts5faultG.test 0544411ffcb3e19b42866f757a8a5e0fb8fef3a62c06f61d14deebc571bb7ea9
|
||||
F ext/fts5/test/fts5faultH.test 2b2b5b8cb1b3fd7679f488c06e22af44107fbc6137eaf45b3e771dc7b149312d
|
||||
F ext/fts5/test/fts5faultI.test fbc65a64944fb747f6d3fb30628a807d5cce1bca43c11df40e7770ad7a7ed593
|
||||
F ext/fts5/test/fts5faultI.test e1e8a927122a8c3be8614a59717e838cad0505ba0a6f404983da8430e7aeb14d
|
||||
F ext/fts5/test/fts5first.test bfd685b96905bf541d99d8644e0a7219d1d833455a08ab64e344071a613b6ba9
|
||||
F ext/fts5/test/fts5full.test 97d263c1072f4a560929cca31e70f65d2ae232610e17e6affcf7e979df59547b
|
||||
F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e
|
||||
@@ -187,7 +188,7 @@ F ext/fts5/test/fts5interrupt.test 20d04204d3e341b104c0c24a41596b6393a3a81eba104
|
||||
F ext/fts5/test/fts5lastrowid.test f36298a1fb9f988bde060a274a7ce638faa9c38a31400f8d2d27ea9373e0c4a1
|
||||
F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad
|
||||
F ext/fts5/test/fts5limits.test 8ab67cf5d311c124b6ceb0062d0297767176df4572d955fce79fa43004dff01c
|
||||
F ext/fts5/test/fts5locale.test 79cbd3000ae269de50826f6061c81f7c9fdb21dd9954c0b7f9485263482c539d
|
||||
F ext/fts5/test/fts5locale.test 797cf6f5e017462ab11313ce884b9f1df8ff063811e74ef42190cd19ed6b600b
|
||||
F ext/fts5/test/fts5matchinfo.test 877520582feb86bbfd95ab780099bcba4526f18ac75ee34979144cf86ba3a5a3
|
||||
F ext/fts5/test/fts5merge.test 2654df0bcdb2d117c2d38b6aeb0168061be01c643f9e9194b36c43a2970e8082
|
||||
F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2
|
||||
@@ -417,7 +418,7 @@ F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab840709636240
|
||||
F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
|
||||
F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
|
||||
F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946
|
||||
F ext/misc/series.c d96e5aac21658c6b5d54f918ac140460ec7197734c1a4fba806950831a7b1e7a
|
||||
F ext/misc/series.c a6089b5e8e3002bd1e5d9877cee6aead0b9a6426e406c09a399817db9e9ae823
|
||||
F ext/misc/sha1.c 4011aef176616872b2a0d5bccf0ecfb1f7ce3fe5c3d107f3a8e949d8e1e3f08d
|
||||
F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c
|
||||
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
|
||||
@@ -712,7 +713,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 64e4b1227b4ed123146f0aa2989131d1fbd9b927b11e80c9d58c6a68f9cd5ce3
|
||||
F src/date.c 89ce1ff20512a7fa5070ba6e7dd5c171148ca7d580955795bf97c79c2456144a
|
||||
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
|
||||
F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
|
||||
F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
|
||||
F src/delete.c 444c4d1eaac40103461e3b6f0881846dd3aafc1cec1dd169d3482fa331667da7
|
||||
F src/expr.c 6d5f2c38fe3ec06a7eac599dac822788b36064124e20112a844e9cd5156cb239
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
@@ -762,11 +763,11 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7
|
||||
F src/prepare.c d99931f45416652895e502328ca49fe782cfc4e1ebdcda13b3736d991ebf42ce
|
||||
F src/printf.c 6a87534ebfb9e5346011191b1f3a7ebc457f5938c7e4feeea478ecf53f6a41b2
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c 9afed5fd7b9111633bdb74a73cdc47324e28e4dc6c27113e3e9aee38fb9422ab
|
||||
F src/resolve.c 2c127880c0634962837f16f2f48a295e514357af959330cc038de73015d5b5e8
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
|
||||
F src/shell.c.in 9a45cd618ed3cd09927e04bb0ccfd929fb5efa03a7166daec4645d230b7267f3
|
||||
F src/sqlite.h.in c6512f60f9fe06de46e49161e3f8fca72f3875f67dad8eaf469622567f434e48
|
||||
F src/shell.c.in 40de636c1d90fb8a9ca7f49dc8f50d930f1b60736e73aca5eb37c4c7d0e47f9d
|
||||
F src/sqlite.h.in f07bff4225a1244efd604a0ffef81ed69f29d3dbaed7e22f906f26229ba3ca9e
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||
F src/sqliteInt.h 28c878bdf528879afefe1994ac007d094f8061f2fdacdc55d6055d7e9341151e
|
||||
@@ -834,7 +835,7 @@ F src/update.c 0e01aa6a3edf9ec112b33eb714b9016a81241497b1fb7c3e74332f4f71756508
|
||||
F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
|
||||
F src/utf.c f23165685a67b4caf8ec08fb274cb3f319103decfb2a980b7cfd55d18dfa855e
|
||||
F src/util.c 5d1a0134cf4240648d1c6bb5cc8efaca0ea2b5d5c840985aec7e947271f04375
|
||||
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
||||
F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40
|
||||
F src/vdbe.c be5f58bc29f60252e041a618eae59e8d57d460ba136c5403cf0abf955560c457
|
||||
F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a
|
||||
F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c
|
||||
@@ -850,9 +851,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||
F src/wal.c 887fc4ca3f020ebb2e376f222069570834ac63bf50111ef0cbf3ae417048ed89
|
||||
F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452
|
||||
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
|
||||
F src/where.c 61fea6c34c9c2350b114a4f64dce51ec073c2d8c50ca0734a0882ba6ab531805
|
||||
F src/whereInt.h 6444b888ce395cb80511284b8a73b63472d34247fcb1b125ee06a54fa6ae878e
|
||||
F src/wherecode.c 137797b0de9ddf1ff43e5b0edffcc76fb05184ed651fc4f5a0a01a45c0b89d04
|
||||
F src/where.c c046dd58c3410f7b7528e1e6317cb876398557bad346d568ed8562321a7d002d
|
||||
F src/whereInt.h a5d079c346a658b7a6e9e47bb943d021e02fa1e6aed3b964ca112112a4892192
|
||||
F src/wherecode.c 5172d647798134e7c92536ddffe7e530c393d79b5dedd648b88faf2646c65baf
|
||||
F src/whereexpr.c 44f41ae554c7572e1de1485b3169b233ee04d464b2ee5881687ede3bf07cacfa
|
||||
F src/window.c 499d48f315a09242dc68f2fac635ed27dcf6bbb0d9ab9084857898c64489e975
|
||||
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
|
||||
@@ -1441,7 +1442,7 @@ F test/memjournal2.test dbc2c5cb5f7b38950f4f6dc3e73fcecf0fcbed3fc32c7ce913bba164
|
||||
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
|
||||
F test/memsubsys1.test 86b8158752af9188ed5b32a30674a1ef71183e6bc4e6808e815cd658ca9058a6
|
||||
F test/memsubsys2.test 774b93cb09ca50d1b759bb7c645baa2a9ce172edc3a3da67d5150a26a9fc2a08
|
||||
F test/merge1.test 2de6d6ef8d25402764b1aab49d8f9d7f89208c89a6674e437f76de4c812157b8
|
||||
F test/merge1.test 7dd9dc6838bcd0623a069485fe3a8dd498a051c16e1877cf84f506c0d6a29b43
|
||||
F test/minmax.test fe638b55d77d2375531a8f549b338eafcd9adfbd2f72df37ed77d9b26ca0a71a
|
||||
F test/minmax2.test cf9311babb6f0518d04e42fd6a42c619531c4309a9dd790a2c4e9b3bc595e0de
|
||||
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
|
||||
@@ -1700,7 +1701,7 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309
|
||||
F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039
|
||||
F test/syscall.test a067468b43b8cb2305e9f9fe414e5f40c875bb5d2cba5f00b8154396e95fcf37
|
||||
F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04
|
||||
F test/tabfunc01.test f150d206294471d20f50029e6b46b76b87a7a010b16dc57eb44245c76dd02802
|
||||
F test/tabfunc01.test 6002a5f37b76355f173c75c2b3b03173b19d6a8b078c5baaa4c78bbcd0fa6323
|
||||
F test/table.test 7862a00b58b5541511a26757ea9c5c7c3f8298766e98aa099deec703d9c0a8e0
|
||||
F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4
|
||||
F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930
|
||||
@@ -1712,9 +1713,9 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30
|
||||
F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d1631311a16
|
||||
F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637
|
||||
F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc
|
||||
F test/tester.tcl e88c498c369cff6bf0898db6d04088685066730be51821ef775ef13fd2b1d077
|
||||
F test/testrunner.tcl 5d02deeba7a53baeadae6aa7641d90aac58fdfa3a7bcac85cfcfd752b1aab87c
|
||||
F test/testrunner_data.tcl c5ae2b1f9a99210b0600d002fb3af1fee350997cee9416551e83b93501360ebf
|
||||
F test/tester.tcl 2c203a2dd664298f239f0ec3ce22fbc65b5f021c1e09edbae8452af8a694e052
|
||||
F test/testrunner.tcl c27905c57f54450411be922037d227fee65b08928d09715d784380a398b0e758
|
||||
F test/testrunner_data.tcl 6a0facfbff26f2f8573ebaeb209426bbb59809d5c0f6925f983bd030ab5248cd
|
||||
F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899
|
||||
F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502
|
||||
F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7
|
||||
@@ -2069,7 +2070,7 @@ F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af
|
||||
F test/windowB.test aad7c31739999f68a98a813cfd78390918fc70f56d2d925317a1523cab548ecf
|
||||
F test/windowC.test 6fd75f5bb2f1343d34e470e36e68f0ff638d8a42f6aa7d99471261b31a0d42f2
|
||||
F test/windowD.test 65cf5a765fb8072450e8a0de2979ce7f09a38d87724fe1280c6444073e3da49b
|
||||
F test/windowE.test 6ba0c8048e4cc02b942e56640f8fcd50fd7ca72c876656c40f6baf42e316684c
|
||||
F test/windowE.test c98507e0b0d95980ad25845db758557757be2d7054198ccf522c7d277057a3df
|
||||
F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0
|
||||
F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b
|
||||
F test/windowfault.test 15094c1529424e62f798bc679e3fe9dfab6e8ba2f7dfe8c923b6248c31660a7c
|
||||
@@ -2210,11 +2211,8 @@ F vsixtest/vsixtest.tcl 6195aba1f12a5e10efc2b8c0009532167be5e301abe5b31385638080
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 6b024c85ef856e26cddac8ad862e16909b5149c3e3efb4e73ba54c97291f1cc4
|
||||
R 5688f40bf117ffce0b629c4446a727b9
|
||||
T *branch * optimization-onoff
|
||||
T *sym-optimization-onoff *
|
||||
T -sym-trunk *
|
||||
P 7c195f132cb48ee44124eb4af3532937493429f7c45f6ac611f7a9b128799ad7
|
||||
R 15868716c90b102057036239341d8066
|
||||
U drh
|
||||
Z b26803088924fd26f08434065f39c8bf
|
||||
Z fde036223228b7af985cf94952c295a1
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
0ea4e1e8fc689cb1af3a8d21dd6af9d483115412b414e85e8a42480f50d65af2
|
||||
2eaea67495fd9961b7145d829789889bf1d8fa7a834d40d1be43e7c74c233bc2
|
||||
|
||||
@@ -279,6 +279,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
|
||||
pIdxInfo->orderByConsumed = 1;
|
||||
pIdxInfo->idxNum |= 0x08;
|
||||
}
|
||||
pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_HEX;
|
||||
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1300,9 +1300,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||||
sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList);
|
||||
}
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( pWin ){
|
||||
if( pWin && pParse->nErr==0 ){
|
||||
Select *pSel = pNC->pWinSelect;
|
||||
assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) );
|
||||
assert( ExprUseYWin(pExpr) && pWin==pExpr->y.pWin );
|
||||
if( IN_RENAME_OBJECT==0 ){
|
||||
sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
|
||||
if( pParse->db->mallocFailed ) break;
|
||||
|
||||
+22
-10
@@ -246,6 +246,7 @@ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
|
||||
# define SQLITE_CIO_NO_CLASSIFY
|
||||
# define SQLITE_CIO_NO_TRANSLATE
|
||||
# define SQLITE_CIO_NO_SETMODE
|
||||
# define SQLITE_CIO_NO_FLUSH
|
||||
#endif
|
||||
INCLUDE ../ext/consio/console_io.h
|
||||
INCLUDE ../ext/consio/console_io.c
|
||||
@@ -279,11 +280,12 @@ INCLUDE ../ext/consio/console_io.c
|
||||
# define eputz(z) ePutsUtf8(z)
|
||||
# define eputf ePrintfUtf8
|
||||
# define oputb(buf,na) oPutbUtf8(buf,na)
|
||||
# define fflush(s) fFlushBuffer(s);
|
||||
|
||||
#else
|
||||
/* For Fiddle, all console handling and emit redirection is omitted. */
|
||||
/* These next 3 macros are for emitting formatted output. When complaints
|
||||
* from the WASM build are issued for non-formatted output, (when a mere
|
||||
* from the WASM build are issued for non-formatted output, when a mere
|
||||
* string literal is to be emitted, the ?putz(z) forms should be used.
|
||||
* (This permits compile-time checking of format string / argument mismatch.)
|
||||
*/
|
||||
@@ -295,6 +297,7 @@ INCLUDE ../ext/consio/console_io.c
|
||||
# define eputz(z) fputs(z,stderr)
|
||||
# define sputz(fp,z) fputs(z,fp)
|
||||
# define oputb(buf,na) fwrite(buf,1,na,stdout)
|
||||
# undef fflush
|
||||
#endif
|
||||
|
||||
/* True if the timer is enabled */
|
||||
@@ -534,6 +537,14 @@ static char *shell_strncpy(char *dest, const char *src, size_t n){
|
||||
return dest;
|
||||
}
|
||||
|
||||
/*
|
||||
** strcpy() workalike to squelch an unwarranted link-time warning
|
||||
** from OpenBSD.
|
||||
*/
|
||||
static void shell_strcpy(char *dest, const char *src){
|
||||
while( (*(dest++) = *(src++))!=0 ){}
|
||||
}
|
||||
|
||||
/*
|
||||
** Optionally disable dynamic continuation prompt.
|
||||
** Unless disabled, the continuation prompt shows open SQL lexemes if any,
|
||||
@@ -599,7 +610,7 @@ static char *dynamicContinuePrompt(void){
|
||||
size_t ncp = strlen(continuePrompt);
|
||||
size_t ndp = strlen(dynPrompt.zScannerAwaits);
|
||||
if( ndp > ncp-3 ) return continuePrompt;
|
||||
strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits);
|
||||
shell_strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits);
|
||||
while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' ';
|
||||
shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3,
|
||||
PROMPT_LEN_MAX-4);
|
||||
@@ -3548,10 +3559,11 @@ static void bind_prepared_stmt(ShellState *pArg, sqlite3_stmt *pStmt){
|
||||
}else if( strncmp(zVar, "$int_", 5)==0 ){
|
||||
sqlite3_bind_int(pStmt, i, atoi(&zVar[5]));
|
||||
}else if( strncmp(zVar, "$text_", 6)==0 ){
|
||||
char *zBuf = sqlite3_malloc64( strlen(zVar)-5 );
|
||||
size_t szVar = strlen(zVar);
|
||||
char *zBuf = sqlite3_malloc64( szVar-5 );
|
||||
if( zBuf ){
|
||||
memcpy(zBuf, &zVar[6], strlen(zVar)-5);
|
||||
sqlite3_bind_text64(pStmt, i, zBuf, -1, sqlite3_free, SQLITE_UTF8);
|
||||
memcpy(zBuf, &zVar[6], szVar-5);
|
||||
sqlite3_bind_text64(pStmt, i, zBuf, szVar-6, sqlite3_free, SQLITE_UTF8);
|
||||
}
|
||||
}else{
|
||||
sqlite3_bind_null(pStmt, i);
|
||||
@@ -11044,7 +11056,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
for(ii=2; ii<nArg; ii++){
|
||||
const char *z = azArg[ii];
|
||||
int useLabel = 0;
|
||||
const char *zLabel;
|
||||
const char *zLabel = 0;
|
||||
if( (z[0]=='+'|| z[0]=='-') && !IsDigit(z[1]) ){
|
||||
useLabel = z[0];
|
||||
zLabel = &z[1];
|
||||
@@ -11061,11 +11073,11 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
if( jj>=ArraySize(aLabel) ){
|
||||
eputf("Error: no such optimization: \"%s\"\n", zLabel);
|
||||
eputf("Should be one of:");
|
||||
eputz("Should be one of:");
|
||||
for(jj=0; jj<ArraySize(aLabel); jj++){
|
||||
eputf(" %s", aLabel[jj].zLabel);
|
||||
}
|
||||
eputf("\n");
|
||||
eputz("\n");
|
||||
rc = 1;
|
||||
goto meta_command_exit;
|
||||
}
|
||||
@@ -11082,9 +11094,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
curOpt = ~newOpt;
|
||||
}
|
||||
if( newOpt==0 ){
|
||||
oputf("+All\n");
|
||||
oputz("+All\n");
|
||||
}else if( newOpt==0xffffffff ){
|
||||
oputf("-All\n");
|
||||
oputz("-All\n");
|
||||
}else{
|
||||
int jj;
|
||||
for(jj=0; jj<ArraySize(aLabel); jj++){
|
||||
|
||||
+8
-4
@@ -7427,9 +7427,11 @@ struct sqlite3_module {
|
||||
** will be returned by the strategy.
|
||||
**
|
||||
** The xBestIndex method may optionally populate the idxFlags field with a
|
||||
** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
|
||||
** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
|
||||
** assumes that the strategy may visit at most one row.
|
||||
** mask of SQLITE_INDEX_SCAN_* flags. One such flag is
|
||||
** [SQLITE_INDEX_SCAN_HEX], which if set causes the [EXPLAIN QUERY PLAN]
|
||||
** output to show the idxNum has hex instead of as decimal. Another flag is
|
||||
** SQLITE_INDEX_SCAN_UNIQUE, which if set indicates that the query plan will
|
||||
** return at most one row.
|
||||
**
|
||||
** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
|
||||
** SQLite also assumes that if a call to the xUpdate() method is made as
|
||||
@@ -7493,7 +7495,9 @@ struct sqlite3_index_info {
|
||||
** [sqlite3_index_info].idxFlags field to some combination of
|
||||
** these bits.
|
||||
*/
|
||||
#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
|
||||
#define SQLITE_INDEX_SCAN_UNIQUE 0x00000001 /* Scan visits at most 1 row */
|
||||
#define SQLITE_INDEX_SCAN_HEX 0x00000002 /* Display idxNum as hex */
|
||||
/* in EXPLAIN QUERY PLAN */
|
||||
|
||||
/*
|
||||
** CAPI3REF: Virtual Table Constraint Operator Codes
|
||||
|
||||
+14
-9
@@ -162,6 +162,9 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
const char *zDbMain; /* Schema name of database to vacuum */
|
||||
const char *zOut; /* Name of output file */
|
||||
u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */
|
||||
u64 iRandom; /* Random value used for zDbVacuum[] */
|
||||
char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */
|
||||
|
||||
|
||||
if( !db->autoCommit ){
|
||||
sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
|
||||
@@ -202,27 +205,29 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
pMain = db->aDb[iDb].pBt;
|
||||
isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));
|
||||
|
||||
/* Attach the temporary database as 'vacuum_db'. The synchronous pragma
|
||||
/* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma
|
||||
** can be set to 'off' for this file, as it is not recovered if a crash
|
||||
** occurs anyway. The integrity of the database is maintained by a
|
||||
** (possibly synchronous) transaction opened on the main database before
|
||||
** sqlite3BtreeCopyFile() is called.
|
||||
**
|
||||
** An optimization would be to use a non-journaled pager.
|
||||
** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but
|
||||
** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but
|
||||
** that actually made the VACUUM run slower. Very little journalling
|
||||
** actually occurs when doing a vacuum since the vacuum_db is initially
|
||||
** empty. Only the journal header is written. Apparently it takes more
|
||||
** time to parse and run the PRAGMA to turn journalling off than it does
|
||||
** to write the journal header file.
|
||||
*/
|
||||
sqlite3_randomness(sizeof(iRandom),&iRandom);
|
||||
sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom);
|
||||
nDb = db->nDb;
|
||||
rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut);
|
||||
rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum);
|
||||
db->openFlags = saved_openFlags;
|
||||
if( rc!=SQLITE_OK ) goto end_of_vacuum;
|
||||
assert( (db->nDb-1)==nDb );
|
||||
pDb = &db->aDb[nDb];
|
||||
assert( strcmp(pDb->zDbSName,"vacuum_db")==0 );
|
||||
assert( strcmp(pDb->zDbSName,zDbVacuum)==0 );
|
||||
pTemp = pDb->pBt;
|
||||
if( pOut ){
|
||||
sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
|
||||
@@ -299,11 +304,11 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
** the contents to the temporary database.
|
||||
*/
|
||||
rc = execSqlF(db, pzErrMsg,
|
||||
"SELECT'INSERT INTO vacuum_db.'||quote(name)"
|
||||
"SELECT'INSERT INTO %s.'||quote(name)"
|
||||
"||' SELECT*FROM\"%w\".'||quote(name)"
|
||||
"FROM vacuum_db.sqlite_schema "
|
||||
"FROM %s.sqlite_schema "
|
||||
"WHERE type='table'AND coalesce(rootpage,1)>0",
|
||||
zDbMain
|
||||
zDbVacuum, zDbMain, zDbVacuum
|
||||
);
|
||||
assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 );
|
||||
db->mDbFlags &= ~DBFLAG_Vacuum;
|
||||
@@ -315,11 +320,11 @@ SQLITE_NOINLINE int sqlite3RunVacuum(
|
||||
** from the schema table.
|
||||
*/
|
||||
rc = execSqlF(db, pzErrMsg,
|
||||
"INSERT INTO vacuum_db.sqlite_schema"
|
||||
"INSERT INTO %s.sqlite_schema"
|
||||
" SELECT*FROM \"%w\".sqlite_schema"
|
||||
" WHERE type IN('view','trigger')"
|
||||
" OR(type='table'AND rootpage=0)",
|
||||
zDbMain
|
||||
zDbVacuum, zDbMain
|
||||
);
|
||||
if( rc ) goto end_of_vacuum;
|
||||
|
||||
|
||||
@@ -3987,6 +3987,7 @@ static int whereLoopAddBtree(
|
||||
pNew->prereq = mPrereq;
|
||||
pNew->nOut = rSize;
|
||||
pNew->u.btree.pIndex = pProbe;
|
||||
pNew->u.btree.pOrderBy = 0;
|
||||
b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
|
||||
|
||||
/* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
|
||||
@@ -4349,6 +4350,7 @@ static int whereLoopAddVirtualOne(
|
||||
pNew->u.vtab.idxStr = pIdxInfo->idxStr;
|
||||
pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
|
||||
pIdxInfo->nOrderBy : 0);
|
||||
pNew->u.vtab.bIdxNumHex = (pIdxInfo->idxFlags&SQLITE_INDEX_SCAN_HEX)!=0;
|
||||
pNew->rSetup = 0;
|
||||
pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
|
||||
pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
|
||||
|
||||
@@ -149,6 +149,7 @@ struct WhereLoop {
|
||||
int idxNum; /* Index number */
|
||||
u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */
|
||||
u32 bOmitOffset : 1; /* True to let virtual table handle offset */
|
||||
u32 bIdxNumHex : 1; /* Show idxNum as hex in EXPLAIN QUERY PLAN */
|
||||
i8 isOrdered; /* True if satisfies ORDER BY */
|
||||
u16 omitMask; /* Terms that may be omitted */
|
||||
char *idxStr; /* Index identifier string */
|
||||
|
||||
+3
-1
@@ -200,7 +200,9 @@ int sqlite3WhereExplainOneScan(
|
||||
}
|
||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
|
||||
sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
|
||||
sqlite3_str_appendall(&str, " VIRTUAL TABLE INDEX ");
|
||||
sqlite3_str_appendf(&str,
|
||||
pLoop->u.vtab.bIdxNumHex ? "0x%x:%s" : "%d:%s",
|
||||
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
|
||||
}
|
||||
#endif
|
||||
|
||||
+12
-12
@@ -64,21 +64,21 @@ do_eqp_test 101 {
|
||||
| |--LEFT
|
||||
| | `--MERGE (UNION ALL)
|
||||
| | |--LEFT
|
||||
| | | `--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
| | | `--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
| | `--RIGHT
|
||||
| | `--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
| | `--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
| `--RIGHT
|
||||
| `--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
| `--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
`--RIGHT
|
||||
`--MERGE (UNION ALL)
|
||||
|--LEFT
|
||||
| `--MERGE (UNION ALL)
|
||||
| |--LEFT
|
||||
| | `--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
| | `--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
| `--RIGHT
|
||||
| `--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
| `--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
`--RIGHT
|
||||
`--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
`--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
}
|
||||
|
||||
# Same test with the blanced-merge optimization
|
||||
@@ -129,17 +129,17 @@ do_eqp_test 111 {
|
||||
| | | |--LEFT
|
||||
| | | | `--MERGE (UNION ALL)
|
||||
| | | | |--LEFT
|
||||
| | | | | `--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
| | | | | `--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
| | | | `--RIGHT
|
||||
| | | | `--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
| | | | `--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
| | | `--RIGHT
|
||||
| | | `--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
| | | `--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
| | `--RIGHT
|
||||
| | `--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
| | `--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
| `--RIGHT
|
||||
| `--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
| `--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
`--RIGHT
|
||||
`--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
`--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+6
-6
@@ -121,26 +121,26 @@ do_eqp_test tabfunc01-3.10 {
|
||||
SELECT value FROM generate_series(1,10) ORDER BY value;
|
||||
} {
|
||||
QUERY PLAN
|
||||
`--SCAN generate_series VIRTUAL TABLE INDEX 19:
|
||||
`--SCAN generate_series VIRTUAL TABLE INDEX 0x13:
|
||||
}
|
||||
do_eqp_test tabfunc01-3.11 {
|
||||
SELECT value FROM generate_series(1,10) ORDER BY +value;
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SCAN generate_series VIRTUAL TABLE INDEX 3:
|
||||
|--SCAN generate_series VIRTUAL TABLE INDEX 0x3:
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
do_eqp_test tabfunc01-3.12 {
|
||||
SELECT value FROM generate_series(1,10) ORDER BY value, stop;
|
||||
} {
|
||||
QUERY PLAN
|
||||
`--SCAN generate_series VIRTUAL TABLE INDEX 19:
|
||||
`--SCAN generate_series VIRTUAL TABLE INDEX 0x13:
|
||||
}
|
||||
do_eqp_test tabfunc01-3.13 {
|
||||
SELECT value FROM generate_series(1,10) ORDER BY stop, value;
|
||||
} {
|
||||
QUERY PLAN
|
||||
|--SCAN generate_series VIRTUAL TABLE INDEX 3:
|
||||
|--SCAN generate_series VIRTUAL TABLE INDEX 0x3:
|
||||
`--USE TEMP B-TREE FOR ORDER BY
|
||||
}
|
||||
|
||||
@@ -156,9 +156,9 @@ do_eqp_test tabfunc01-3.20 {
|
||||
QUERY PLAN
|
||||
`--MERGE (UNION ALL)
|
||||
|--LEFT
|
||||
| `--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
| `--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
`--RIGHT
|
||||
`--SCAN generate_series VIRTUAL TABLE INDEX 23:
|
||||
`--SCAN generate_series VIRTUAL TABLE INDEX 0x17:
|
||||
}
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -985,7 +985,7 @@ proc query_plan_graph {sql} {
|
||||
}
|
||||
set a "\n QUERY PLAN\n"
|
||||
append a [append_graph " " dx cx 0]
|
||||
regsub -all { 0x[A-F0-9]+\y} $a { xxxxxx} a
|
||||
regsub -all {SUBQUERY 0x[A-F0-9]+\y} $a {SUBQUERY xxxxxx} a
|
||||
regsub -all {(MATERIALIZE|CO-ROUTINE|SUBQUERY) \d+\y} $a {\1 xxxxxx} a
|
||||
regsub -all {\((join|subquery)-\d+\)} $a {(\1-xxxxxx)} a
|
||||
return $a
|
||||
|
||||
+78
-31
@@ -89,7 +89,9 @@ Other PERMUTATION arguments must be run using testfixture, not tclsh:
|
||||
If no PATTERN arguments are present, all tests specified by the PERMUTATION
|
||||
are run. Otherwise, each pattern is interpreted as a glob pattern. Only
|
||||
those tcl tests for which the final component of the filename matches at
|
||||
least one specified pattern are run.
|
||||
least one specified pattern are run. The glob wildcard '*' is prepended
|
||||
to the pattern if it does not start with '^' and appended to every
|
||||
pattern that does not end with '$'.
|
||||
|
||||
If no PATTERN arguments are present, then various fuzztest, threadtest
|
||||
and other tests are run as part of the "release" permutation. These are
|
||||
@@ -277,10 +279,12 @@ set TRG(schema) {
|
||||
priority INTEGER NOT NULL, -- higher priority jobs may run earlier
|
||||
|
||||
/* Fields updated as jobs run */
|
||||
starttime INTEGER,
|
||||
endtime INTEGER,
|
||||
starttime INTEGER, -- Start time (milliseconds since 1970)
|
||||
endtime INTEGER, -- End time
|
||||
state TEXT CHECK( state IN ('','ready','running','done','failed','omit') ),
|
||||
output TEXT
|
||||
ntest INT, -- Number of test cases run
|
||||
nerr INT, -- Number of errors reported
|
||||
output TEXT -- test output
|
||||
);
|
||||
|
||||
CREATE TABLE config(
|
||||
@@ -389,14 +393,36 @@ if {[string compare -nocase script [lindex $argv 0]]==0} {
|
||||
exit
|
||||
}
|
||||
|
||||
# Compute an elapse time string MM:SS or HH:MM:SS based on the
|
||||
# number of milliseconds in the argument.
|
||||
#
|
||||
proc elapsetime {ms} {
|
||||
set s [expr {int(($ms+500.0)*0.001)}]
|
||||
set hr [expr {$s/3600}]
|
||||
set mn [expr {($s/60)%60}]
|
||||
set sc [expr {$s%60}]
|
||||
if {$hr>0} {
|
||||
return [format %02d:%02d:%02d $hr $mn $sc]
|
||||
} else {
|
||||
return [format %02d:%02d $mn $sc]
|
||||
}
|
||||
}
|
||||
|
||||
# Helper routine for show_status
|
||||
#
|
||||
proc display_job {jobdict {tm ""}} {
|
||||
array set job $jobdict
|
||||
set dfname [format %-60s $job(displayname)]
|
||||
if {[string length $job(displayname)]>65} {
|
||||
set dfname [format %.65s... $job(displayname)]
|
||||
} else {
|
||||
set dfname [format %-68s $job(displayname)]
|
||||
}
|
||||
set dtm ""
|
||||
if {$tm!=""} {
|
||||
set dtm [format %-10s "\[[expr {$tm-$job(starttime)}]ms\]"]
|
||||
set dtm [expr {$tm-$job(starttime)}]
|
||||
set dtm [format %8s [elapsetime $dtm]]
|
||||
} else {
|
||||
set dtm [format %8s ""]
|
||||
}
|
||||
puts " $dfname $dtm"
|
||||
}
|
||||
@@ -431,6 +457,11 @@ proc show_status {db cls} {
|
||||
incr S($state) $cnt
|
||||
incr total $cnt
|
||||
}
|
||||
set nt 0
|
||||
set ne 0
|
||||
$db eval {
|
||||
SELECT sum(ntest) AS nt, sum(nerr) AS ne FROM jobs HAVING nt>0
|
||||
} break
|
||||
set fin [expr $S(done)+$S(failed)]
|
||||
if {$cmdline!=""} {set cmdline " $cmdline"}
|
||||
|
||||
@@ -443,14 +474,10 @@ proc show_status {db cls} {
|
||||
} else {
|
||||
set clreol ""
|
||||
}
|
||||
set f ""
|
||||
if {$S(failed)>0} {
|
||||
set f "$S(failed) FAILED, "
|
||||
}
|
||||
puts "Command line: \[testrunner.tcl$cmdline\]$clreol"
|
||||
puts "Jobs: $nJob "
|
||||
puts "Summary: ${tm}ms, ($fin/$total) finished,\
|
||||
${f}$S(running) running "
|
||||
puts [format %-79.79s "Command: \[testrunner.tcl$cmdline\]$clreol"]
|
||||
puts [format %-79.79s "Cores: $nJob max $S(running) active"]
|
||||
puts [format %-79.79s "Summary: [elapsetime $tm], $fin/$total tasks,\
|
||||
$ne errors, $nt tests"]
|
||||
|
||||
set srcdir [file dirname [file dirname $TRG(info_script)]]
|
||||
if {$S(running)>0} {
|
||||
@@ -470,7 +497,7 @@ proc show_status {db cls} {
|
||||
}
|
||||
set nOmit [$db one {SELECT count(*) FROM jobs WHERE state='omit'}]
|
||||
if {$nOmit} {
|
||||
puts "$nOmit jobs omitted due to failures$clreol"
|
||||
puts [format %-79s "$nOmit jobs omitted due to failures$clreol"]
|
||||
}
|
||||
}
|
||||
if {$cls} {
|
||||
@@ -842,6 +869,17 @@ proc add_tcl_jobs {build config patternlist {shelldepid ""}} {
|
||||
if {[llength $patternlist]>0} {
|
||||
set bMatch 0
|
||||
foreach p $patternlist {
|
||||
set p [string trim $p *]
|
||||
if {[string index $p 0]=="^"} {
|
||||
set p [string range $p 1 end]
|
||||
} else {
|
||||
set p "*$p"
|
||||
}
|
||||
if {[string index $p end]=="\$"} {
|
||||
set p [string range $p 0 end-1]
|
||||
} else {
|
||||
set p "$p*"
|
||||
}
|
||||
if {[string match $p [file tail $f]]} {
|
||||
set bMatch 1
|
||||
break
|
||||
@@ -1062,25 +1100,13 @@ proc add_jobs_from_cmdline {patternlist} {
|
||||
}
|
||||
|
||||
release {
|
||||
set patternlist [lrange $patternlist 1 end]
|
||||
set config_set {}
|
||||
foreach b [trd_builds $TRG(platform)] {
|
||||
if {$TRG(config)!="" && ![regexp "\\y$b\\y" $TRG(config)]} continue
|
||||
if {[regexp "\\y$b\\y" $TRG(omitconfig)]} continue
|
||||
set bld [add_build_job $b $TRG(testfixture)]
|
||||
foreach c [trd_configs $TRG(platform) $b] {
|
||||
add_tcl_jobs $bld $c $patternlist
|
||||
}
|
||||
|
||||
if {$patternlist==""} {
|
||||
foreach e [trd_extras $TRG(platform) $b] {
|
||||
if {$e=="fuzztest"} {
|
||||
add_fuzztest_jobs $b
|
||||
} else {
|
||||
add_make_job $bld $e
|
||||
}
|
||||
}
|
||||
}
|
||||
lappend config_set $b
|
||||
}
|
||||
add_devtest_jobs $config_set [lrange $patternlist 1 end]
|
||||
}
|
||||
|
||||
list {
|
||||
@@ -1120,15 +1146,25 @@ proc make_new_testset {} {
|
||||
}
|
||||
|
||||
proc mark_job_as_finished {jobid output state endtm} {
|
||||
set ntest 1
|
||||
set nerr 0
|
||||
if {$endtm>0} {
|
||||
if {[regexp {\y(\d+) errors out of (\d+) tests} $output all a b]} {
|
||||
set nerr $a
|
||||
set ntest $b
|
||||
}
|
||||
}
|
||||
r_write_db {
|
||||
if {$state=="failed"} {
|
||||
set childstate omit
|
||||
if {$nerr<=0} {set nerr 1}
|
||||
} else {
|
||||
set childstate ready
|
||||
}
|
||||
trdb eval {
|
||||
UPDATE jobs
|
||||
SET output=$output, state=$state, endtime=$endtm
|
||||
SET output=$output, state=$state, endtime=$endtm,
|
||||
ntest=$ntest, nerr=$nerr
|
||||
WHERE jobid=$jobid;
|
||||
UPDATE jobs SET state=$childstate WHERE depid=$jobid;
|
||||
}
|
||||
@@ -1371,6 +1407,17 @@ proc run_testset {} {
|
||||
|
||||
puts "\nTest database is $TRG(dbname)"
|
||||
puts "Test log is $TRG(logname)"
|
||||
trdb eval {
|
||||
SELECT sum(ntest) AS totaltest,
|
||||
sum(nerr) AS totalerr
|
||||
FROM jobs
|
||||
} break
|
||||
trdb eval {
|
||||
SELECT max(endtime)-min(starttime) AS totaltime
|
||||
FROM jobs WHERE endtime>0
|
||||
} break;
|
||||
set et [elapsetime $totaltime]
|
||||
puts "$totalerr errors out of $totaltest tests in about $et"
|
||||
}
|
||||
|
||||
# Handle the --buildonly option, if it was specified.
|
||||
|
||||
@@ -16,7 +16,6 @@ namespace eval trd {
|
||||
set tcltest(linux.Have-Not) veryquick
|
||||
set tcltest(linux.Secure-Delete) veryquick
|
||||
set tcltest(linux.Unlock-Notify) veryquick
|
||||
set tcltest(linux.User-Auth) veryquick
|
||||
set tcltest(linux.Update-Delete-Limit) veryquick
|
||||
set tcltest(linux.Extra-Robustness) veryquick
|
||||
set tcltest(linux.Device-Two) veryquick
|
||||
@@ -116,6 +115,7 @@ namespace eval trd {
|
||||
}
|
||||
set build(Stdcall) {
|
||||
-DUSE_STDCALL=1
|
||||
-DSQLITE_USE_ONLY_WIN32=1
|
||||
-O2
|
||||
}
|
||||
|
||||
@@ -139,10 +139,6 @@ namespace eval trd {
|
||||
-DSQLITE_THREADSAFE
|
||||
-DSQLITE_TCL_DEFAULT_FULLMUTEX=1
|
||||
}
|
||||
set build(User-Auth) {
|
||||
-O2
|
||||
-DSQLITE_USER_AUTHENTICATION=1
|
||||
}
|
||||
set build(Secure-Delete) {
|
||||
-O2
|
||||
-DSQLITE_SECURE_DELETE=1
|
||||
@@ -222,7 +218,7 @@ namespace eval trd {
|
||||
-DSQLITE_MAX_PAGE_SIZE=4096
|
||||
-DSQLITE_OMIT_LOAD_EXTENSION=1
|
||||
-DSQLITE_OMIT_PROGRESS_CALLBACK=1
|
||||
-DSQLITE_OMIT_VIRTUALTABLE=1
|
||||
-DSQLITE_OMIT_VIRTUALTABLEx=1
|
||||
-DSQLITE_ENABLE_HIDDEN_COLUMNS
|
||||
-DSQLITE_TEMP_STORE=3
|
||||
}
|
||||
|
||||
@@ -54,5 +54,25 @@ do_execsql_test 1.3 {
|
||||
5 5,4 5,4,1 5,4,1,6 5,4,1,6,3 5,4,1,6,3,2
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t1(x);
|
||||
}
|
||||
|
||||
sqlite3_create_aggregate db
|
||||
|
||||
breakpoint
|
||||
do_catchsql_test 2.1 {
|
||||
SELECT min(x) OVER w1 FROM t1
|
||||
WINDOW w1 AS (PARTITION BY x_count(x) OVER w1);
|
||||
} {1 {x_count() may not be used as a window function}}
|
||||
|
||||
do_catchsql_test 2.2 {
|
||||
SELECT min(x) FILTER (WHERE x_count(x) OVER w1) OVER w1 FROM t1
|
||||
WINDOW w1 AS (PARTITION BY x OVER w1);
|
||||
} {1 {near "OVER": syntax error}}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
Reference in New Issue
Block a user