1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-10 01:02:56 +03:00

Merge the latest trunk changes into shared-schema branch. Also fix a C99-ism

in that branch.

FossilOrigin-Name: 42338e9e6979bb497823527f8f39e96f63623c59
This commit is contained in:
drh
2012-06-05 19:20:03 +00:00
46 changed files with 29631 additions and 214 deletions

View File

@@ -165,8 +165,9 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
backup.lo bitvec.lo btmutex.lo btree.lo build.lo \ backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
callback.lo complete.lo ctime.lo date.lo delete.lo \ callback.lo complete.lo ctime.lo date.lo delete.lo \
expr.lo fault.lo fkey.lo \ expr.lo fault.lo fkey.lo \
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo fts3_porter.lo \ fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo fts3_write.lo \ fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
func.lo global.lo hash.lo \ func.lo global.lo hash.lo \
icu.lo insert.lo journal.lo legacy.lo loadext.lo \ icu.lo insert.lo journal.lo legacy.lo loadext.lo \
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \ main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
@@ -317,6 +318,8 @@ SRC += \
$(TOP)/ext/fts3/fts3_tokenizer.h \ $(TOP)/ext/fts3/fts3_tokenizer.h \
$(TOP)/ext/fts3/fts3_tokenizer.c \ $(TOP)/ext/fts3/fts3_tokenizer.c \
$(TOP)/ext/fts3/fts3_tokenizer1.c \ $(TOP)/ext/fts3/fts3_tokenizer1.c \
$(TOP)/ext/fts3/fts3_unicode.c \
$(TOP)/ext/fts3/fts3_unicode2.c \
$(TOP)/ext/fts3/fts3_write.c $(TOP)/ext/fts3/fts3_write.c
SRC += \ SRC += \
$(TOP)/ext/icu/sqliteicu.h \ $(TOP)/ext/icu/sqliteicu.h \

View File

@@ -250,8 +250,9 @@ LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
backup.lo bitvec.lo btmutex.lo btree.lo build.lo \ backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
callback.lo complete.lo ctime.lo date.lo delete.lo \ callback.lo complete.lo ctime.lo date.lo delete.lo \
expr.lo fault.lo fkey.lo \ expr.lo fault.lo fkey.lo \
fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo fts3_porter.lo \ fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo fts3_write.lo \ fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
func.lo global.lo hash.lo \ func.lo global.lo hash.lo \
icu.lo insert.lo journal.lo legacy.lo loadext.lo \ icu.lo insert.lo journal.lo legacy.lo loadext.lo \
main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \ main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
@@ -405,6 +406,8 @@ SRC = $(SRC) \
$(TOP)\ext\fts3\fts3_tokenizer.h \ $(TOP)\ext\fts3\fts3_tokenizer.h \
$(TOP)\ext\fts3\fts3_tokenizer.c \ $(TOP)\ext\fts3\fts3_tokenizer.c \
$(TOP)\ext\fts3\fts3_tokenizer1.c \ $(TOP)\ext\fts3\fts3_tokenizer1.c \
$(TOP)\ext\fts3\fts3_unicode.c \
$(TOP)\ext\fts3\fts3_unicode2.c \
$(TOP)\ext\fts3\fts3_write.c $(TOP)\ext\fts3\fts3_write.c
SRC = $(SRC) \ SRC = $(SRC) \
$(TOP)\ext\icu\sqliteicu.h \ $(TOP)\ext\icu\sqliteicu.h \
@@ -512,6 +515,8 @@ TESTSRC2 = \
$(TOP)\ext\fts3\fts3_aux.c \ $(TOP)\ext\fts3\fts3_aux.c \
$(TOP)\ext\fts3\fts3_expr.c \ $(TOP)\ext\fts3\fts3_expr.c \
$(TOP)\ext\fts3\fts3_tokenizer.c \ $(TOP)\ext\fts3\fts3_tokenizer.c \
$(TOP)\ext\fts3\fts3_unicode.c \
$(TOP)\ext\fts3\fts3_unicode2.c \
$(TOP)\ext\fts3\fts3_write.c \ $(TOP)\ext\fts3\fts3_write.c \
$(TOP)\ext\async\sqlite3async.c $(TOP)\ext\async\sqlite3async.c
@@ -926,6 +931,12 @@ fts3_tokenizer.lo: $(TOP)\ext\fts3\fts3_tokenizer.c $(HDR) $(EXTHDR)
fts3_tokenizer1.lo: $(TOP)\ext\fts3\fts3_tokenizer1.c $(HDR) $(EXTHDR) fts3_tokenizer1.lo: $(TOP)\ext\fts3\fts3_tokenizer1.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_tokenizer1.c $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_tokenizer1.c
fts3_unicode.lo: $(TOP)\ext\fts3\fts3_unicode.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_unicode.c
fts3_unicode2.lo: $(TOP)\ext\fts3\fts3_unicode2.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_unicode2.c
fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR) fts3_write.lo: $(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR)
$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_write.c $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_write.c

View File

@@ -1 +1 @@
3.7.12 3.7.13

18
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.62 for sqlite 3.7.12. # Generated by GNU Autoconf 2.62 for sqlite 3.7.13.
# #
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -743,8 +743,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='sqlite' PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite' PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.7.12' PACKAGE_VERSION='3.7.13'
PACKAGE_STRING='sqlite 3.7.12' PACKAGE_STRING='sqlite 3.7.13'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
# Factoring default headers for most tests. # Factoring default headers for most tests.
@@ -1485,7 +1485,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures sqlite 3.7.12 to adapt to many kinds of systems. \`configure' configures sqlite 3.7.13 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1550,7 +1550,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.7.12:";; short | recursive ) echo "Configuration of sqlite 3.7.13:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1666,7 +1666,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
sqlite configure 3.7.12 sqlite configure 3.7.13
generated by GNU Autoconf 2.62 generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1680,7 +1680,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.7.12, which was It was created by sqlite $as_me 3.7.13, which was
generated by GNU Autoconf 2.62. Invocation command line was generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@ $ $0 $@
@@ -14032,7 +14032,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by sqlite $as_me 3.7.12, which was This file was extended by sqlite $as_me 3.7.13, which was
generated by GNU Autoconf 2.62. Invocation command line was generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -14085,7 +14085,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\ ac_cs_version="\\
sqlite config.status 3.7.12 sqlite config.status 3.7.13
configured by $0, generated by GNU Autoconf 2.62, configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"

View File

@@ -11,7 +11,7 @@
); );
The built-in tokenizers (valid values to pass as <tokenizer name>) are The built-in tokenizers (valid values to pass as <tokenizer name>) are
"simple" and "porter". "simple", "porter" and "unicode".
<tokenizer-args> should consist of zero or more white-space separated <tokenizer-args> should consist of zero or more white-space separated
arguments to pass to the selected tokenizer implementation. The arguments to pass to the selected tokenizer implementation. The

View File

@@ -3554,6 +3554,9 @@ static void hashDestroy(void *p){
*/ */
void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule); void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
#ifndef SQLITE_DISABLE_FTS3_UNICODE
void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const**ppModule);
#endif
#ifdef SQLITE_ENABLE_ICU #ifdef SQLITE_ENABLE_ICU
void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule); void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
#endif #endif
@@ -3569,12 +3572,19 @@ int sqlite3Fts3Init(sqlite3 *db){
Fts3Hash *pHash = 0; Fts3Hash *pHash = 0;
const sqlite3_tokenizer_module *pSimple = 0; const sqlite3_tokenizer_module *pSimple = 0;
const sqlite3_tokenizer_module *pPorter = 0; const sqlite3_tokenizer_module *pPorter = 0;
#ifndef SQLITE_DISABLE_FTS3_UNICODE
const sqlite3_tokenizer_module *pUnicode = 0;
#endif
#ifdef SQLITE_ENABLE_ICU #ifdef SQLITE_ENABLE_ICU
const sqlite3_tokenizer_module *pIcu = 0; const sqlite3_tokenizer_module *pIcu = 0;
sqlite3Fts3IcuTokenizerModule(&pIcu); sqlite3Fts3IcuTokenizerModule(&pIcu);
#endif #endif
#ifndef SQLITE_DISABLE_FTS3_UNICODE
sqlite3Fts3UnicodeTokenizer(&pUnicode);
#endif
#ifdef SQLITE_TEST #ifdef SQLITE_TEST
rc = sqlite3Fts3InitTerm(db); rc = sqlite3Fts3InitTerm(db);
if( rc!=SQLITE_OK ) return rc; if( rc!=SQLITE_OK ) return rc;
@@ -3598,6 +3608,10 @@ int sqlite3Fts3Init(sqlite3 *db){
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple)
|| sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter)
#ifndef SQLITE_DISABLE_FTS3_UNICODE
|| sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode)
#endif
#ifdef SQLITE_ENABLE_ICU #ifdef SQLITE_ENABLE_ICU
|| (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu))
#endif #endif

View File

@@ -541,5 +541,9 @@ int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr);
int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *);
/* fts3_unicode2.c (functions generated by parsing unicode text files) */
int sqlite3FtsUnicodeTolower(int);
int sqlite3FtsUnicodeIsalnum(int);
#endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */
#endif /* _FTSINT_H */ #endif /* _FTSINT_H */

246
ext/fts3/fts3_unicode.c Normal file
View File

@@ -0,0 +1,246 @@
/*
** 2012 May 24
**
** 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.
**
******************************************************************************
**
** Implementation of the "unicode" full-text-search tokenizer.
*/
#ifndef SQLITE_DISABLE_FTS3_UNICODE
#include "fts3Int.h"
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "fts3_tokenizer.h"
/*
** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied
** from the sqlite3 source file utf.c. If this file is compiled as part
** of the amalgamation, they are not required.
*/
#ifndef SQLITE_AMALGAMATION
static const unsigned char sqlite3Utf8Trans1[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
};
#define READ_UTF8(zIn, zTerm, c) \
c = *(zIn++); \
if( c>=0xc0 ){ \
c = sqlite3Utf8Trans1[c-0xc0]; \
while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \
c = (c<<6) + (0x3f & *(zIn++)); \
} \
if( c<0x80 \
|| (c&0xFFFFF800)==0xD800 \
|| (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \
}
#define WRITE_UTF8(zOut, c) { \
if( c<0x00080 ){ \
*zOut++ = (u8)(c&0xFF); \
} \
else if( c<0x00800 ){ \
*zOut++ = 0xC0 + (u8)((c>>6)&0x1F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
} \
else if( c<0x10000 ){ \
*zOut++ = 0xE0 + (u8)((c>>12)&0x0F); \
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
}else{ \
*zOut++ = 0xF0 + (u8)((c>>18) & 0x07); \
*zOut++ = 0x80 + (u8)((c>>12) & 0x3F); \
*zOut++ = 0x80 + (u8)((c>>6) & 0x3F); \
*zOut++ = 0x80 + (u8)(c & 0x3F); \
} \
}
#endif /* ifndef SQLITE_AMALGAMATION */
typedef struct unicode_tokenizer unicode_tokenizer;
typedef struct unicode_cursor unicode_cursor;
struct unicode_tokenizer {
sqlite3_tokenizer base;
};
struct unicode_cursor {
sqlite3_tokenizer_cursor base;
const unsigned char *aInput; /* Input text being tokenized */
int nInput; /* Size of aInput[] in bytes */
int iOff; /* Current offset within aInput[] */
int iToken; /* Index of next token to be returned */
char *zToken; /* storage for current token */
int nAlloc; /* space allocated at zToken */
};
/*
** Create a new tokenizer instance.
*/
static int unicodeCreate(
int nArg, /* Size of array argv[] */
const char * const *azArg, /* Tokenizer creation arguments */
sqlite3_tokenizer **pp /* OUT: New tokenizer handle */
){
unicode_tokenizer *pNew; /* New tokenizer object */
pNew = (unicode_tokenizer *) sqlite3_malloc(sizeof(unicode_tokenizer));
if( pNew==NULL ){
return SQLITE_NOMEM;
}
memset(pNew, 0, sizeof(unicode_tokenizer));
*pp = &pNew->base;
return SQLITE_OK;
}
/*
** Destroy a tokenizer allocated by unicodeCreate().
*/
static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){
sqlite3_free(pTokenizer);
return SQLITE_OK;
}
/*
** Prepare to begin tokenizing a particular string. The input
** string to be tokenized is pInput[0..nBytes-1]. A cursor
** used to incrementally tokenize this string is returned in
** *ppCursor.
*/
static int unicodeOpen(
sqlite3_tokenizer *p, /* The tokenizer */
const char *aInput, /* Input string */
int nInput, /* Size of string aInput in bytes */
sqlite3_tokenizer_cursor **pp /* OUT: New cursor object */
){
unicode_cursor *pCsr;
pCsr = (unicode_cursor *)sqlite3_malloc(sizeof(unicode_cursor));
if( pCsr==0 ){
return SQLITE_NOMEM;
}
memset(pCsr, 0, sizeof(unicode_cursor));
pCsr->aInput = (const unsigned char *)aInput;
if( aInput==0 ){
pCsr->nInput = 0;
}else if( nInput<0 ){
pCsr->nInput = (int)strlen(aInput);
}else{
pCsr->nInput = nInput;
}
*pp = &pCsr->base;
UNUSED_PARAMETER(p);
return SQLITE_OK;
}
/*
** Close a tokenization cursor previously opened by a call to
** simpleOpen() above.
*/
static int unicodeClose(sqlite3_tokenizer_cursor *pCursor){
unicode_cursor *pCsr = (unicode_cursor *) pCursor;
sqlite3_free(pCsr->zToken);
sqlite3_free(pCsr);
return SQLITE_OK;
}
/*
** Extract the next token from a tokenization cursor. The cursor must
** have been opened by a prior call to simpleOpen().
*/
static int unicodeNext(
sqlite3_tokenizer_cursor *p, /* Cursor returned by simpleOpen */
const char **paToken, /* OUT: Token text */
int *pnToken, /* OUT: Number of bytes at *paToken */
int *piStart, /* OUT: Starting offset of token */
int *piEnd, /* OUT: Ending offset of token */
int *piPos /* OUT: Position integer of token */
){
unicode_cursor *pCsr = (unicode_cursor *)p;
int iCode;
char *zOut;
const unsigned char *z = &pCsr->aInput[pCsr->iOff];
const unsigned char *zStart = z;
const unsigned char *zEnd;
const unsigned char *zTerm = &pCsr->aInput[pCsr->nInput];
/* Scan past any delimiter characters before the start of the next token.
** Return SQLITE_DONE early if this takes us all the way to the end of
** the input. */
while( z<zTerm ){
READ_UTF8(z, zTerm, iCode);
if( sqlite3FtsUnicodeIsalnum(iCode) ) break;
zStart = z;
}
if( zStart>=zTerm ) return SQLITE_DONE;
zOut = pCsr->zToken;
do {
/* Grow the output buffer if required. */
if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){
char *zNew = sqlite3_realloc(pCsr->zToken, pCsr->nAlloc+64);
if( !zNew ) return SQLITE_NOMEM;
zOut = &zNew[zOut - pCsr->zToken];
pCsr->zToken = zNew;
pCsr->nAlloc += 64;
}
/* Write the folded case of the last character read to the output */
zEnd = z;
WRITE_UTF8(zOut, sqlite3FtsUnicodeTolower(iCode));
/* If the cursor is not at EOF, read the next character */
if( z>=zTerm ) break;
READ_UTF8(z, zTerm, iCode);
}while( sqlite3FtsUnicodeIsalnum(iCode) );
/* Set the output variables and return. */
pCsr->iOff = (z - pCsr->aInput);
*paToken = pCsr->zToken;
*pnToken = zOut - pCsr->zToken;
*piStart = (zStart - pCsr->aInput);
*piEnd = (zEnd - pCsr->aInput);
*piPos = pCsr->iToken++;
return SQLITE_OK;
}
/*
** Set *ppModule to a pointer to the sqlite3_tokenizer_module
** structure for the unicode tokenizer.
*/
void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){
static const sqlite3_tokenizer_module module = {
0,
unicodeCreate,
unicodeDestroy,
unicodeOpen,
unicodeClose,
unicodeNext,
0,
};
*ppModule = &module;
}
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
#endif /* ifndef SQLITE_DISABLE_FTS3_UNICODE */

296
ext/fts3/fts3_unicode2.c Normal file
View File

@@ -0,0 +1,296 @@
/*
** 2012 May 25
**
** 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.
**
******************************************************************************
*/
/*
** DO NOT EDIT THIS MACHINE GENERATED FILE.
*/
#if !defined(SQLITE_DISABLE_FTS3_UNICODE)
#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
#include <assert.h>
/*
** Return true if the argument corresponds to a unicode codepoint
** classified as either a letter or a number. Otherwise false.
**
** The results are undefined if the value passed to this function
** is less than zero.
*/
int sqlite3FtsUnicodeIsalnum(int c){
/* Each unsigned integer in the following array corresponds to a contiguous
** range of unicode codepoints that are not either letters or numbers (i.e.
** codepoints for which this function should return 0).
**
** The most significant 22 bits in each 32-bit value contain the first
** codepoint in the range. The least significant 10 bits are used to store
** the size of the range (always at least 1). In other words, the value
** ((C<<22) + N) represents a range of N codepoints starting with codepoint
** C. It is not possible to represent a range larger than 1023 codepoints
** using this format.
*/
const static unsigned int aEntry[] = {
0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01,
0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802,
0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F,
0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401,
0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804,
0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403,
0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812,
0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001,
0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802,
0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805,
0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401,
0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03,
0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807,
0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001,
0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01,
0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804,
0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001,
0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01,
0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06,
0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007,
0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006,
0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417,
0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14,
0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07,
0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01,
0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001,
0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802,
0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F,
0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002,
0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802,
0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006,
0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D,
0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802,
0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027,
0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403,
0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805,
0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04,
0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401,
0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005,
0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B,
0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A,
0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001,
0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59,
0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807,
0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01,
0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E,
0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100,
0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10,
0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402,
0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804,
0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012,
0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004,
0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002,
0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803,
0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07,
0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
0x037FFC02, 0x03E3FC01, 0x03EC7801, 0x03ECA401, 0x03EEC810,
0x03F4F802, 0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023,
0x03F95013, 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807,
0x03FCEC06, 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405,
0x04040003, 0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E,
0x040E7C01, 0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01,
0x04280403, 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01,
0x04294009, 0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016,
0x04420003, 0x0442C012, 0x04440003, 0x04449C0E, 0x04450004,
0x04460003, 0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004,
0x05BD442E, 0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5,
0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01,
0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401,
0x075EA401, 0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064,
0x07C2800F, 0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F,
0x07C4C03C, 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009,
0x07C94002, 0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014,
0x07CE8025, 0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001,
0x07D108B6, 0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018,
0x07D7EC46, 0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401,
0x38008060, 0x380400F0, 0x3C000001, 0x3FFFF401, 0x40000001,
0x43FFF401,
};
static const unsigned int aAscii[4] = {
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
};
if( c<128 ){
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
}else if( c<(1<<22) ){
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
int iRes;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
if( key >= aEntry[iTest] ){
iRes = iTest;
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( aEntry[0]<key );
assert( key>=aEntry[iRes] );
return (c >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
}
return 1;
}
/*
** Interpret the argument as a unicode codepoint. If the codepoint
** is an upper case character that has a lower case equivalent,
** return the codepoint corresponding to the lower case version.
** Otherwise, return a copy of the argument.
**
** The results are undefined if the value passed to this function
** is less than zero.
*/
int sqlite3FtsUnicodeTolower(int c){
/* Each entry in the following array defines a rule for folding a range
** of codepoints to lower case. The rule applies to a range of nRange
** codepoints starting at codepoint iCode.
**
** If the least significant bit in flags is clear, then the rule applies
** to all nRange codepoints (i.e. all nRange codepoints are upper case and
** need to be folded). Or, if it is set, then the rule only applies to
** every second codepoint in the range, starting with codepoint C.
**
** The 7 most significant bits in flags are an index into the aiOff[]
** array. If a specific codepoint C does require folding, then its lower
** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF).
**
** The contents of this array are generated by parsing the CaseFolding.txt
** file distributed as part of the "Unicode Character Database". See
** http://www.unicode.org for details.
*/
static const struct TableEntry {
unsigned short iCode;
unsigned char flags;
unsigned char nRange;
} aEntry[] = {
{65, 14, 26}, {181, 64, 1}, {192, 14, 23},
{216, 14, 7}, {256, 1, 48}, {306, 1, 6},
{313, 1, 16}, {330, 1, 46}, {376, 116, 1},
{377, 1, 6}, {383, 104, 1}, {385, 50, 1},
{386, 1, 4}, {390, 44, 1}, {391, 0, 1},
{393, 42, 2}, {395, 0, 1}, {398, 32, 1},
{399, 38, 1}, {400, 40, 1}, {401, 0, 1},
{403, 42, 1}, {404, 46, 1}, {406, 52, 1},
{407, 48, 1}, {408, 0, 1}, {412, 52, 1},
{413, 54, 1}, {415, 56, 1}, {416, 1, 6},
{422, 60, 1}, {423, 0, 1}, {425, 60, 1},
{428, 0, 1}, {430, 60, 1}, {431, 0, 1},
{433, 58, 2}, {435, 1, 4}, {439, 62, 1},
{440, 0, 1}, {444, 0, 1}, {452, 2, 1},
{453, 0, 1}, {455, 2, 1}, {456, 0, 1},
{458, 2, 1}, {459, 1, 18}, {478, 1, 18},
{497, 2, 1}, {498, 1, 4}, {502, 122, 1},
{503, 134, 1}, {504, 1, 40}, {544, 110, 1},
{546, 1, 18}, {570, 70, 1}, {571, 0, 1},
{573, 108, 1}, {574, 68, 1}, {577, 0, 1},
{579, 106, 1}, {580, 28, 1}, {581, 30, 1},
{582, 1, 10}, {837, 36, 1}, {880, 1, 4},
{886, 0, 1}, {902, 18, 1}, {904, 16, 3},
{908, 26, 1}, {910, 24, 2}, {913, 14, 17},
{931, 14, 9}, {962, 0, 1}, {975, 4, 1},
{976, 140, 1}, {977, 142, 1}, {981, 146, 1},
{982, 144, 1}, {984, 1, 24}, {1008, 136, 1},
{1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1},
{1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1},
{1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32},
{1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1},
{1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38},
{4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1},
{7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1},
{7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6},
{7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6},
{8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8},
{8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2},
{8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1},
{8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2},
{8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2},
{8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2},
{8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1},
{8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16},
{8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47},
{11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1},
{11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1},
{11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1},
{11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2},
{11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1},
{42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14},
{42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1},
{42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1},
{42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1},
{65313, 14, 26},
};
static const unsigned short aiOff[] = {
1, 2, 8, 15, 16, 26, 28, 32,
37, 38, 40, 48, 63, 64, 69, 71,
79, 80, 116, 202, 203, 205, 206, 207,
209, 210, 211, 213, 214, 217, 218, 219,
775, 7264, 10792, 10795, 23228, 23256, 30204, 54721,
54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274,
57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406,
65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462,
65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511,
65514, 65521, 65527, 65528, 65529,
};
int ret = c;
assert( c>=0 );
assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
if( c<128 ){
if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
}else if( c<65536 ){
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
int iRes = -1;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
int cmp = (c - aEntry[iTest].iCode);
if( cmp>=0 ){
iRes = iTest;
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( iRes<0 || c>=aEntry[iRes].iCode );
if( iRes>=0 ){
const struct TableEntry *p = &aEntry[iRes];
if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
assert( ret>0 );
}
}
}
else if( c>=66560 && c<66600 ){
ret = c + 40;
}
return ret;
}
#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */
#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */

View File

@@ -3174,7 +3174,12 @@ static void fts3UpdateDocTotals(
}else{ }else{
memset(a, 0, sizeof(u32)*(nStat) ); memset(a, 0, sizeof(u32)*(nStat) );
} }
sqlite3_reset(pStmt); rc = sqlite3_reset(pStmt);
if( rc!=SQLITE_OK ){
sqlite3_free(a);
*pRC = rc;
return;
}
if( nChng<0 && a[0]<(u32)(-nChng) ){ if( nChng<0 && a[0]<(u32)(-nChng) ){
a[0] = 0; a[0] = 0;
}else{ }else{

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,574 @@
# Parameter $zName must be a path to the file UnicodeData.txt. This command
# reads the file and returns a list of codepoints (integers). The list
# contains all codepoints in the UnicodeData.txt assigned to any "General
# Category" that is not a "Letter" or "Number".
#
proc an_load_unicodedata_text {zName} {
set fd [open $zName]
set lField {
code
character_name
general_category
canonical_combining_classes
bidirectional_category
character_decomposition_mapping
decimal_digit_value
digit_value
numeric_value
mirrored
unicode_1_name
iso10646_comment_field
uppercase_mapping
lowercase_mapping
titlecase_mapping
}
set lRet [list]
while { ![eof $fd] } {
set line [gets $fd]
if {$line == ""} continue
set fields [split $line ";"]
if {[llength $fields] != [llength $lField]} { error "parse error: $line" }
foreach $lField $fields {}
set iCode [expr "0x$code"]
set bAlnum [expr {[lsearch {L N} [string range $general_category 0 0]]>=0}]
if { !$bAlnum } { lappend lRet $iCode }
}
close $fd
set lRet
}
proc an_load_separator_ranges {} {
global unicodedata.txt
set lSep [an_load_unicodedata_text ${unicodedata.txt}]
unset -nocomplain iFirst
unset -nocomplain nRange
set lRange [list]
foreach sep $lSep {
if {0==[info exists iFirst]} {
set iFirst $sep
set nRange 1
} elseif { $sep == ($iFirst+$nRange) } {
incr nRange
} else {
lappend lRange [list $iFirst $nRange]
set iFirst $sep
set nRange 1
}
}
lappend lRange [list $iFirst $nRange]
set lRange
}
proc an_print_range_array {lRange} {
set iFirstMax 0
set nRangeMax 0
foreach range $lRange {
foreach {iFirst nRange} $range {}
if {$iFirst > $iFirstMax} {set iFirstMax $iFirst}
if {$nRange > $nRangeMax} {set nRangeMax $nRange}
}
if {$iFirstMax >= (1<<22)} {error "first-max is too large for format"}
if {$nRangeMax >= (1<<10)} {error "range-max is too large for format"}
puts -nonewline " "
puts [string trim {
/* Each unsigned integer in the following array corresponds to a contiguous
** range of unicode codepoints that are not either letters or numbers (i.e.
** codepoints for which this function should return 0).
**
** The most significant 22 bits in each 32-bit value contain the first
** codepoint in the range. The least significant 10 bits are used to store
** the size of the range (always at least 1). In other words, the value
** ((C<<22) + N) represents a range of N codepoints starting with codepoint
** C. It is not possible to represent a range larger than 1023 codepoints
** using this format.
*/
}]
puts -nonewline " const static unsigned int aEntry\[\] = \{"
set i 0
foreach range $lRange {
foreach {iFirst nRange} $range {}
set u32 [format "0x%08X" [expr ($iFirst<<10) + $nRange]]
if {($i % 5)==0} {puts "" ; puts -nonewline " "}
puts -nonewline " $u32,"
incr i
}
puts ""
puts " \};"
}
proc an_print_ascii_bitmap {lRange} {
foreach range $lRange {
foreach {iFirst nRange} $range {}
for {set i $iFirst} {$i < ($iFirst+$nRange)} {incr i} {
if {$i<=127} { set a($i) 1 }
}
}
set aAscii [list 0 0 0 0]
foreach key [array names a] {
set idx [expr $key >> 5]
lset aAscii $idx [expr [lindex $aAscii $idx] | (1 << ($key&0x001F))]
}
puts " static const unsigned int aAscii\[4\] = \{"
puts -nonewline " "
foreach v $aAscii { puts -nonewline [format " 0x%08X," $v] }
puts ""
puts " \};"
}
proc print_isalnum {zFunc lRange} {
puts "/*"
puts "** Return true if the argument corresponds to a unicode codepoint"
puts "** classified as either a letter or a number. Otherwise false."
puts "**"
puts "** The results are undefined if the value passed to this function"
puts "** is less than zero."
puts "*/"
puts "int ${zFunc}\(int c)\{"
an_print_range_array $lRange
an_print_ascii_bitmap $lRange
puts {
if( c<128 ){
return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
}else if( c<(1<<22) ){
unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
int iRes;
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
if( key >= aEntry[iTest] ){
iRes = iTest;
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( aEntry[0]<key );
assert( key>=aEntry[iRes] );
return (c >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
}
return 1;}
puts "\}"
}
proc print_test_isalnum {zFunc lRange} {
foreach range $lRange {
foreach {iFirst nRange} $range {}
for {set i $iFirst} {$i < ($iFirst+$nRange)} {incr i} { set a($i) 1 }
}
puts "static int isalnum_test(int *piCode)\{"
puts -nonewline " unsigned char aAlnum\[\] = \{"
for {set i 0} {$i < 70000} {incr i} {
if {($i % 32)==0} { puts "" ; puts -nonewline " " }
set bFlag [expr ![info exists a($i)]]
puts -nonewline "${bFlag},"
}
puts ""
puts " \};"
puts -nonewline " int aLargeSep\[\] = \{"
set i 0
foreach iSep [lsort -integer [array names a]] {
if {$iSep<70000} continue
if {($i % 8)==0} { puts "" ; puts -nonewline " " }
puts -nonewline " $iSep,"
incr i
}
puts ""
puts " \};"
puts -nonewline " int aLargeOther\[\] = \{"
set i 0
foreach iSep [lsort -integer [array names a]] {
if {$iSep<70000} continue
if {[info exists a([expr $iSep-1])]==0} {
if {($i % 8)==0} { puts "" ; puts -nonewline " " }
puts -nonewline " [expr $iSep-1],"
incr i
}
if {[info exists a([expr $iSep+1])]==0} {
if {($i % 8)==0} { puts "" ; puts -nonewline " " }
puts -nonewline " [expr $iSep+1],"
incr i
}
}
puts ""
puts " \};"
puts [subst -nocommands {
int i;
for(i=0; i<sizeof(aAlnum)/sizeof(aAlnum[0]); i++){
if( ${zFunc}(i)!=aAlnum[i] ){
*piCode = i;
return 1;
}
}
for(i=0; i<sizeof(aLargeSep)/sizeof(aLargeSep[0]); i++){
if( ${zFunc}(aLargeSep[i])!=0 ){
*piCode = aLargeSep[i];
return 1;
}
}
for(i=0; i<sizeof(aLargeOther)/sizeof(aLargeOther[0]); i++){
if( ${zFunc}(aLargeOther[i])!=1 ){
*piCode = aLargeOther[i];
return 1;
}
}
}]
puts " return 0;"
puts "\}"
}
#-------------------------------------------------------------------------
proc tl_load_casefolding_txt {zName} {
global tl_lookup_table
set fd [open $zName]
while { ![eof $fd] } {
set line [gets $fd]
if {[string range $line 0 0] == "#"} continue
if {$line == ""} continue
foreach x {a b c d} {unset -nocomplain $x}
foreach {a b c d} [split $line ";"] {}
set a2 [list]
set c2 [list]
foreach elem $a { lappend a2 [expr "0x[string trim $elem]"] }
foreach elem $c { lappend c2 [expr "0x[string trim $elem]"] }
set b [string trim $b]
set d [string trim $d]
if {$b=="C" || $b=="S"} { set tl_lookup_table($a2) $c2 }
}
}
proc tl_create_records {} {
global tl_lookup_table
set iFirst ""
set nOff 0
set nRange 0
set nIncr 0
set lRecord [list]
foreach code [lsort -integer [array names tl_lookup_table]] {
set mapping $tl_lookup_table($code)
if {$iFirst == ""} {
set iFirst $code
set nOff [expr $mapping - $code]
set nRange 1
set nIncr 1
} else {
set diff [expr $code - ($iFirst + ($nIncr * ($nRange - 1)))]
if { $nRange==1 && ($diff==1 || $diff==2) } {
set nIncr $diff
}
if {$diff != $nIncr || ($mapping - $code)!=$nOff} {
if { $nRange==1 } {set nIncr 1}
lappend lRecord [list $iFirst $nIncr $nRange $nOff]
set iFirst $code
set nOff [expr $mapping - $code]
set nRange 1
set nIncr 1
} else {
incr nRange
}
}
}
lappend lRecord [list $iFirst $nIncr $nRange $nOff]
set lRecord
}
proc tl_print_table_header {} {
puts -nonewline " "
puts [string trim {
/* Each entry in the following array defines a rule for folding a range
** of codepoints to lower case. The rule applies to a range of nRange
** codepoints starting at codepoint iCode.
**
** If the least significant bit in flags is clear, then the rule applies
** to all nRange codepoints (i.e. all nRange codepoints are upper case and
** need to be folded). Or, if it is set, then the rule only applies to
** every second codepoint in the range, starting with codepoint C.
**
** The 7 most significant bits in flags are an index into the aiOff[]
** array. If a specific codepoint C does require folding, then its lower
** case equivalent is ((C + aiOff[flags>>1]) & 0xFFFF).
**
** The contents of this array are generated by parsing the CaseFolding.txt
** file distributed as part of the "Unicode Character Database". See
** http://www.unicode.org for details.
*/
}]
puts " static const struct TableEntry \{"
puts " unsigned short iCode;"
puts " unsigned char flags;"
puts " unsigned char nRange;"
puts " \} aEntry\[\] = \{"
}
proc tl_print_table_entry {togglevar entry liOff} {
upvar $togglevar t
foreach {iFirst nIncr nRange nOff} $entry {}
if {$iFirst > (1<<16)} { return 1 }
if {[info exists t]==0} {set t 0}
if {$t==0} { puts -nonewline " " }
set flags 0
if {$nIncr==2} { set flags 1 ; set nRange [expr $nRange * 2]}
if {$nOff<0} { incr nOff [expr (1<<16)] }
set idx [lsearch $liOff $nOff]
if {$idx<0} {error "malfunction generating aiOff"}
set flags [expr $flags + $idx*2]
set txt "{$iFirst, $flags, $nRange},"
if {$t==2} {
puts $txt
} else {
puts -nonewline [format "% -23s" $txt]
}
set t [expr ($t+1)%3]
return 0
}
proc tl_print_table_footer {togglevar} {
upvar $togglevar t
if {$t!=0} {puts ""}
puts " \};"
}
proc tl_print_if_entry {entry} {
foreach {iFirst nIncr nRange nOff} $entry {}
if {$nIncr==2} {error "tl_print_if_entry needs improvement!"}
puts " else if( c>=$iFirst && c<[expr $iFirst+$nRange] )\{"
puts " ret = c + $nOff;"
puts " \}"
}
proc tl_generate_ioff_table {lRecord} {
foreach entry $lRecord {
foreach {iFirst nIncr nRange iOff} $entry {}
if {$iOff<0} { incr iOff [expr (1<<16)] }
if {[info exists a($iOff)]} continue
set a($iOff) 1
}
set liOff [lsort -integer [array names a]]
if {[llength $liOff]>128} { error "Too many distinct ioffs" }
return $liOff
}
proc tl_print_ioff_table {liOff} {
puts -nonewline " static const unsigned short aiOff\[\] = \{"
set i 0
foreach off $liOff {
if {($i % 8)==0} {puts "" ; puts -nonewline " "}
puts -nonewline [format "% -7s" "$off,"]
incr i
}
puts ""
puts " \};"
}
proc print_tolower {zFunc} {
set lRecord [tl_create_records]
set lHigh [list]
puts "/*"
puts "** Interpret the argument as a unicode codepoint. If the codepoint"
puts "** is an upper case character that has a lower case equivalent,"
puts "** return the codepoint corresponding to the lower case version."
puts "** Otherwise, return a copy of the argument."
puts "**"
puts "** The results are undefined if the value passed to this function"
puts "** is less than zero."
puts "*/"
puts "int ${zFunc}\(int c)\{"
set liOff [tl_generate_ioff_table $lRecord]
tl_print_table_header
foreach entry $lRecord {
if {[tl_print_table_entry toggle $entry $liOff]} {
lappend lHigh $entry
}
}
tl_print_table_footer toggle
tl_print_ioff_table $liOff
puts {
int ret = c;
assert( c>=0 );
assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
if( c<128 ){
if( c>='A' && c<='Z' ) ret = c + ('a' - 'A');
}else if( c<65536 ){
int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
int iLo = 0;
int iRes = -1;
while( iHi>=iLo ){
int iTest = (iHi + iLo) / 2;
int cmp = (c - aEntry[iTest].iCode);
if( cmp>=0 ){
iRes = iTest;
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( iRes<0 || c>=aEntry[iRes].iCode );
if( iRes>=0 ){
const struct TableEntry *p = &aEntry[iRes];
if( c<(p->iCode + p->nRange) && 0==(0x01 & p->flags & (p->iCode ^ c)) ){
ret = (c + (aiOff[p->flags>>1])) & 0x0000FFFF;
assert( ret>0 );
}
}
}
}
foreach entry $lHigh {
tl_print_if_entry $entry
}
puts ""
puts " return ret;"
puts "\}"
}
proc print_tolower_test {zFunc} {
global tl_lookup_table
puts "static int tolower_test(int *piCode)\{"
puts -nonewline " static int aLookup\[\] = \{"
for {set i 0} {$i < 70000} {incr i} {
set expected $i
catch { set expected $tl_lookup_table($i) }
if {($i % 8)==0} { puts "" ; puts -nonewline " " }
puts -nonewline "$expected, "
}
puts " \};"
puts " int i;"
puts " for(i=0; i<sizeof(aLookup)/sizeof(aLookup\[0\]); i++)\{"
puts " if( ${zFunc}\(i)!=aLookup\[i\] )\{"
puts " *piCode = i;"
puts " return 1;"
puts " \}"
puts " \}"
puts " return 0;"
puts "\}"
}
proc print_fileheader {} {
puts [string trim {
/*
** 2012 May 25
**
** 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.
**
******************************************************************************
*/
/*
** DO NOT EDIT THIS MACHINE GENERATED FILE.
*/
}]
puts ""
puts "#if !defined(SQLITE_DISABLE_FTS3_UNICODE)"
puts "#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)"
puts ""
puts "#include <assert.h>"
puts ""
}
proc print_test_main {} {
puts ""
puts "#include <stdio.h>"
puts ""
puts "int main(int argc, char **argv)\{"
puts " int r1, r2;"
puts " int code;"
puts " r1 = isalnum_test(&code);"
puts " if( r1 ) printf(\"isalnum(): Problem with code %d\\n\",code);"
puts " else printf(\"isalnum(): test passed\\n\");"
puts " r2 = tolower_test(&code);"
puts " if( r2 ) printf(\"tolower(): Problem with code %d\\n\",code);"
puts " else printf(\"tolower(): test passed\\n\");"
puts " return (r1 || r2);"
puts "\}"
}
# Proces the command line arguments. Exit early if they are not to
# our liking.
#
proc usage {} {
puts -nonewline stderr "Usage: $::argv0 ?-test? "
puts stderr "<CaseFolding.txt file> <UnicodeData.txt file>"
exit 1
}
if {[llength $argv]!=2 && [llength $argv]!=3} usage
if {[llength $argv]==3 && [lindex $argv 0]!="-test"} usage
set unicodedata.txt [lindex $argv end]
set casefolding.txt [lindex $argv end-1]
set generate_test_code [expr {[llength $argv]==3}]
# Print the isalnum() function to stdout.
#
print_fileheader
set lRange [an_load_separator_ranges]
print_isalnum sqlite3FtsUnicodeIsalnum $lRange
# Leave a gap between the two generated C functions.
#
puts ""
puts ""
# Print the tolower() function to stdout.
#
tl_load_casefolding_txt ${casefolding.txt}
print_tolower sqlite3FtsUnicodeTolower
# Print the test routines and main() function to stdout, if -test
# was specified.
#
if {$::generate_test_code} {
print_test_isalnum sqlite3FtsUnicodeIsalnum $lRange
print_tolower_test sqlite3FtsUnicodeTolower
print_test_main
}
puts "#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */"
puts "#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */"

View File

@@ -2739,6 +2739,36 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){
return rc; return rc;
} }
/*
** Rounding constants for float->double conversion.
*/
#define RNDTOWARDS (1.0 - 1.0/8388608.0) /* Round towards zero */
#define RNDAWAY (1.0 + 1.0/8388608.0) /* Round away from zero */
#if !defined(SQLITE_RTREE_INT_ONLY)
/*
** Convert an sqlite3_value into an RtreeValue (presumably a float)
** while taking care to round toward negative or positive, respectively.
*/
static RtreeValue rtreeValueDown(sqlite3_value *v){
double d = sqlite3_value_double(v);
float f = (float)d;
if( f>d ){
f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS));
}
return f;
}
static RtreeValue rtreeValueUp(sqlite3_value *v){
double d = sqlite3_value_double(v);
float f = (float)d;
if( f<d ){
f = (float)(d*(d<0 ? RNDTOWARDS : RNDAWAY));
}
return f;
}
#endif /* !defined(SQLITE_RTREE_INT_ONLY) */
/* /*
** The xUpdate method for rtree module virtual tables. ** The xUpdate method for rtree module virtual tables.
*/ */
@@ -2775,8 +2805,8 @@ static int rtreeUpdate(
#ifndef SQLITE_RTREE_INT_ONLY #ifndef SQLITE_RTREE_INT_ONLY
if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
for(ii=0; ii<(pRtree->nDim*2); ii+=2){ for(ii=0; ii<(pRtree->nDim*2); ii+=2){
cell.aCoord[ii].f = (RtreeValue)sqlite3_value_double(azData[ii+3]); cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
cell.aCoord[ii+1].f = (RtreeValue)sqlite3_value_double(azData[ii+4]); cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){ if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
rc = SQLITE_CONSTRAINT; rc = SQLITE_CONSTRAINT;
goto constraint; goto constraint;

View File

@@ -55,6 +55,7 @@ LIBOBJ+= alter.o analyze.o attach.o auth.o \
callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \ callback.o complete.o ctime.o date.o delete.o expr.o fault.o fkey.o \
fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \ fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \ fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
fts3_unicode.o fts3_unicode2.o \
fts3_write.o func.o global.o hash.o \ fts3_write.o func.o global.o hash.o \
icu.o insert.o journal.o legacy.o loadext.o \ icu.o insert.o journal.o legacy.o loadext.o \
main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \ main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
@@ -198,6 +199,8 @@ SRC += \
$(TOP)/ext/fts3/fts3_tokenizer.h \ $(TOP)/ext/fts3/fts3_tokenizer.h \
$(TOP)/ext/fts3/fts3_tokenizer.c \ $(TOP)/ext/fts3/fts3_tokenizer.c \
$(TOP)/ext/fts3/fts3_tokenizer1.c \ $(TOP)/ext/fts3/fts3_tokenizer1.c \
$(TOP)/ext/fts3/fts3_unicode.c \
$(TOP)/ext/fts3/fts3_unicode2.c \
$(TOP)/ext/fts3/fts3_write.c $(TOP)/ext/fts3/fts3_write.c
SRC += \ SRC += \
$(TOP)/ext/icu/sqliteicu.h \ $(TOP)/ext/icu/sqliteicu.h \
@@ -508,6 +511,12 @@ fts3_tokenizer.o: $(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR) fts3_tokenizer1.o: $(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR)
$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c
fts3_unicode.o: $(TOP)/ext/fts3/fts3_unicode.c $(HDR) $(EXTHDR)
$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode.c
fts3_unicode2.o: $(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR)
$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c
fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR) fts3_write.o: $(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c $(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c

View File

@@ -1,12 +1,12 @@
C Return\sSQLITE_MISUSE\sif\san\sapplication\sattempts\sto\sregister\sa\svirtual\stable\smodule\swith\sthe\ssame\sname\sas\san\sexisting\smodule. C Merge\sthe\slatest\strunk\schanges\sinto\sshared-schema\sbranch.\s\sAlso\sfix\sa\sC99-ism\s\nin\sthat\sbranch.
D 2012-05-16T14:29:11.421 D 2012-06-05T19:20:03.039
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20 F Makefile.in 4f37eb61be9d38643cdd839a74b8e3bad724cfcf
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F Makefile.msc 7849a871b6cdb20fd51baee6bbe5965a03326be4 F Makefile.msc 0891f992d012d6b2976f86e80a82ae6839fa9ded
F Makefile.vxworks 3b7fe7a0571fdadc61363ebc1b23732d2d6363ca F Makefile.vxworks 3b7fe7a0571fdadc61363ebc1b23732d2d6363ca
F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6
F VERSION f9313d88cb77df8617059a88eb382291321ef6bc F VERSION 3e857b9b826e818eec9411eafe2c3fa22c1dbb8a
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531 F addopcodes.awk 17dc593f791f874d2c23a0f9360850ded0286531
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
@@ -15,7 +15,7 @@ F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977 F config.guess 226d9a188c6196f3033ffc651cbc9dcee1a42977
F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de F config.h.in 0921066a13130082764ab4ab6456f7b5bebe56de
F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55 F config.sub 9ebe4c3b3dab6431ece34f16828b594fb420da55
F configure eb9e5e7f4c1601b5acf674a724e1a778481d2835 x F configure 79405675c313ce4a5e94afac6ec880bb3e27b4f1 x
F configure.ac 9ee886c21c095b3272137b1553ae416c8b8c8557 F configure.ac 9ee886c21c095b3272137b1553ae416c8b8c8557
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/lemon.html 3091574143dd3415669b6745843ff8d011d33549 F doc/lemon.html 3091574143dd3415669b6745843ff8d011d33549
@@ -53,11 +53,11 @@ F ext/fts2/fts2_tokenizer1.c 0123d21078e053bd98fd6186c5c6dc6d67969f2e
F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0 F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0
F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51 F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9 F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c a7adf6747d1fdd627ecd421c1709996741ca6693 F ext/fts3/fts3.c 41824d0db7d244ca335ce98162df1244863a05c4
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h aca752b99c15ee738f5bcf0910eafb9e4aeb1b97 F ext/fts3/fts3Int.h 7b163fa22e7a625c404c424f2779a4d7b14c14ad
F ext/fts3/fts3_aux.c 5205182bd8f372782597888156404766edf5781e F ext/fts3/fts3_aux.c 5205182bd8f372782597888156404766edf5781e
F ext/fts3/fts3_expr.c dbc7ba4c3a6061adde0f38ed8e9b349568299551 F ext/fts3/fts3_expr.c dbc7ba4c3a6061adde0f38ed8e9b349568299551
F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914 F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914
@@ -70,15 +70,20 @@ F ext/fts3/fts3_test.c 348f7d08cae05285794e23dc4fe8b8fdf66e264a
F ext/fts3/fts3_tokenizer.c 3da7254a9881f7e270ab28e2004e0d22b3212bce F ext/fts3/fts3_tokenizer.c 3da7254a9881f7e270ab28e2004e0d22b3212bce
F ext/fts3/fts3_tokenizer.h 66dec98e365854b6cd2d54f1a96bb6d428fc5a68 F ext/fts3/fts3_tokenizer.h 66dec98e365854b6cd2d54f1a96bb6d428fc5a68
F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
F ext/fts3/fts3_write.c cd4af00b3b0512b4d76177a267fcaafab44cbce4 F ext/fts3/fts3_unicode.c 76b6f6fe6e86acd75b08272502fae74a13cef310
F ext/fts3/fts3_unicode2.c 3ddf1728a396a03b5a73ff0f11ecfd2009de117d
F ext/fts3/fts3_write.c 6a6391d6b01114f885e24e1f66bbc11ffba0e9e2
F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197 F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
F ext/fts3/unicode/mkunicode.tcl 2029991cc2cd0bf71df12768578a29c852bf54d1
F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9 F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9
F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a F ext/icu/icu.c eb9ae1d79046bd7871aa97ee6da51eb770134b5a
F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/rtree.c 73502e5336162fdc8f5d1c4bdd4ec6b1299c2f2a F ext/rtree/rtree.c d17aecb7a92762efa7b1f5d5fd7c88fd77d70827
F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e F ext/rtree/rtree.h 834dbcb82dc85b2481cde6a07cdadfddc99e9b9e
F ext/rtree/rtree1.test e474a2b5eff231496dbd073fe67e5fbaf7f444c9 F ext/rtree/rtree1.test e474a2b5eff231496dbd073fe67e5fbaf7f444c9
F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba F ext/rtree/rtree2.test acbb3a4ce0f4fbc2c304d2b4b784cfa161856bba
@@ -98,7 +103,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F main.mk a80771d44176a0c744d9d4e048497e7ed0b4040d F main.mk 84ed9c324cf0b8f4eb6f276553d1fd092b5ae0f4
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
@@ -118,16 +123,16 @@ F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c d7fb4c6d2ad3fe51a4ce1a897fde7b00f4de5fef F src/backup.c d7fb4c6d2ad3fe51a4ce1a897fde7b00f4de5fef
F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7 F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c df800f10896bc2ddaa1125c532d6e7a7b9efc532 F src/btree.c f0b71054103cb77eb5e782088c16998ec4f06624
F src/btree.h 48a013f8964f12d944d90e4700df47b72dd6d923 F src/btree.h 48a013f8964f12d944d90e4700df47b72dd6d923
F src/btreeInt.h 38a639c0542c29fe8331a221c4aed0cb8686249e F src/btreeInt.h 38a639c0542c29fe8331a221c4aed0cb8686249e
F src/build.c 6da3a261958d79805df198808b35209e93acf52d F src/build.c 178b24b35ada3688aa63d04cd6a2f972cb481aea
F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33 F src/ctime.c a9c26822515f81ec21588cbb482ca6724be02e33
F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
F src/delete.c 4c20ea4f6213b3bc1c6a510586864b679946e05e F src/delete.c 4c20ea4f6213b3bc1c6a510586864b679946e05e
F src/expr.c eefabaa4a3dc67309a754eb0eab1a163ff4c2bf3 F src/expr.c 06a7733d19dc725dc46ba51afd9feadb4b85d991
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5 F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5
F src/func.c c6b3c94320253a35bda43fb69cc292618e3285d6 F src/func.c c6b3c94320253a35bda43fb69cc292618e3285d6
@@ -140,8 +145,8 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416 F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
F src/main.c 48f47554ccedb2e800aa8f5fb316835a584f709f F src/main.c 41bfe7e14319b44f6322332bce2b48599e524f75
F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97 F src/malloc.c fe085aa851b666b7c375c1ff957643dc20a04bf6
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c b3677415e69603d6a0e7c5410a1b3731d55beda1 F src/mem1.c b3677415e69603d6a0e7c5410a1b3731d55beda1
F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf F src/mem2.c e307323e86b5da1853d7111b68fd6b84ad6f09cf
@@ -159,10 +164,10 @@ F src/os.c e1acdc09ff3ac2412945cca9766e2dcf4675f31c
F src/os.h 59beba555b65a450bd1d804220532971d4299f60 F src/os.h 59beba555b65a450bd1d804220532971d4299f60
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
F src/os_unix.c 424d46e0edab969293c2223f09923b2178171f47 F src/os_unix.c d7c96b5d140f550f07345870112fae5d7ef99757
F src/os_win.c 412d6434133c7c81dc48b7702f3ea5e61c309e5c F src/os_win.c 412d6434133c7c81dc48b7702f3ea5e61c309e5c
F src/pager.c bb5635dde0b152797836d1c72275284724bb563c F src/pager.c 9d4d6406512002d9a243ec27b9c01e93fda43e36
F src/pager.h ef1eaf8593e78f73885c1dfac27ad83bee23bdc5 F src/pager.h 8b8c9bc065a3c66769df8724dfdf492ee1aab3c5
F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099 F src/parse.y f29df90bd3adc64b33114ab1de9fb7768fcf2099
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
@@ -171,13 +176,13 @@ F src/pragma.c 28d7955a9e9a27d41cb462690228d39e3cec231c
F src/prepare.c ef197444dac110ee57a5f49745368b447a8c6bd1 F src/prepare.c ef197444dac110ee57a5f49745368b447a8c6bd1
F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699 F src/printf.c 7ffb4ebb8b341f67e049695ba031da717b3d2699
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/resolve.c 748e75299faff345f34f0e5bd02a2bac8aa69fcd F src/resolve.c b3c70ab28cac60de33684c9aa9e5138dcf71d6dd
F src/rowset.c f6a49f3e9579428024662f6e2931832511f831a1 F src/rowset.c f6a49f3e9579428024662f6e2931832511f831a1
F src/select.c d7b9018b7dd2e821183d69477ab55c39b8272335 F src/select.c f6c4833c4d8e94714761d99013d74f381e084f1d
F src/shell.c 04399b2f9942bd02ed5ffee3b84bcdb39c52a1e6 F src/shell.c c16f72e34f611f060546709564c121a67cb2b31b
F src/sqlite.h.in 4f4d4792f6fb00387c877af013cb09d955643f12 F src/sqlite.h.in 922d2907cc2b0177b2c4a3b462f04937750d6edd
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
F src/sqliteInt.h 05b22e581622128168d786a7c852d1763dd45559 F src/sqliteInt.h 29b5348f0056d9b46d0bb94d4853db21568afde9
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -194,8 +199,8 @@ F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad
F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2 F src/test_btree.c 5b89601dcb42a33ba8b820a6b763cc9cb48bac16
F src/test_config.c 0de329e736eb4aa5845069bed630e5c72f012264 F src/test_config.c d2da9f1490c38d9b9cb52f399b6adb81d538273a
F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094 F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_func.c 090f2c3339e85c2c964435f99aed6f3da9d59525 F src/test_func.c 090f2c3339e85c2c964435f99aed6f3da9d59525
@@ -213,8 +218,8 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25 F src/test_onefile.c 0396f220561f3b4eedc450cef26d40c593c69a25
F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba F src/test_osinst.c 90a845c8183013d80eccb1f29e8805608516edba
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
F src/test_quota.c 9d6be9cd3bb132df2b964193b6a4ec850f50a210 F src/test_quota.c 0af3e1e9a1f22bc5f431dd3efcc32762f4109f58
F src/test_quota.h ee5da2ae7f84d1c8e0e0e2ab33f01d69f10259b5 F src/test_quota.h 8761e463b25e75ebc078bd67d70e39b9c817a0cb
F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9 F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
@@ -234,7 +239,7 @@ F src/update.c d3076782c887c10e882996550345da9c4c9f9dea
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84 F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
F src/util.c 4f6cfad661b2e3454b0cdd5b1b9d39a54942d0e3 F src/util.c 4f6cfad661b2e3454b0cdd5b1b9d39a54942d0e3
F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd F src/vacuum.c 587a52bb8833d7ac15af8916f25437e2575028bd
F src/vdbe.c 6ed3e89957a0dd55e9c4ab7842949051ba8eaaa9 F src/vdbe.c 76ae5ef2a0227681c3808ce20fe2d8b194bac634
F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb F src/vdbe.h 18f581cac1f4339ec3299f3e0cc6e11aec654cdb
F src/vdbeInt.h 6ff4180a05683566a8835d12f7ec504b22932c82 F src/vdbeInt.h 6ff4180a05683566a8835d12f7ec504b22932c82
F src/vdbeapi.c 3662b6a468a2a4605a15dfab313baa6dff81ad91 F src/vdbeapi.c 3662b6a468a2a4605a15dfab313baa6dff81ad91
@@ -242,7 +247,7 @@ F src/vdbeaux.c d52c8a424fdd4b1d5cf1ac93cc7cd20da023ec5c
F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb F src/vdbeblob.c 32f2a4899d67f69634ea4dd93e3f651936d732cb
F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74 F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74
F src/vdbesort.c b25814d385895544ebc8118245c8311ded7f81c9 F src/vdbesort.c b25814d385895544ebc8118245c8311ded7f81c9
F src/vdbetrace.c d6e50e04e1ec498150e519058f617d91b8f5c843 F src/vdbetrace.c 79059ebd17b3c8545fab2a24253713e77e4ab392
F src/vtab.c bb8ea3a26608bb1357538a5d2fc72beba6638998 F src/vtab.c bb8ea3a26608bb1357538a5d2fc72beba6638998
F src/wal.c 7bb3ad807afc7973406c805d5157ec7a2f65e146 F src/wal.c 7bb3ad807afc7973406c805d5157ec7a2f65e146
F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6 F src/wal.h 29c197540b19044e6cd73487017e5e47a1d3dac6
@@ -384,7 +389,7 @@ F test/e_resolve.test dcce9308fb13b934ce29591105d031d3e14fbba6
F test/e_select.test f5d4b81205701deacfae42051ae200969c41d2c0 F test/e_select.test f5d4b81205701deacfae42051ae200969c41d2c0
F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92 F test/e_select2.test 5c3d3da19c7b3e90ae444579db2b70098599ab92
F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c F test/e_update.test 161d5dc6a3ed9dd08f5264d13e20735d7a89f00c
F test/e_uri.test e8b894474fdfe7b18b0c9cb2d911270de2ad64ce F test/e_uri.test cd2ddb4494c7ebf30b6e3539645bb4e54c0104b9
F test/e_vacuum.test 331da289ae186656cf5f2eb27f577a89c0c221af F test/e_vacuum.test 331da289ae186656cf5f2eb27f577a89c0c221af
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
F test/enc2.test 796c59832e2b9a52842f382ffda8f3e989db03ad F test/enc2.test 796c59832e2b9a52842f382ffda8f3e989db03ad
@@ -477,7 +482,7 @@ F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851
F test/fts3expr.test 5e745b2b6348499d9ef8d59015de3182072c564c F test/fts3expr.test 5e745b2b6348499d9ef8d59015de3182072c564c
F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a
F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660 F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660
F test/fts3fault2.test b62a2bc843c20414405f80e5eeb78e39bc68fe53 F test/fts3fault2.test 3198eef2804deea7cac8403e771d9cbcb752d887
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
F test/fts3malloc.test b86ea33db9e8c58c0c2f8027a9fcadaf6a1568be F test/fts3malloc.test b86ea33db9e8c58c0c2f8027a9fcadaf6a1568be
F test/fts3matchinfo.test 6507fe1c342e542300d65ea637d4110eccf894e6 F test/fts3matchinfo.test 6507fe1c342e542300d65ea637d4110eccf894e6
@@ -496,9 +501,11 @@ F test/fts4langid.test 24a6e41063b416bbdf371ff6b4476fa41c194aa7
F test/fts4merge.test c424309743fdd203f8e56a1f1cd7872cd66cc0ee F test/fts4merge.test c424309743fdd203f8e56a1f1cd7872cd66cc0ee
F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7 F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7
F test/fts4unicode.test c812e9cf843e26ba633f58b36a2629f878af20fd
F test/func.test 9809b7622d721904a8cc33c1ffb87f46d506ed01 F test/func.test 9809b7622d721904a8cc33c1ffb87f46d506ed01
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a F test/func3.test 001021e5b88bd02a3b365a5c5fd8f6f49d39744a
F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74
F test/fuzz.test 77fd50afc12847af50fcf1941679d90adebadde6 F test/fuzz.test 77fd50afc12847af50fcf1941679d90adebadde6
F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167
F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5
@@ -635,7 +642,7 @@ F test/pageropt.test 9191867ed19a2b3db6c42d1b36b6fbc657cd1ab0
F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0 F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16 F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/permutations.test dbda172249564f43ec556108a704581044c57dbd F test/permutations.test ea7b6948eaa22993fcfa662eb704ce29ddb24b2a
F test/pragma.test c51c148defe32bf4a419a522f95d26838d5cf677 F test/pragma.test c51c148defe32bf4a419a522f95d26838d5cf677
F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947 F test/pragma2.test 3a55f82b954242c642f8342b17dffc8b47472947
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552 F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
@@ -644,7 +651,7 @@ F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
F test/quota.test c2f778dab4c7fb07bcfa962cc5c762f36d8061dc F test/quota.test c2f778dab4c7fb07bcfa962cc5c762f36d8061dc
F test/quota2.test bc9fdb2e46aace691c1a01a9cc8d097bd4d7c1ab F test/quota2.test 52175f1c94fb01711da38095a7d3988d0c7d6575
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
@@ -682,7 +689,7 @@ F test/selectA.test 06d1032fa9009314c95394f2ca2e60d9f7ae8532
F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25 F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977 F test/selectC.test 871fb55d884d3de5943c4057ebd22c2459e71977
F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118 F test/server1.test 46803bd3fe8b99b30dbc5ff38ffc756f5c13a118
F test/shared.test 34945a516532b11182c3eb26e31247eee3c9ae48 F test/shared.test 64fe647f17b2de0622437829a9e9823c20439fce
F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879
F test/shared3.test ebf77f023f4bdaa8f74f65822b559e86ce5c6257 F test/shared3.test ebf77f023f4bdaa8f74f65822b559e86ce5c6257
F test/shared4.test 72d90821e8d2fc918a08f16d32880868d8ee8e9d F test/shared4.test 72d90821e8d2fc918a08f16d32880868d8ee8e9d
@@ -691,7 +698,7 @@ F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e
F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d F test/shared8.test b27befbefbe7f4517f1d6b7ff8f64a41ec74165d
F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de
F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf
F test/shell1.test cd9f846702d1d471225a988fee590a153be8192c F test/shell1.test 6e3013bc50e2b73f00d17e491f776decc82a71c8
F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a
F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59 F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59
F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
@@ -713,7 +720,7 @@ F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test 08e8185b3fd5b010c90d7ad82b9dd4ea1cbf14b0 F test/stat.test 08e8185b3fd5b010c90d7ad82b9dd4ea1cbf14b0
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9 F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
F test/subquery.test c5e0d183f1ae6251453338a465b32ae11326e0fa F test/subquery.test d4aea23ac267463d4aa604bf937c3992347b20f7
F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
@@ -972,7 +979,7 @@ F tool/mkkeywordhash.c bb52064aa614e1426445e4b2b9b00eeecd23cc79
F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 105023aa86f696a74b1d6a4929d1e1c3baf9471c F tool/mksqlite3c-noext.tcl 105023aa86f696a74b1d6a4929d1e1c3baf9471c
F tool/mksqlite3c.tcl 9fbac513cd9d5ac95ad55630f49bb16c5347ab75 F tool/mksqlite3c.tcl f289ba51f74f45c71a80c13e6c74a6dd92763253
F tool/mksqlite3h.tcl 78013ad79a5e492e5f764f3c7a8ef834255061f8 F tool/mksqlite3h.tcl 78013ad79a5e492e5f764f3c7a8ef834255061f8
F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87 F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091 F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
@@ -998,7 +1005,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh a8a0a3babda96dfb1ff51adda3cbbf3dfb7266c2 F tool/warnings-clang.sh a8a0a3babda96dfb1ff51adda3cbbf3dfb7266c2
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
P 5587c73badc07d3e01a7c5c5964e178b5112dd24 P ea2cd55e098b21cd8997fd6c1978131d3ef2fab4 61669c95859e187618fb2fb4249306a947ae8d26
R c4833805a7760d62c8726aeccbf50a1f R fc7cb647ad4d37ffcdbbdbe50e659acc
U dan U drh
Z 29dbe9b5d386a5757fe1ec7bc83d13ea Z 0c46cbc562d7f9db30fca97ff8d69c33

View File

@@ -1 +1 @@
ea2cd55e098b21cd8997fd6c1978131d3ef2fab4 42338e9e6979bb497823527f8f39e96f63623c59

View File

@@ -1721,7 +1721,8 @@ int sqlite3BtreeOpen(
const int isMemdb = 0; const int isMemdb = 0;
#else #else
const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0)
|| (isTempDb && sqlite3TempInMemory(db)); || (isTempDb && sqlite3TempInMemory(db))
|| (vfsFlags & SQLITE_OPEN_MEMORY)!=0;
#endif #endif
assert( db!=0 ); assert( db!=0 );
@@ -1757,7 +1758,7 @@ int sqlite3BtreeOpen(
** If this Btree is a candidate for shared cache, try to find an ** If this Btree is a candidate for shared cache, try to find an
** existing BtShared object that we can share with ** existing BtShared object that we can share with
*/ */
if( isMemdb==0 && isTempDb==0 ){ if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){
if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
int nFullPathname = pVfs->mxPathname+1; int nFullPathname = pVfs->mxPathname+1;
char *zFullPathname = sqlite3Malloc(nFullPathname); char *zFullPathname = sqlite3Malloc(nFullPathname);
@@ -1767,11 +1768,16 @@ int sqlite3BtreeOpen(
sqlite3_free(p); sqlite3_free(p);
return SQLITE_NOMEM; return SQLITE_NOMEM;
} }
rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); if( isMemdb ){
if( rc ){ memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1);
sqlite3_free(zFullPathname); }else{
sqlite3_free(p); rc = sqlite3OsFullPathname(pVfs, zFilename,
return rc; nFullPathname, zFullPathname);
if( rc ){
sqlite3_free(zFullPathname);
sqlite3_free(p);
return rc;
}
} }
#if SQLITE_THREADSAFE #if SQLITE_THREADSAFE
mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
@@ -1781,7 +1787,7 @@ int sqlite3BtreeOpen(
#endif #endif
for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
assert( pBt->nRef>0 ); assert( pBt->nRef>0 );
if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0))
&& sqlite3PagerVfs(pBt->pPager)==pVfs ){ && sqlite3PagerVfs(pBt->pPager)==pVfs ){
int iDb; int iDb;
for(iDb=db->nDb-1; iDb>=0; iDb--){ for(iDb=db->nDb-1; iDb>=0; iDb--){
@@ -8046,14 +8052,15 @@ char *sqlite3BtreeIntegrityCheck(
#endif /* SQLITE_OMIT_INTEGRITY_CHECK */ #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
/* /*
** Return the full pathname of the underlying database file. ** Return the full pathname of the underlying database file. Return
** an empty string if the database is in-memory or a TEMP database.
** **
** The pager filename is invariant as long as the pager is ** The pager filename is invariant as long as the pager is
** open so it is safe to access without the BtShared mutex. ** open so it is safe to access without the BtShared mutex.
*/ */
const char *sqlite3BtreeGetFilename(Btree *p){ const char *sqlite3BtreeGetFilename(Btree *p){
assert( p->pBt->pPager!=0 ); assert( p->pBt->pPager!=0 );
return sqlite3PagerFilename(p->pBt->pPager); return sqlite3PagerFilename(p->pBt->pPager, 1);
} }
/* /*

View File

@@ -429,10 +429,11 @@ void sqlite3CollapseDatabaseArray(sqlite3 *db){
** TEMP schema. ** TEMP schema.
*/ */
void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ void sqlite3ResetOneSchema(sqlite3 *db, int iDb){
Db *pDb;
assert( iDb<db->nDb ); assert( iDb<db->nDb );
/* Case 1: Reset the single schema identified by iDb */ /* Case 1: Reset the single schema identified by iDb */
Db *pDb = &db->aDb[iDb]; pDb = &db->aDb[iDb];
assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
assert( pDb->pSchema!=0 ); assert( pDb->pSchema!=0 );
sqlite3SchemaClear(pDb->pSchema); sqlite3SchemaClear(pDb->pSchema);
@@ -1508,7 +1509,7 @@ void sqlite3EndTable(
sSrc.a[0].iCursor = -1; sSrc.a[0].iCursor = -1;
sNC.pParse = pParse; sNC.pParse = pParse;
sNC.pSrcList = &sSrc; sNC.pSrcList = &sSrc;
sNC.isCheck = 1; sNC.ncFlags = NC_IsCheck;
pList = p->pCheck; pList = p->pCheck;
for(i=0; i<pList->nExpr; i++){ for(i=0; i<pList->nExpr; i++){
if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){ if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){

View File

@@ -3778,7 +3778,7 @@ int sqlite3ExprCompare(Expr *pA, Expr *pB){
if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){ if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
return 2; return 2;
} }
}else if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2; if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
return 2; return 2;
@@ -3965,7 +3965,9 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
return WRC_Prune; return WRC_Prune;
} }
case TK_AGG_FUNCTION: { case TK_AGG_FUNCTION: {
if( !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList) ){ if( (pNC->ncFlags & NC_InAggFunc)==0
&& !sqlite3FunctionUsesOtherSrc(pExpr, pSrcList)
){
/* Check to see if pExpr is a duplicate of another aggregate /* Check to see if pExpr is a duplicate of another aggregate
** function that is already in the pAggInfo structure ** function that is already in the pAggInfo structure
*/ */
@@ -4002,8 +4004,8 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
ExprSetIrreducible(pExpr); ExprSetIrreducible(pExpr);
pExpr->iAgg = (i16)i; pExpr->iAgg = (i16)i;
pExpr->pAggInfo = pAggInfo; pExpr->pAggInfo = pAggInfo;
return WRC_Prune;
} }
return WRC_Prune;
} }
} }
return WRC_Continue; return WRC_Continue;

View File

@@ -2044,10 +2044,14 @@ int sqlite3ParseUri(
{ "ro", SQLITE_OPEN_READONLY }, { "ro", SQLITE_OPEN_READONLY },
{ "rw", SQLITE_OPEN_READWRITE }, { "rw", SQLITE_OPEN_READWRITE },
{ "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE },
{ "memory",
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
| SQLITE_OPEN_MEMORY },
{ 0, 0 } { 0, 0 }
}; };
mask = SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE
| SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY;
aMode = aOpenMode; aMode = aOpenMode;
limit = mask & flags; limit = mask & flags;
zModeType = "access"; zModeType = "access";
@@ -2068,7 +2072,7 @@ int sqlite3ParseUri(
rc = SQLITE_ERROR; rc = SQLITE_ERROR;
goto parse_uri_out; goto parse_uri_out;
} }
if( mode>limit ){ if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){
*pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s",
zModeType, zVal); zModeType, zVal);
rc = SQLITE_PERM; rc = SQLITE_PERM;
@@ -2087,6 +2091,7 @@ int sqlite3ParseUri(
memcpy(zFile, zUri, nUri); memcpy(zFile, zUri, nUri);
zFile[nUri] = '\0'; zFile[nUri] = '\0';
zFile[nUri+1] = '\0'; zFile[nUri+1] = '\0';
flags &= ~SQLITE_OPEN_URI;
} }
*ppVfs = sqlite3_vfs_find(zVfs); *ppVfs = sqlite3_vfs_find(zVfs);

View File

@@ -491,6 +491,10 @@ void sqlite3DbFree(sqlite3 *db, void *p){
} }
if( isLookaside(db, p) ){ if( isLookaside(db, p) ){
LookasideSlot *pBuf = (LookasideSlot*)p; LookasideSlot *pBuf = (LookasideSlot*)p;
#if SQLITE_DEBUG
/* Trash all content in the buffer being freed */
memset(p, 0xaa, db->lookaside.sz);
#endif
pBuf->pNext = db->lookaside.pFree; pBuf->pNext = db->lookaside.pFree;
db->lookaside.pFree = pBuf; db->lookaside.pFree = pBuf;
db->lookaside.nOut--; db->lookaside.nOut--;

View File

@@ -227,7 +227,7 @@ struct unixFile {
#if OS_VXWORKS #if OS_VXWORKS
struct vxworksFileId *pId; /* Unique file ID */ struct vxworksFileId *pId; /* Unique file ID */
#endif #endif
#ifndef NDEBUG #ifdef SQLITE_DEBUG
/* The next group of variables are used to track whether or not the /* The next group of variables are used to track whether or not the
** transaction counter in bytes 24-27 of database files are updated ** transaction counter in bytes 24-27 of database files are updated
** whenever any part of the database changes. An assertion fault will ** whenever any part of the database changes. An assertion fault will
@@ -262,7 +262,6 @@ struct unixFile {
#define UNIXFILE_DELETE 0x20 /* Delete on close */ #define UNIXFILE_DELETE 0x20 /* Delete on close */
#define UNIXFILE_URI 0x40 /* Filename might have query parameters */ #define UNIXFILE_URI 0x40 /* Filename might have query parameters */
#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */ #define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
#define UNIXFILE_CHOWN 0x100 /* File ownership was changed */
/* /*
** Include code that is common to all os_*.c files ** Include code that is common to all os_*.c files
@@ -308,6 +307,15 @@ static int posixOpen(const char *zFile, int flags, int mode){
return open(zFile, flags, mode); return open(zFile, flags, mode);
} }
/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes. So avoid calling fchown() if
** we are not running as root.
*/
static int posixFchown(int fd, uid_t uid, gid_t gid){
return geteuid() ? 0 : fchown(fd,uid,gid);
}
/* Forward reference */ /* Forward reference */
static int openDirectory(const char*, int*); static int openDirectory(const char*, int*);
@@ -419,7 +427,7 @@ static struct unix_syscall {
{ "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 },
#define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent)
{ "fchown", (sqlite3_syscall_ptr)fchown, 0 }, { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 },
#define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)
{ "umask", (sqlite3_syscall_ptr)umask, 0 }, { "umask", (sqlite3_syscall_ptr)umask, 0 },
@@ -1563,7 +1571,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
} }
#ifndef NDEBUG #ifdef SQLITE_DEBUG
/* Set up the transaction-counter change checking flags when /* Set up the transaction-counter change checking flags when
** transitioning from a SHARED to a RESERVED lock. The change ** transitioning from a SHARED to a RESERVED lock. The change
** from SHARED to RESERVED marks the beginning of a normal ** from SHARED to RESERVED marks the beginning of a normal
@@ -1642,7 +1650,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
if( pFile->eFileLock>SHARED_LOCK ){ if( pFile->eFileLock>SHARED_LOCK ){
assert( pInode->eFileLock==pFile->eFileLock ); assert( pInode->eFileLock==pFile->eFileLock );
#ifndef NDEBUG #ifdef SQLITE_DEBUG
/* When reducing a lock such that other processes can start /* When reducing a lock such that other processes can start
** reading the database file again, make sure that the ** reading the database file again, make sure that the
** transaction counter was updated if any part of the database ** transaction counter was updated if any part of the database
@@ -2841,7 +2849,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
SimulateIOError( h=(-1) ) SimulateIOError( h=(-1) )
SimulateIOErrorBenign(0); SimulateIOErrorBenign(0);
#ifndef NDEBUG #ifdef SQLITE_DEBUG
/* When reducing a lock such that other processes can start /* When reducing a lock such that other processes can start
** reading the database file again, make sure that the ** reading the database file again, make sure that the
** transaction counter was updated if any part of the database ** transaction counter was updated if any part of the database
@@ -3145,7 +3153,7 @@ static int unixWrite(
); );
#endif #endif
#ifndef NDEBUG #ifdef SQLITE_DEBUG
/* If we are doing a normal write to a database file (as opposed to /* If we are doing a normal write to a database file (as opposed to
** doing a hot-journal rollback or a write to some file other than a ** doing a hot-journal rollback or a write to some file other than a
** normal database file) then record the fact that the database ** normal database file) then record the fact that the database
@@ -3436,7 +3444,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
pFile->lastErrno = errno; pFile->lastErrno = errno;
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
}else{ }else{
#ifndef NDEBUG #ifdef SQLITE_DEBUG
/* If we are doing a normal write to a database file (as opposed to /* If we are doing a normal write to a database file (as opposed to
** doing a hot-journal rollback or a write to some file other than a ** doing a hot-journal rollback or a write to some file other than a
** normal database file) and we truncate the file to zero length, ** normal database file) and we truncate the file to zero length,
@@ -3593,7 +3601,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
*(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
return SQLITE_OK; return SQLITE_OK;
} }
#ifndef NDEBUG #ifdef SQLITE_DEBUG
/* The pager calls this method to signal that it has done /* The pager calls this method to signal that it has done
** a rollback and that the database is therefore unchanged and ** a rollback and that the database is therefore unchanged and
** it hence it is OK for the transaction change counter to be ** it hence it is OK for the transaction change counter to be
@@ -3944,14 +3952,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
/* If this process is running as root, make sure that the SHM file /* If this process is running as root, make sure that the SHM file
** is owned by the same user that owns the original database. Otherwise, ** is owned by the same user that owns the original database. Otherwise,
** the original owner will not be able to connect. If this process is ** the original owner will not be able to connect.
** not root, the following fchown() will fail, but we don't care. The
** if(){..} and the UNIXFILE_CHOWN flag are purely to silence compiler
** warnings.
*/ */
if( osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid)==0 ){ osFchown(pShmNode->h, sStat.st_uid, sStat.st_gid);
pDbFd->ctrlFlags |= UNIXFILE_CHOWN;
}
/* Check to see if another process is holding the dead-man switch. /* Check to see if another process is holding the dead-man switch.
** If not, truncate the file to zero length. ** If not, truncate the file to zero length.
@@ -5157,13 +5160,10 @@ static int unixOpen(
/* If this process is running as root and if creating a new rollback /* If this process is running as root and if creating a new rollback
** journal or WAL file, set the ownership of the journal or WAL to be ** journal or WAL file, set the ownership of the journal or WAL to be
** the same as the original database. If we are not running as root, ** the same as the original database.
** then the fchown() call will fail, but that's ok. The "if(){}" and
** the setting of the UNIXFILE_CHOWN flag are purely to silence compiler
** warnings from gcc.
*/ */
if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){ if( flags & (SQLITE_OPEN_WAL|SQLITE_OPEN_MAIN_JOURNAL) ){
if( osFchown(fd, uid, gid)==0 ){ p->ctrlFlags |= UNIXFILE_CHOWN; } osFchown(fd, uid, gid);
} }
} }
assert( fd>=0 ); assert( fd>=0 );

View File

@@ -4360,7 +4360,12 @@ int sqlite3PagerOpen(
#ifndef SQLITE_OMIT_MEMORYDB #ifndef SQLITE_OMIT_MEMORYDB
if( flags & PAGER_MEMORY ){ if( flags & PAGER_MEMORY ){
memDb = 1; memDb = 1;
zFilename = 0; if( zFilename && zFilename[0] ){
zPathname = sqlite3DbStrDup(0, zFilename);
if( zPathname==0 ) return SQLITE_NOMEM;
nPathname = sqlite3Strlen30(zPathname);
zFilename = 0;
}
} }
#endif #endif
@@ -6296,9 +6301,16 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
/* /*
** Return the full pathname of the database file. ** Return the full pathname of the database file.
**
** Except, if the pager is in-memory only, then return an empty string if
** nullIfMemDb is true. This routine is called with nullIfMemDb==1 when
** used to report the filename to the user, for compatibility with legacy
** behavior. But when the Btree needs to know the filename for matching to
** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
** participate in shared-cache.
*/ */
const char *sqlite3PagerFilename(Pager *pPager){ const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
return pPager->zFilename; return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
} }
/* /*

View File

@@ -151,7 +151,7 @@ int sqlite3PagerCloseWal(Pager *pPager);
u8 sqlite3PagerIsreadonly(Pager*); u8 sqlite3PagerIsreadonly(Pager*);
int sqlite3PagerRefcount(Pager*); int sqlite3PagerRefcount(Pager*);
int sqlite3PagerMemUsed(Pager*); int sqlite3PagerMemUsed(Pager*);
const char *sqlite3PagerFilename(Pager*); const char *sqlite3PagerFilename(Pager*, int);
const sqlite3_vfs *sqlite3PagerVfs(Pager*); const sqlite3_vfs *sqlite3PagerVfs(Pager*);
sqlite3_file *sqlite3PagerFile(Pager*); sqlite3_file *sqlite3PagerFile(Pager*);
const char *sqlite3PagerJournalname(Pager*); const char *sqlite3PagerJournalname(Pager*);

View File

@@ -311,7 +311,7 @@ static int lookupName(
assert( pExpr->x.pList==0 ); assert( pExpr->x.pList==0 );
assert( pExpr->x.pSelect==0 ); assert( pExpr->x.pSelect==0 );
pOrig = pEList->a[j].pExpr; pOrig = pEList->a[j].pExpr;
if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){ if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
return WRC_Abort; return WRC_Abort;
} }
@@ -556,7 +556,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
} }
} }
#endif #endif
if( is_agg && !pNC->allowAgg ){ if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId); sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
pNC->nErr++; pNC->nErr++;
is_agg = 0; is_agg = 0;
@@ -570,11 +570,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
} }
if( is_agg ){ if( is_agg ){
pExpr->op = TK_AGG_FUNCTION; pExpr->op = TK_AGG_FUNCTION;
pNC->hasAgg = 1; pNC->ncFlags |= NC_HasAgg;
} }
if( is_agg ) pNC->allowAgg = 0; if( is_agg ) pNC->ncFlags &= ~NC_AllowAgg;
sqlite3WalkExprList(pWalker, pList); sqlite3WalkExprList(pWalker, pList);
if( is_agg ) pNC->allowAgg = 1; if( is_agg ) pNC->ncFlags |= NC_AllowAgg;
/* FIX ME: Compute pExpr->affinity based on the expected return /* FIX ME: Compute pExpr->affinity based on the expected return
** type of the function ** type of the function
*/ */
@@ -589,7 +589,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
if( ExprHasProperty(pExpr, EP_xIsSelect) ){ if( ExprHasProperty(pExpr, EP_xIsSelect) ){
int nRef = pNC->nRef; int nRef = pNC->nRef;
#ifndef SQLITE_OMIT_CHECK #ifndef SQLITE_OMIT_CHECK
if( pNC->isCheck ){ if( (pNC->ncFlags & NC_IsCheck)!=0 ){
sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints"); sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
} }
#endif #endif
@@ -603,7 +603,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
} }
#ifndef SQLITE_OMIT_CHECK #ifndef SQLITE_OMIT_CHECK
case TK_VARIABLE: { case TK_VARIABLE: {
if( pNC->isCheck ){ if( (pNC->ncFlags & NC_IsCheck)!=0 ){
sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints"); sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
} }
break; break;
@@ -685,7 +685,7 @@ static int resolveOrderByTermToExprList(
nc.pParse = pParse; nc.pParse = pParse;
nc.pSrcList = pSelect->pSrc; nc.pSrcList = pSelect->pSrc;
nc.pEList = pEList; nc.pEList = pEList;
nc.allowAgg = 1; nc.ncFlags = NC_AllowAgg;
nc.nErr = 0; nc.nErr = 0;
db = pParse->db; db = pParse->db;
savedSuppErr = db->suppressErr; savedSuppErr = db->suppressErr;
@@ -987,7 +987,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to /* Set up the local name-context to pass to sqlite3ResolveExprNames() to
** resolve the result-set expression list. ** resolve the result-set expression list.
*/ */
sNC.allowAgg = 1; sNC.ncFlags = NC_AllowAgg;
sNC.pSrcList = p->pSrc; sNC.pSrcList = p->pSrc;
sNC.pNext = pOuterNC; sNC.pNext = pOuterNC;
@@ -1033,10 +1033,10 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
*/ */
assert( (p->selFlags & SF_Aggregate)==0 ); assert( (p->selFlags & SF_Aggregate)==0 );
pGroupBy = p->pGroupBy; pGroupBy = p->pGroupBy;
if( pGroupBy || sNC.hasAgg ){ if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){
p->selFlags |= SF_Aggregate; p->selFlags |= SF_Aggregate;
}else{ }else{
sNC.allowAgg = 0; sNC.ncFlags &= ~NC_AllowAgg;
} }
/* If a HAVING clause is present, then there must be a GROUP BY clause. /* If a HAVING clause is present, then there must be a GROUP BY clause.
@@ -1065,7 +1065,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** outer queries ** outer queries
*/ */
sNC.pNext = 0; sNC.pNext = 0;
sNC.allowAgg = 1; sNC.ncFlags |= NC_AllowAgg;
/* Process the ORDER BY clause for singleton SELECT statements. /* Process the ORDER BY clause for singleton SELECT statements.
** The ORDER BY clause for compounds SELECT statements is handled ** The ORDER BY clause for compounds SELECT statements is handled
@@ -1153,7 +1153,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
** **
** Function calls are checked to make sure that the function is ** Function calls are checked to make sure that the function is
** defined and that the correct number of arguments are specified. ** defined and that the correct number of arguments are specified.
** If the function is an aggregate function, then the pNC->hasAgg is ** If the function is an aggregate function, then the NC_HasAgg flag is
** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION. ** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION.
** If an expression contains aggregate functions then the EP_Agg ** If an expression contains aggregate functions then the EP_Agg
** property on the expression is set. ** property on the expression is set.
@@ -1165,7 +1165,7 @@ int sqlite3ResolveExprNames(
NameContext *pNC, /* Namespace to resolve expressions in. */ NameContext *pNC, /* Namespace to resolve expressions in. */
Expr *pExpr /* The expression to be analyzed. */ Expr *pExpr /* The expression to be analyzed. */
){ ){
int savedHasAgg; u8 savedHasAgg;
Walker w; Walker w;
if( pExpr==0 ) return 0; if( pExpr==0 ) return 0;
@@ -1178,8 +1178,8 @@ int sqlite3ResolveExprNames(
pParse->nHeight += pExpr->nHeight; pParse->nHeight += pExpr->nHeight;
} }
#endif #endif
savedHasAgg = pNC->hasAgg; savedHasAgg = pNC->ncFlags & NC_HasAgg;
pNC->hasAgg = 0; pNC->ncFlags &= ~NC_HasAgg;
w.xExprCallback = resolveExprStep; w.xExprCallback = resolveExprStep;
w.xSelectCallback = resolveSelectStep; w.xSelectCallback = resolveSelectStep;
w.pParse = pNC->pParse; w.pParse = pNC->pParse;
@@ -1191,10 +1191,10 @@ int sqlite3ResolveExprNames(
if( pNC->nErr>0 || w.pParse->nErr>0 ){ if( pNC->nErr>0 || w.pParse->nErr>0 ){
ExprSetProperty(pExpr, EP_Error); ExprSetProperty(pExpr, EP_Error);
} }
if( pNC->hasAgg ){ if( pNC->ncFlags & NC_HasAgg ){
ExprSetProperty(pExpr, EP_Agg); ExprSetProperty(pExpr, EP_Agg);
}else if( savedHasAgg ){ }else if( savedHasAgg ){
pNC->hasAgg = 1; pNC->ncFlags |= NC_HasAgg;
} }
return ExprHasProperty(pExpr, EP_Error); return ExprHasProperty(pExpr, EP_Error);
} }

View File

@@ -3149,6 +3149,7 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
if( IsVirtual(pTab) ) return 0; if( IsVirtual(pTab) ) return 0;
if( pExpr->op!=TK_AGG_FUNCTION ) return 0; if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
if( pAggInfo->nFunc==0 ) return 0;
if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0; if( (pAggInfo->aFunc[0].pFunc->flags&SQLITE_FUNC_COUNT)==0 ) return 0;
if( pExpr->flags&EP_Distinct ) return 0; if( pExpr->flags&EP_Distinct ) return 0;
@@ -4139,7 +4140,9 @@ int sqlite3Select(
sAggInfo.nAccumulator = sAggInfo.nColumn; sAggInfo.nAccumulator = sAggInfo.nColumn;
for(i=0; i<sAggInfo.nFunc; i++){ for(i=0; i<sAggInfo.nFunc; i++){
assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) ); assert( !ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_xIsSelect) );
sNC.ncFlags |= NC_InAggFunc;
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList); sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
sNC.ncFlags &= ~NC_InAggFunc;
} }
if( db->mallocFailed ) goto select_end; if( db->mallocFailed ) goto select_end;

View File

@@ -2184,23 +2184,25 @@ static int do_meta_command(char *zLine, struct callback_data *p){
zShellStatic = azArg[1]; zShellStatic = azArg[1];
rc = sqlite3_exec(p->db, rc = sqlite3_exec(p->db,
"SELECT sql FROM " "SELECT sql FROM "
" (SELECT sql sql, type type, tbl_name tbl_name, name name" " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
" FROM sqlite_master UNION ALL" " FROM sqlite_master UNION ALL"
" SELECT sql, type, tbl_name, name FROM sqlite_temp_master) " " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
"WHERE lower(tbl_name) LIKE shellstatic()" "WHERE lower(tbl_name) LIKE shellstatic()"
" AND type!='meta' AND sql NOTNULL " " AND type!='meta' AND sql NOTNULL "
"ORDER BY substr(type,2,1), name", "ORDER BY substr(type,2,1), "
" CASE type WHEN 'view' THEN rowid ELSE name END",
callback, &data, &zErrMsg); callback, &data, &zErrMsg);
zShellStatic = 0; zShellStatic = 0;
} }
}else{ }else{
rc = sqlite3_exec(p->db, rc = sqlite3_exec(p->db,
"SELECT sql FROM " "SELECT sql FROM "
" (SELECT sql sql, type type, tbl_name tbl_name, name name" " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
" FROM sqlite_master UNION ALL" " FROM sqlite_master UNION ALL"
" SELECT sql, type, tbl_name, name FROM sqlite_temp_master) " " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
"WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'" "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
"ORDER BY substr(type,2,1), name", "ORDER BY substr(type,2,1),"
" CASE type WHEN 'view' THEN rowid ELSE name END",
callback, &data, &zErrMsg callback, &data, &zErrMsg
); );
} }

View File

@@ -473,6 +473,7 @@ int sqlite3_exec(
#define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */
#define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */
#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */
#define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */
#define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */
#define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */
@@ -2570,18 +2571,20 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
** present, then the VFS specified by the option takes precedence over ** present, then the VFS specified by the option takes precedence over
** the value passed as the fourth parameter to sqlite3_open_v2(). ** the value passed as the fourth parameter to sqlite3_open_v2().
** **
** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw" or ** <li> <b>mode</b>: ^(The mode parameter may be set to either "ro", "rw",
** "rwc". Attempting to set it to any other value is an error)^. ** "rwc", or "memory". Attempting to set it to any other value is
** an error)^.
** ^If "ro" is specified, then the database is opened for read-only ** ^If "ro" is specified, then the database is opened for read-only
** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the ** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the
** third argument to sqlite3_prepare_v2(). ^If the mode option is set to ** third argument to sqlite3_prepare_v2(). ^If the mode option is set to
** "rw", then the database is opened for read-write (but not create) ** "rw", then the database is opened for read-write (but not create)
** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had ** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had
** been set. ^Value "rwc" is equivalent to setting both ** been set. ^Value "rwc" is equivalent to setting both
** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If sqlite3_open_v2() is ** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is
** used, it is an error to specify a value for the mode parameter that is ** set to "memory" then a pure [in-memory database] that never reads
** less restrictive than that specified by the flags passed as the third ** or writes from disk is used. ^It is an error to specify a value for
** parameter. ** the mode parameter that is less restrictive than that specified by
** the flags passed in the third parameter to sqlite3_open_v2().
** **
** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or ** <li> <b>cache</b>: ^The cache parameter may be set to either "shared" or
** "private". ^Setting it to "shared" is equivalent to setting the ** "private". ^Setting it to "shared" is equivalent to setting the
@@ -4622,7 +4625,6 @@ void *sqlite3_update_hook(
/* /*
** CAPI3REF: Enable Or Disable Shared Pager Cache ** CAPI3REF: Enable Or Disable Shared Pager Cache
** KEYWORDS: {shared cache}
** **
** ^(This routine enables or disables the sharing of the database cache ** ^(This routine enables or disables the sharing of the database cache
** and schema data structures between [database connection | connections] ** and schema data structures between [database connection | connections]

View File

@@ -203,15 +203,22 @@
#endif #endif
/* /*
** Many people are failing to set -DNDEBUG=1 when compiling SQLite. ** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that
** Setting NDEBUG makes the code smaller and run faster. So the following ** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true,
** lines are added to automatically set NDEBUG unless the -DSQLITE_DEBUG=1 ** make it true by defining or undefining NDEBUG.
** option is set. Thus NDEBUG becomes an opt-in rather than an opt-out **
** Setting NDEBUG makes the code smaller and run faster by disabling the
** number assert() statements in the code. So we want the default action
** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG
** is set. Thus NDEBUG becomes an opt-in rather than an opt-out
** feature. ** feature.
*/ */
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) #if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1 # define NDEBUG 1
#endif #endif
#if defined(NDEBUG) && defined(SQLITE_DEBUG)
# undef NDEBUG
#endif
/* /*
** The testcase() macro is used to aid in coverage testing. When ** The testcase() macro is used to aid in coverage testing. When
@@ -2006,15 +2013,21 @@ struct NameContext {
Parse *pParse; /* The parser */ Parse *pParse; /* The parser */
SrcList *pSrcList; /* One or more tables used to resolve names */ SrcList *pSrcList; /* One or more tables used to resolve names */
ExprList *pEList; /* Optional list of named expressions */ ExprList *pEList; /* Optional list of named expressions */
int nRef; /* Number of names resolved by this context */
int nErr; /* Number of errors encountered while resolving names */
u8 allowAgg; /* Aggregate functions allowed here */
u8 hasAgg; /* True if aggregates are seen */
u8 isCheck; /* True if resolving names in a CHECK constraint */
AggInfo *pAggInfo; /* Information about aggregates at this level */ AggInfo *pAggInfo; /* Information about aggregates at this level */
NameContext *pNext; /* Next outer name context. NULL for outermost */ NameContext *pNext; /* Next outer name context. NULL for outermost */
int nRef; /* Number of names resolved by this context */
int nErr; /* Number of errors encountered while resolving names */
u8 ncFlags; /* Zero or more NC_* flags defined below */
}; };
/*
** Allowed values for the NameContext, ncFlags field.
*/
#define NC_AllowAgg 0x01 /* Aggregate functions are allowed here */
#define NC_HasAgg 0x02 /* One or more aggregate functions seen */
#define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */
#define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */
/* /*
** An instance of the following structure contains all information ** An instance of the following structure contains all information
** needed to generate code for a single SELECT statement. ** needed to generate code for a single SELECT statement.

View File

@@ -33,7 +33,7 @@ int sqlite3BtreeSharedCacheReport(
BtShared *pBt; BtShared *pBt;
Tcl_Obj *pRet = Tcl_NewObj(); Tcl_Obj *pRet = Tcl_NewObj();
for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
const char *zFile = sqlite3PagerFilename(pBt->pPager); const char *zFile = sqlite3PagerFilename(pBt->pPager, 1);
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1)); Tcl_ListObjAppendElement(interp, pRet, Tcl_NewStringObj(zFile, -1));
Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef)); Tcl_ListObjAppendElement(interp, pRet, Tcl_NewIntObj(pBt->nRef));
} }

View File

@@ -307,6 +307,12 @@ static void set_options(Tcl_Interp *interp){
Tcl_SetVar2(interp, "sqlite_options", "fts3", "0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "fts3", "0", TCL_GLOBAL_ONLY);
#endif #endif
#if !defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_DISABLE_FTS3_UNICODE)
Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "0", TCL_GLOBAL_ONLY);
#else
Tcl_SetVar2(interp, "sqlite_options", "fts3_unicode", "1", TCL_GLOBAL_ONLY);
#endif
#ifdef SQLITE_OMIT_GET_TABLE #ifdef SQLITE_OMIT_GET_TABLE
Tcl_SetVar2(interp, "sqlite_options", "gettable", "0", TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "sqlite_options", "gettable", "0", TCL_GLOBAL_ONLY);
#else #else

View File

@@ -45,6 +45,62 @@
#endif /* SQLITE_THREADSAFE==0 */ #endif /* SQLITE_THREADSAFE==0 */
/*
** Figure out if we are dealing with Unix, Windows, or some other
** operating system. After the following block of preprocess macros,
** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER
** will defined to either 1 or 0. One of the four will be 1. The other
** three will be 0.
*/
#if defined(SQLITE_OS_OTHER)
# if SQLITE_OS_OTHER==1
# undef SQLITE_OS_UNIX
# define SQLITE_OS_UNIX 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# undef SQLITE_OS_OS2
# define SQLITE_OS_OS2 0
# else
# undef SQLITE_OS_OTHER
# endif
#endif
#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
# define SQLITE_OS_OTHER 0
# ifndef SQLITE_OS_WIN
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) \
|| defined(__MINGW32__) || defined(__BORLANDC__)
# define SQLITE_OS_WIN 1
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 0
# elif defined(__EMX__) || defined(_OS2) || defined(OS2) \
|| defined(_OS2_) || defined(__OS2__)
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 1
# else
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 1
# define SQLITE_OS_OS2 0
# endif
# else
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 0
# endif
#else
# ifndef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# endif
#endif
#if SQLITE_OS_UNIX
# include <unistd.h>
#endif
#if SQLITE_OS_WIN
# include <windows.h>
# include <io.h>
#endif
/************************ Object Definitions ******************************/ /************************ Object Definitions ******************************/
/* Forward declaration of all object types */ /* Forward declaration of all object types */
@@ -359,62 +415,6 @@ static quotaFile *quotaFindFile(
} }
return pFile; return pFile;
} }
/*
** Figure out if we are dealing with Unix, Windows, or some other
** operating system. After the following block of preprocess macros,
** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER
** will defined to either 1 or 0. One of the four will be 1. The other
** three will be 0.
*/
#if defined(SQLITE_OS_OTHER)
# if SQLITE_OS_OTHER==1
# undef SQLITE_OS_UNIX
# define SQLITE_OS_UNIX 0
# undef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# undef SQLITE_OS_OS2
# define SQLITE_OS_OS2 0
# else
# undef SQLITE_OS_OTHER
# endif
#endif
#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
# define SQLITE_OS_OTHER 0
# ifndef SQLITE_OS_WIN
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) \
|| defined(__MINGW32__) || defined(__BORLANDC__)
# define SQLITE_OS_WIN 1
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 0
# elif defined(__EMX__) || defined(_OS2) || defined(OS2) \
|| defined(_OS2_) || defined(__OS2__)
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 1
# else
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 1
# define SQLITE_OS_OS2 0
# endif
# else
# define SQLITE_OS_UNIX 0
# define SQLITE_OS_OS2 0
# endif
#else
# ifndef SQLITE_OS_WIN
# define SQLITE_OS_WIN 0
# endif
#endif
#if SQLITE_OS_UNIX
# include <unistd.h>
#endif
#if SQLITE_OS_WIN
# include <windows.h>
# include <io.h>
#endif
/* /*
** Translate UTF8 to MBCS for use in fopen() calls. Return a pointer to the ** Translate UTF8 to MBCS for use in fopen() calls. Return a pointer to the
** translated text.. Call quota_mbcs_free() to deallocate any memory ** translated text.. Call quota_mbcs_free() to deallocate any memory
@@ -1042,7 +1042,7 @@ size_t sqlite3_quota_fread(
** the write if we exceed quota. ** the write if we exceed quota.
*/ */
size_t sqlite3_quota_fwrite( size_t sqlite3_quota_fwrite(
void *pBuf, /* Take content to write from here */ const void *pBuf, /* Take content to write from here */
size_t size, /* Size of each element */ size_t size, /* Size of each element */
size_t nmemb, /* Number of elements */ size_t nmemb, /* Number of elements */
quota_FILE *p /* Write to this quota_FILE objecct */ quota_FILE *p /* Write to this quota_FILE objecct */
@@ -1160,6 +1160,13 @@ long sqlite3_quota_ftell(quota_FILE *p){
return ftell(p->f); return ftell(p->f);
} }
/*
** Test the error indicator for the given file.
*/
int sqlite3_quota_ferror(quota_FILE *p){
return ferror(p->f);
}
/* /*
** Truncate a file to szNew bytes. ** Truncate a file to szNew bytes.
*/ */
@@ -1237,6 +1244,25 @@ sqlite3_int64 sqlite3_quota_file_size(quota_FILE *p){
return p->pFile ? p->pFile->iSize : -1; return p->pFile ? p->pFile->iSize : -1;
} }
/*
** Determine the amount of data in bytes available for reading
** in the given file.
*/
long sqlite3_quota_file_available(quota_FILE *p){
FILE* f = p->f;
long pos1, pos2;
int rc;
pos1 = ftell(f);
if ( pos1 < 0 ) return -1;
rc = fseek(f, 0, SEEK_END);
if ( rc != 0 ) return -1;
pos2 = ftell(f);
if ( pos2 < 0 ) return -1;
rc = fseek(f, pos1, SEEK_SET);
if ( rc != 0 ) return -1;
return pos2 - pos1;
}
/* /*
** Remove a managed file. Update quotas accordingly. ** Remove a managed file. Update quotas accordingly.
*/ */
@@ -1895,6 +1921,53 @@ static int test_quota_glob(
return TCL_OK; return TCL_OK;
} }
/*
** tclcmd: sqlite3_quota_file_available HANDLE
**
** Return the number of bytes from the current file point to the end of
** the file.
*/
static int test_quota_file_available(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
quota_FILE *p;
sqlite3_int64 x;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
return TCL_ERROR;
}
p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
x = sqlite3_quota_file_available(p);
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
return TCL_OK;
}
/*
** tclcmd: sqlite3_quota_ferror HANDLE
**
** Return true if the file handle is in the error state.
*/
static int test_quota_ferror(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
quota_FILE *p;
int x;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
return TCL_ERROR;
}
p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
x = sqlite3_quota_ferror(p);
Tcl_SetObjResult(interp, Tcl_NewIntObj(x));
return TCL_OK;
}
/* /*
** This routine registers the custom TCL commands defined in this ** This routine registers the custom TCL commands defined in this
** module. This should be the only procedure visible from outside ** module. This should be the only procedure visible from outside
@@ -1924,6 +1997,8 @@ int Sqlitequota_Init(Tcl_Interp *interp){
{ "sqlite3_quota_file_mtime", test_quota_file_mtime }, { "sqlite3_quota_file_mtime", test_quota_file_mtime },
{ "sqlite3_quota_remove", test_quota_remove }, { "sqlite3_quota_remove", test_quota_remove },
{ "sqlite3_quota_glob", test_quota_glob }, { "sqlite3_quota_glob", test_quota_glob },
{ "sqlite3_quota_file_available",test_quota_file_available },
{ "sqlite3_quota_ferror", test_quota_ferror },
}; };
int i; int i;

View File

@@ -162,7 +162,7 @@ quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode);
** the sum of sizes of all files from going over quota. ** the sum of sizes of all files from going over quota.
*/ */
size_t sqlite3_quota_fread(void*, size_t, size_t, quota_FILE*); size_t sqlite3_quota_fread(void*, size_t, size_t, quota_FILE*);
size_t sqlite3_quota_fwrite(void*, size_t, size_t, quota_FILE*); size_t sqlite3_quota_fwrite(const void*, size_t, size_t, quota_FILE*);
/* /*
** Flush all written content held in memory buffers out to disk. ** Flush all written content held in memory buffers out to disk.
@@ -190,6 +190,13 @@ int sqlite3_quota_fseek(quota_FILE*, long, int);
void sqlite3_quota_rewind(quota_FILE*); void sqlite3_quota_rewind(quota_FILE*);
long sqlite3_quota_ftell(quota_FILE*); long sqlite3_quota_ftell(quota_FILE*);
/*
** Test the error indicator for the given file.
**
** Return non-zero if the error indicator is set.
*/
int sqlite3_quota_ferror(quota_FILE*);
/* /*
** Truncate a file previously opened by sqlite3_quota_fopen(). Return ** Truncate a file previously opened by sqlite3_quota_fopen(). Return
** zero on success and non-zero on any kind of failure. ** zero on success and non-zero on any kind of failure.
@@ -198,7 +205,7 @@ long sqlite3_quota_ftell(quota_FILE*);
** Any attempt to "truncate" a file to a larger size results in ** Any attempt to "truncate" a file to a larger size results in
** undefined behavior. ** undefined behavior.
*/ */
int sqlite3_quota_ftrunate(quota_FILE*, sqlite3_int64 newSize); int sqlite3_quota_ftruncate(quota_FILE*, sqlite3_int64 newSize);
/* /*
** Return the last modification time of the opened file, in seconds ** Return the last modification time of the opened file, in seconds
@@ -232,6 +239,14 @@ sqlite3_int64 sqlite3_quota_file_size(quota_FILE*);
*/ */
sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE*); sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE*);
/*
** Determine the amount of data in bytes available for reading
** in the given file.
**
** Return -1 if the amount cannot be determined for some reason.
*/
long sqlite3_quota_file_available(quota_FILE*);
/* /*
** Delete a file from the disk, if that file is under quota management. ** Delete a file from the disk, if that file is under quota management.
** Adjust quotas accordingly. ** Adjust quotas accordingly.

View File

@@ -5511,7 +5511,7 @@ case OP_JournalMode: { /* out2-prerelease */
if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld; if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld;
#ifndef SQLITE_OMIT_WAL #ifndef SQLITE_OMIT_WAL
zFilename = sqlite3PagerFilename(pPager); zFilename = sqlite3PagerFilename(pPager, 1);
/* Do not allow a transition to journal_mode=WAL for a database /* Do not allow a transition to journal_mode=WAL for a database
** in temporary storage or if the VFS does not support shared memory ** in temporary storage or if the VFS does not support shared memory

View File

@@ -167,8 +167,9 @@ char *sqlite3VdbeExpandSql(
*/ */
void sqlite3ExplainBegin(Vdbe *pVdbe){ void sqlite3ExplainBegin(Vdbe *pVdbe){
if( pVdbe ){ if( pVdbe ){
Explain *p;
sqlite3BeginBenignMalloc(); sqlite3BeginBenignMalloc();
Explain *p = sqlite3_malloc( sizeof(Explain) ); p = sqlite3_malloc( sizeof(Explain) );
if( p ){ if( p ){
memset(p, 0, sizeof(*p)); memset(p, 0, sizeof(*p));
p->pVdbe = pVdbe; p->pVdbe = pVdbe;

View File

@@ -254,6 +254,8 @@ foreach {tn uri error} "
4 {file:test.db?mode=Ro} {no such access mode: Ro} 4 {file:test.db?mode=Ro} {no such access mode: Ro}
5 {file:test.db?mode=Rw} {no such access mode: Rw} 5 {file:test.db?mode=Rw} {no such access mode: Rw}
6 {file:test.db?mode=Rwc} {no such access mode: Rwc} 6 {file:test.db?mode=Rwc} {no such access mode: Rwc}
7 {file:test.db?mode=memory} {not an error}
8 {file:test.db?mode=MEMORY} {no such access mode: MEMORY}
" { " {
do_test 7.$tn { open_uri_error $uri } $error do_test 7.$tn { open_uri_error $uri } $error
} }

View File

@@ -131,4 +131,28 @@ do_faultsim_test 4.1 -prep {
faultsim_test_result {0 {}} faultsim_test_result {0 {}}
} }
ifcapable fts3_unicode {
do_test 5.0 {
faultsim_delete_and_reopen
execsql {
CREATE VIRTUAL TABLE ft USING fts4(a, tokenize=unicode61);
}
faultsim_save_and_close
} {}
do_faultsim_test 5.1 -faults oom* -prep {
faultsim_restore_and_reopen
db eval {SELECT * FROM sqlite_master}
} -body {
execsql { INSERT INTO ft VALUES('the quick brown fox'); }
execsql { INSERT INTO ft VALUES(
'theunusuallylongtokenthatjustdragsonandonandonandthendragsonsomemoreeof'
);
}
execsql { SELECT docid FROM ft WHERE ft MATCH 'th*' }
} -test {
faultsim_test_result {0 {1 2}}
}
}
finish_test finish_test

227
test/fts4unicode.test Normal file
View File

@@ -0,0 +1,227 @@
# 2012 May 25
#
# 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.
#
#*************************************************************************
#
# The tests in this file focus on testing the "unicode" FTS tokenizer.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !fts3_unicode { finish_test ; return }
set ::testprefix fts4unicode
proc do_unicode_token_test {tn input res} {
set input [string map {' ''} $input]
uplevel [list do_execsql_test $tn "
SELECT fts3_tokenizer_test('unicode61', '$input');
" [list [list {*}$res]]]
}
do_unicode_token_test 1.0 {a B c D} {0 a a 1 b B 2 c c 3 d D}
do_unicode_token_test 1.1 {<7B> <20> <20>} {0 <20> <20> 1 <20> <20> 2 <20> <20>}
do_unicode_token_test 1.2 {x<>x x<>x x<>x} {0 x<>x x<>x 1 x<>x x<>x 2 x<>x x<>x}
# 0x00DF is a small "sharp s". 0x1E9E is a capital sharp s.
do_unicode_token_test 1.3 "\uDF" "0 \uDF \uDF"
do_unicode_token_test 1.4 "\u1E9E" "0 <20> \u1E9E"
do_unicode_token_test 1.5 "\u1E9E" "0 \uDF \u1E9E"
do_unicode_token_test 1.6 "The quick brown fox" {
0 the The 1 quick quick 2 brown brown 3 fox fox
}
do_unicode_token_test 1.7 "The\u00bfquick\u224ebrown\u2263fox" {
0 the The 1 quick quick 2 brown brown 3 fox fox
}
#-------------------------------------------------------------------------
#
set docs [list {
Enhance the INSERT syntax to allow multiple rows to be inserted via the
VALUES clause.
} {
Enhance the CREATE VIRTUAL TABLE command to support the IF NOT EXISTS clause.
} {
Added the sqlite3_stricmp() interface as a counterpart to sqlite3_strnicmp().
} {
Added the sqlite3_db_readonly() interface.
} {
Added the SQLITE_FCNTL_PRAGMA file control, giving VFS implementations the
ability to add new PRAGMA statements or to override built-in PRAGMAs.
} {
Queries of the form: "SELECT max(x), y FROM table" returns the value of y on
the same row that contains the maximum x value.
} {
Added support for the FTS4 languageid option.
} {
Documented support for the FTS4 content option. This feature has actually
been in the code since version 3.7.9 but is only now considered to be
officially supported.
} {
Pending statements no longer block ROLLBACK. Instead, the pending statement
will return SQLITE_ABORT upon next access after the ROLLBACK.
} {
Improvements to the handling of CSV inputs in the command-line shell
} {
Fix a bug introduced in version 3.7.10 that might cause a LEFT JOIN to be
incorrectly converted into an INNER JOIN if the WHERE clause indexable terms
connected by OR.
}]
set map(a) [list "\u00C4" "\u00E4"] ; # LATIN LETTER A WITH DIAERESIS
set map(e) [list "\u00CB" "\u00EB"] ; # LATIN LETTER E WITH DIAERESIS
set map(i) [list "\u00CF" "\u00EF"] ; # LATIN LETTER I WITH DIAERESIS
set map(o) [list "\u00D6" "\u00F6"] ; # LATIN LETTER O WITH DIAERESIS
set map(u) [list "\u00DC" "\u00FC"] ; # LATIN LETTER U WITH DIAERESIS
set map(y) [list "\u0178" "\u00FF"] ; # LATIN LETTER Y WITH DIAERESIS
set map(h) [list "\u1E26" "\u1E27"] ; # LATIN LETTER H WITH DIAERESIS
set map(w) [list "\u1E84" "\u1E85"] ; # LATIN LETTER W WITH DIAERESIS
set map(x) [list "\u1E8C" "\u1E8D"] ; # LATIN LETTER X WITH DIAERESIS
foreach k [array names map] {
lappend mappings [string toupper $k] [lindex $map($k) 0]
lappend mappings $k [lindex $map($k) 1]
}
proc mapdoc {doc} {
set doc [regsub -all {[[:space:]]+} $doc " "]
string map $::mappings [string trim $doc]
}
do_test 2.0 {
execsql { CREATE VIRTUAL TABLE t2 USING fts4(tokenize=unicode61, x); }
foreach doc $docs {
set d [mapdoc $doc]
execsql { INSERT INTO t2 VALUES($d) }
}
} {}
do_test 2.1 {
set q [mapdoc "row"]
execsql { SELECT * FROM t2 WHERE t2 MATCH $q }
} [list [mapdoc {
Queries of the form: "SELECT max(x), y FROM table" returns the value of y on
the same row that contains the maximum x value.
}]]
foreach {tn query snippet} {
2 "row" {
...returns the value of y on the same [row] that contains
the maximum x value.
}
3 "ROW" {
...returns the value of y on the same [row] that contains
the maximum x value.
}
4 "rollback" {
...[ROLLBACK]. Instead, the pending statement
will return SQLITE_ABORT upon next access after the [ROLLBACK].
}
5 "rOllback" {
...[ROLLBACK]. Instead, the pending statement
will return SQLITE_ABORT upon next access after the [ROLLBACK].
}
6 "lang*" {
Added support for the FTS4 [languageid] option.
}
} {
do_test 2.$tn {
set q [mapdoc $query]
execsql { SELECT snippet(t2, '[', ']', '...') FROM t2 WHERE t2 MATCH $q }
} [list [mapdoc $snippet]]
}
#-------------------------------------------------------------------------
# Make sure the unicode61 tokenizer does not crash if it is passed a
# NULL pointer.
reset_db
do_execsql_test 3.1 {
CREATE VIRTUAL TABLE t1 USING fts4(tokenize=unicode61, x, y);
INSERT INTO t1 VALUES(NULL, 'a b c');
}
do_execsql_test 3.2 {
SELECT snippet(t1, '[', ']') FROM t1 WHERE t1 MATCH 'b'
} {{a [b] c}}
do_execsql_test 3.3 {
BEGIN;
DELETE FROM t1;
INSERT INTO t1 VALUES('b b b b b b b b b b b', 'b b b b b b b b b b b b b');
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 SELECT * FROM t1;
INSERT INTO t1 VALUES('a b c', NULL);
INSERT INTO t1 VALUES('a x c', NULL);
COMMIT;
}
do_execsql_test 3.4 {
SELECT * FROM t1 WHERE t1 MATCH 'a b';
} {{a b c} {}}
#-------------------------------------------------------------------------
#
reset_db
do_test 4.1 {
set a "abc\uFFFEdef"
set b "abc\uD800def"
set c "\uFFFEdef"
set d "\uD800def"
execsql {
CREATE VIRTUAL TABLE t1 USING fts4(tokenize=unicode61, x);
INSERT INTO t1 VALUES($a);
INSERT INTO t1 VALUES($b);
INSERT INTO t1 VALUES($c);
INSERT INTO t1 VALUES($d);
}
} {}
do_test 4.2 {
set a [binary format c* {0x61 0xF7 0xBF 0xBF 0xBF 0x62}]
set b [binary format c* {0x61 0xF7 0xBF 0xBF 0xBF 0xBF 0x62}]
set c [binary format c* {0x61 0xF7 0xBF 0xBF 0xBF 0xBF 0xBF 0x62}]
set d [binary format c* {0x61 0xF7 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF 0x62}]
execsql {
INSERT INTO t1 VALUES($a);
INSERT INTO t1 VALUES($b);
INSERT INTO t1 VALUES($c);
INSERT INTO t1 VALUES($d);
}
} {}
do_test 4.3 {
set a [binary format c* {0xF7 0xBF 0xBF 0xBF}]
set b [binary format c* {0xF7 0xBF 0xBF 0xBF 0xBF}]
set c [binary format c* {0xF7 0xBF 0xBF 0xBF 0xBF 0xBF}]
set d [binary format c* {0xF7 0xBF 0xBF 0xBF 0xBF 0xBF 0xBF}]
execsql {
INSERT INTO t1 VALUES($a);
INSERT INTO t1 VALUES($b);
INSERT INTO t1 VALUES($c);
INSERT INTO t1 VALUES($d);
}
} {}
finish_test

2001
test/fuzz-oss1.test Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -185,7 +185,7 @@ test_suite "fts3" -prefix "" -description {
fts4aa.test fts4content.test fts4aa.test fts4content.test
fts3conf.test fts3prefix.test fts3fault2.test fts3corrupt.test fts3conf.test fts3prefix.test fts3fault2.test fts3corrupt.test
fts3corrupt2.test fts3first.test fts4langid.test fts4merge.test fts3corrupt2.test fts3first.test fts4langid.test fts4merge.test
fts4check.test fts4check.test fts4unicode.test
} }

View File

@@ -164,11 +164,17 @@ do_test quota2-2.1 {
do_test quota2-2.2 { do_test quota2-2.2 {
set ::quota set ::quota
} {} } {}
do_test quota2-2.3 { do_test quota2-2.3.1 {
sqlite3_quota_rewind $::h1 sqlite3_quota_rewind $::h1
sqlite3_quota_file_available $::h1
} {7000}
do_test quota2-2.3.2 {
set ::x [sqlite3_quota_fread $::h1 1001 7] set ::x [sqlite3_quota_fread $::h1 1001 7]
string length $::x string length $::x
} {6006} } {6006}
do_test quota2-2.3.3 {
sqlite3_quota_file_available $::h1
} {0}
do_test quota2-2.4 { do_test quota2-2.4 {
string match $::x [string range $::bigtext 0 6005] string match $::x [string range $::bigtext 0 6005]
} {1} } {1}
@@ -180,22 +186,40 @@ do_test quota2-2.6 {
sqlite3_quota_fseek $::h1 -100 SEEK_END sqlite3_quota_fseek $::h1 -100 SEEK_END
sqlite3_quota_ftell $::h1 sqlite3_quota_ftell $::h1
} {6900} } {6900}
do_test quota2-2.6.1 {
sqlite3_quota_file_available $::h1
} {100}
do_test quota2-2.7 { do_test quota2-2.7 {
sqlite3_quota_fseek $::h1 -100 SEEK_CUR sqlite3_quota_fseek $::h1 -100 SEEK_CUR
sqlite3_quota_ftell $::h1 sqlite3_quota_ftell $::h1
} {6800} } {6800}
do_test quota2-2.7.1 {
sqlite3_quota_file_available $::h1
} {200}
do_test quota2-2.8 { do_test quota2-2.8 {
sqlite3_quota_fseek $::h1 50 SEEK_CUR sqlite3_quota_fseek $::h1 50 SEEK_CUR
sqlite3_quota_ftell $::h1 sqlite3_quota_ftell $::h1
} {6850} } {6850}
do_test quota2-2.8.1 {
sqlite3_quota_file_available $::h1
} {150}
do_test quota2-2.9 { do_test quota2-2.9 {
sqlite3_quota_fseek $::h1 50 SEEK_SET sqlite3_quota_fseek $::h1 50 SEEK_SET
sqlite3_quota_ftell $::h1 sqlite3_quota_ftell $::h1
} {50} } {50}
do_test quota2-2.9.1 {
sqlite3_quota_file_available $::h1
} {6950}
do_test quota2-2.10 { do_test quota2-2.10 {
sqlite3_quota_rewind $::h1 sqlite3_quota_rewind $::h1
sqlite3_quota_ftell $::h1 sqlite3_quota_ftell $::h1
} {0} } {0}
do_test quota2-2.10.1 {
sqlite3_quota_file_available $::h1
} {7000}
do_test quota2-2.10.2 {
sqlite3_quota_ferror $::h1
} {0}
do_test quota2-2.11 { do_test quota2-2.11 {
standard_path [sqlite3_quota_dump] standard_path [sqlite3_quota_dump]
} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}}

View File

@@ -1056,7 +1056,96 @@ do_test shared-$av-15.2 {
db close db close
db2 close db2 close
} # Shared cache on a :memory: database. This only works for URI filenames.
#
do_test shared-$av-16.1 {
sqlite3 db1 file::memory: -uri 1
sqlite3 db2 file::memory: -uri 1
db1 eval {
CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
}
db2 eval {
SELECT x FROM t1 ORDER BY x;
}
} {1 2 3}
do_test shared-$av-16.2 {
db2 eval {
INSERT INTO t1 VALUES(99);
DELETE FROM t1 WHERE x=2;
}
db1 eval {
SELECT x FROM t1 ORDER BY x;
}
} {1 3 99}
# Verify that there is no cache sharing ordinary (non-URI) filenames are
# used.
#
do_test shared-$av-16.3 {
db1 close
db2 close
sqlite3 db1 :memory:
sqlite3 db2 :memory:
db1 eval {
CREATE TABLE t1(x); INSERT INTO t1 VALUES(4),(5),(6);
}
catchsql {
SELECT * FROM t1;
} db2
} {1 {no such table: t1}}
# Shared cache on named memory databases.
#
do_test shared-$av-16.4 {
db1 close
db2 close
forcedelete test.db test.db-wal test.db-journal
sqlite3 db1 file:test.db?mode=memory -uri 1
sqlite3 db2 file:test.db?mode=memory -uri 1
db1 eval {
CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
}
db2 eval {
SELECT x FROM t1 ORDER BY x;
}
} {1 2 3}
do_test shared-$av-16.5 {
db2 eval {
INSERT INTO t1 VALUES(99);
DELETE FROM t1 WHERE x=2;
}
db1 eval {
SELECT x FROM t1 ORDER BY x;
}
} {1 3 99}
do_test shared-$av-16.6 {
file exists test.db
} {0} ;# Verify that the database is in-memory
# Shared cache on named memory databases with different names.
#
do_test shared-$av-16.7 {
db1 close
db2 close
forcedelete test1.db test2.db
sqlite3 db1 file:test1.db?mode=memory -uri 1
sqlite3 db2 file:test2.db?mode=memory -uri 1
db1 eval {
CREATE TABLE t1(x); INSERT INTO t1 VALUES(1),(2),(3);
}
catchsql {
SELECT x FROM t1 ORDER BY x;
} db2
} {1 {no such table: t1}}
do_test shared-$av-16.8 {
file exists test1.db
} {0} ;# Verify that the database is in-memory
db1 close
db2 close
} ;# end of autovacuum on/off loop
sqlite3_enable_shared_cache $::enable_shared_cache sqlite3_enable_shared_cache $::enable_shared_cache
finish_test finish_test

View File

@@ -174,8 +174,7 @@ do_test shell1-1.15.3 {
# -version show SQLite version # -version show SQLite version
do_test shell1-1.16.1 { do_test shell1-1.16.1 {
set x [catchcmd "-version test.db" ""] set x [catchcmd "-version test.db" ""]
regexp {0 \{3.\d.\d+ 20\d\d-[01]\d-\d\d \d\d:\d\d:\d\d [0-9a-f]+\}} $x } {/3.[0-9.]+ 20\d\d-[01]\d-\d\d \d\d:\d\d:\d\d [0-9a-f]+/}
} 1
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Test cases shell1-2.*: Basic "dot" command token parsing. # Test cases shell1-2.*: Basic "dot" command token parsing.
@@ -284,7 +283,7 @@ do_test shell1-3.2.4 {
# .databases List names and files of attached databases # .databases List names and files of attached databases
do_test shell1-3.3.1 { do_test shell1-3.3.1 {
catchcmd "-csv test.db" ".databases" catchcmd "-csv test.db" ".databases"
} {/0 +.*main +.*test.db.*/} } "/0 +.*main +[string map {/ .} [string range [pwd] 0 10]].*/"
do_test shell1-3.3.2 { do_test shell1-3.3.2 {
# too many arguments # too many arguments
catchcmd "test.db" ".databases BAD" catchcmd "test.db" ".databases BAD"
@@ -578,6 +577,18 @@ do_test shell1-3.21.3 {
catchcmd "test.db" ".schema FOO BAD" catchcmd "test.db" ".schema FOO BAD"
} {1 {Error: unknown command or invalid arguments: "schema". Enter ".help" for help}} } {1 {Error: unknown command or invalid arguments: "schema". Enter ".help" for help}}
do_test shell1-3.21.4 {
catchcmd "test.db" {
CREATE TABLE t1(x);
CREATE VIEW v2 AS SELECT x+1 AS y FROM t1;
CREATE VIEW v1 AS SELECT y+1 FROM v2;
}
catchcmd "test.db" ".schema"
} {0 {CREATE TABLE t1(x);
CREATE VIEW v2 AS SELECT x+1 AS y FROM t1;
CREATE VIEW v1 AS SELECT y+1 FROM v2;}}
db eval {DROP VIEW v1; DROP VIEW v2; DROP TABLE t1;}
# .separator STRING Change separator used by output mode and .import # .separator STRING Change separator used by output mode and .import
do_test shell1-3.22.1 { do_test shell1-3.22.1 {
catchcmd "test.db" ".separator" catchcmd "test.db" ".separator"

View File

@@ -377,6 +377,44 @@ do_test subquery-3.4.3 {
} }
} {106 4.5 0 1 107 4.0 1 0} } {106 4.5 0 1 107 4.0 1 0}
do_test subquery-3.5.1 {
execsql {
CREATE TABLE t35a(x); INSERT INTO t35a VALUES(1),(2),(3);
CREATE TABLE t35b(y); INSERT INTO t35b VALUES(98), (99);
SELECT max((SELECT avg(y) FROM t35b)) FROM t35a;
}
} {98.5}
do_test subquery-3.5.2 {
execsql {
SELECT max((SELECT count(y) FROM t35b)) FROM t35a;
}
} {2}
do_test subquery-3.5.3 {
execsql {
SELECT max((SELECT count() FROM t35b)) FROM t35a;
}
} {2}
do_test subquery-3.5.4 {
catchsql {
SELECT max((SELECT count(x) FROM t35b)) FROM t35a;
}
} {1 {misuse of aggregate: count()}}
do_test subquery-3.5.5 {
catchsql {
SELECT max((SELECT count(x) FROM t35b)) FROM t35a;
}
} {1 {misuse of aggregate: count()}}
do_test subquery-3.5.6 {
catchsql {
SELECT max((SELECT a FROM (SELECT count(x) AS a FROM t35b))) FROM t35a;
}
} {1 {misuse of aggregate: count()}}
do_test subquery-3.5.7 {
execsql {
SELECT max((SELECT a FROM (SELECT count(y) AS a FROM t35b))) FROM t35a;
}
} {2}
#------------------------------------------------------------------ #------------------------------------------------------------------
# These tests - subquery-4.* - use the TCL statement cache to try # These tests - subquery-4.* - use the TCL statement cache to try

View File

@@ -316,6 +316,8 @@ foreach file {
fts3_tokenizer1.c fts3_tokenizer1.c
fts3_write.c fts3_write.c
fts3_snippet.c fts3_snippet.c
fts3_unicode.c
fts3_unicode2.c
rtree.c rtree.c
icu.c icu.c