Compare commits
69 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 000705bcce | |||
| fd72563d0a | |||
| f0119b2e1b | |||
| 80262896d6 | |||
| 43ff906d3e | |||
| 2c42c34df5 | |||
| 821b610b63 | |||
| e3eff266bc | |||
| 07f119e470 | |||
| 2c492061ce | |||
| b873f4e404 | |||
| cbeee957e5 | |||
| 3f2cebb6b4 | |||
| 4aafe5957d | |||
| cf847d44ac | |||
| 8ad427f456 | |||
| 9d107262e4 | |||
| f53f88aba6 | |||
| cedfecf90a | |||
| ce2052bc39 | |||
| a968e74fdc | |||
| 8cb83bee0f | |||
| f231e18c6b | |||
| 516c35a72a | |||
| fc50a71be1 | |||
| 3fa5463c03 | |||
| c6c5ab80ee | |||
| 66651c2b4b | |||
| b880a7b1f0 | |||
| 00f0375df7 | |||
| f3f6a5dec3 | |||
| 95ccb6dc8e | |||
| 30f30133d7 | |||
| 24a0c4534a | |||
| 7fbb101c54 | |||
| efce69de37 | |||
| 2589787c5a | |||
| bd45374cc8 | |||
| f6e6f02308 | |||
| cd0abc24d1 | |||
| de8113c31e | |||
| 6974cdcec7 | |||
| f36e4069f3 | |||
| 93c803e960 | |||
| 9579947c55 | |||
| d30830e42d | |||
| 51efe098f4 | |||
| 8b3424d4ee | |||
| d06b5357a4 | |||
| 2d277bb5cb | |||
| cfd74700da | |||
| 8c1eba75a3 | |||
| 9d03f63a7c | |||
| 926961dc53 | |||
| 929cce8890 | |||
| 2cc8f4831e | |||
| d42d8ae337 | |||
| 0d060a071e | |||
| 42a0dbfe92 | |||
| b5a4a7053b | |||
| 3c6de3266e | |||
| 2d44d556b5 | |||
| 86c369428f | |||
| 1e9c47be1e | |||
| 8bbddd8049 | |||
| f01d3a7ef7 | |||
| f1b40e8305 | |||
| c0a499eaad | |||
| a38e6c57bc |
+1
-1
@@ -2091,7 +2091,7 @@ keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
|
||||
# Source files that go into making shell.c
|
||||
SHELL_SRC = \
|
||||
$(TOP)\src\shell.c.in \
|
||||
$(TOP)\ext\misc\appendvfs.c \
|
||||
$(TOP)\ext\misc\appendvfs.c \
|
||||
$(TOP)\ext\misc\shathree.c \
|
||||
$(TOP)\ext\misc\fileio.c \
|
||||
$(TOP)\ext\misc\completion.c \
|
||||
|
||||
@@ -78,7 +78,7 @@ struct completion_cursor {
|
||||
#define COMPLETION_INDEXES 5
|
||||
#define COMPLETION_TRIGGERS 6
|
||||
#define COMPLETION_DATABASES 7
|
||||
#define COMPLETION_TABLES 8
|
||||
#define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */
|
||||
#define COMPLETION_COLUMNS 9
|
||||
#define COMPLETION_MODULES 10
|
||||
#define COMPLETION_EOF 11
|
||||
@@ -250,8 +250,7 @@ static int completionNext(sqlite3_vtab_cursor *cur){
|
||||
const char *zDb = (const char*)sqlite3_column_text(pS2, 1);
|
||||
zSql = sqlite3_mprintf(
|
||||
"%z%s"
|
||||
"SELECT name FROM \"%w\".sqlite_master"
|
||||
" WHERE type='table'",
|
||||
"SELECT name FROM \"%w\".sqlite_master",
|
||||
zSql, zSep, zDb
|
||||
);
|
||||
if( zSql==0 ) return SQLITE_NOMEM;
|
||||
|
||||
+102
-5
@@ -93,6 +93,9 @@ SQLITE_EXTENSION_INIT1
|
||||
# include <direct.h>
|
||||
# include "test_windirent.h"
|
||||
# define dirent DIRENT
|
||||
# ifndef chmod
|
||||
# define chmod _chmod
|
||||
# endif
|
||||
# ifndef stat
|
||||
# define stat _stat
|
||||
# endif
|
||||
@@ -159,6 +162,97 @@ static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
/*
|
||||
** This function is designed to convert a Win32 FILETIME structure into the
|
||||
** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
|
||||
*/
|
||||
static sqlite3_uint64 fileTimeToUnixTime(
|
||||
LPFILETIME pFileTime
|
||||
){
|
||||
SYSTEMTIME epochSystemTime;
|
||||
ULARGE_INTEGER epochIntervals;
|
||||
FILETIME epochFileTime;
|
||||
ULARGE_INTEGER fileIntervals;
|
||||
|
||||
memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
|
||||
epochSystemTime.wYear = 1970;
|
||||
epochSystemTime.wMonth = 1;
|
||||
epochSystemTime.wDay = 1;
|
||||
SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
|
||||
epochIntervals.LowPart = epochFileTime.dwLowDateTime;
|
||||
epochIntervals.HighPart = epochFileTime.dwHighDateTime;
|
||||
|
||||
fileIntervals.LowPart = pFileTime->dwLowDateTime;
|
||||
fileIntervals.HighPart = pFileTime->dwHighDateTime;
|
||||
|
||||
return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function attempts to normalize the time values found in the stat()
|
||||
** buffer to UTC. This is necessary on Win32, where the runtime library
|
||||
** appears to return these values as local times.
|
||||
*/
|
||||
static void statTimesToUtc(
|
||||
const char *zPath,
|
||||
struct stat *pStatBuf
|
||||
){
|
||||
HANDLE hFindFile;
|
||||
WIN32_FIND_DATAW fd;
|
||||
LPWSTR zUnicodeName;
|
||||
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
|
||||
zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
|
||||
if( zUnicodeName ){
|
||||
memset(&fd, 0, sizeof(WIN32_FIND_DATA));
|
||||
hFindFile = FindFirstFileW(zUnicodeName, &fd);
|
||||
if( hFindFile!=NULL ){
|
||||
pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
|
||||
pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
|
||||
pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
|
||||
FindClose(hFindFile);
|
||||
}
|
||||
sqlite3_free(zUnicodeName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This function is used in place of stat(). On Windows, special handling
|
||||
** is required in order for the included time to be returned as UTC. On all
|
||||
** other systems, this function simply calls stat().
|
||||
*/
|
||||
static int fileStat(
|
||||
const char *zPath,
|
||||
struct stat *pStatBuf
|
||||
){
|
||||
#if defined(_WIN32)
|
||||
int rc = stat(zPath, pStatBuf);
|
||||
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
|
||||
return rc;
|
||||
#else
|
||||
return stat(zPath, pStatBuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is used in place of lstat(). On Windows, special handling
|
||||
** is required in order for the included time to be returned as UTC. On all
|
||||
** other systems, this function simply calls lstat().
|
||||
*/
|
||||
static int fileLinkStat(
|
||||
const char *zPath,
|
||||
struct stat *pStatBuf
|
||||
){
|
||||
#if defined(_WIN32)
|
||||
int rc = lstat(zPath, pStatBuf);
|
||||
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
|
||||
return rc;
|
||||
#else
|
||||
return lstat(zPath, pStatBuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
** Argument zFile is the name of a file that will be created and/or written
|
||||
** by SQL function writefile(). This function ensures that the directory
|
||||
@@ -190,7 +284,7 @@ static int makeDirectory(
|
||||
if( i==nCopy ) break;
|
||||
zCopy[i] = '\0';
|
||||
|
||||
rc2 = stat(zCopy, &sStat);
|
||||
rc2 = fileStat(zCopy, &sStat);
|
||||
if( rc2!=0 ){
|
||||
if( mkdir(zCopy, mode & 0777) ) rc = SQLITE_ERROR;
|
||||
}else{
|
||||
@@ -232,7 +326,7 @@ static int writeFile(
|
||||
** to do so using chmod(), it is not an error. */
|
||||
struct stat sStat;
|
||||
if( errno!=EEXIST
|
||||
|| 0!=stat(zFile, &sStat)
|
||||
|| 0!=fileStat(zFile, &sStat)
|
||||
|| !S_ISDIR(sStat.st_mode)
|
||||
|| ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
|
||||
){
|
||||
@@ -279,6 +373,9 @@ static int writeFile(
|
||||
lastWrite.dwLowDateTime = (DWORD)intervals;
|
||||
lastWrite.dwHighDateTime = intervals >> 32;
|
||||
zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
|
||||
if( zUnicodeName==0 ){
|
||||
return 1;
|
||||
}
|
||||
hFile = CreateFileW(
|
||||
zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS, NULL
|
||||
@@ -291,7 +388,7 @@ static int writeFile(
|
||||
}else{
|
||||
return 1;
|
||||
}
|
||||
#elif defined(AT_FDCWD) && 0 /* utimensat() is not univerally available */
|
||||
#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
|
||||
/* Recent unix */
|
||||
struct timespec times[2];
|
||||
times[0].tv_nsec = times[1].tv_nsec = 0;
|
||||
@@ -568,7 +665,7 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){
|
||||
sqlite3_free(pCur->zPath);
|
||||
pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
|
||||
if( pCur->zPath==0 ) return SQLITE_NOMEM;
|
||||
if( lstat(pCur->zPath, &pCur->sStat) ){
|
||||
if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
|
||||
fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
@@ -702,7 +799,7 @@ static int fsdirFilter(
|
||||
if( pCur->zPath==0 ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
if( lstat(pCur->zPath, &pCur->sStat) ){
|
||||
if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
|
||||
fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
+36
-13
@@ -1500,6 +1500,19 @@ static u32 zipfileGetTime(sqlite3_value *pVal){
|
||||
return (u32)sqlite3_value_int64(pVal);
|
||||
}
|
||||
|
||||
/*
|
||||
** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry
|
||||
** linked list. Remove it from the list and free the object.
|
||||
*/
|
||||
static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){
|
||||
if( pOld ){
|
||||
ZipfileEntry **pp;
|
||||
for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext));
|
||||
*pp = (*pp)->pNext;
|
||||
zipfileEntryFree(pOld);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** xUpdate method.
|
||||
*/
|
||||
@@ -1524,6 +1537,8 @@ static int zipfileUpdate(
|
||||
u8 *pFree = 0; /* Free this */
|
||||
char *zFree = 0; /* Also free this */
|
||||
ZipfileEntry *pOld = 0;
|
||||
ZipfileEntry *pOld2 = 0;
|
||||
int bUpdate = 0; /* True for an update that modifies "name" */
|
||||
int bIsDir = 0;
|
||||
u32 iCrc32 = 0;
|
||||
|
||||
@@ -1536,6 +1551,12 @@ static int zipfileUpdate(
|
||||
if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
|
||||
const char *zDelete = (const char*)sqlite3_value_text(apVal[0]);
|
||||
int nDelete = (int)strlen(zDelete);
|
||||
if( nVal>1 ){
|
||||
const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]);
|
||||
if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){
|
||||
bUpdate = 1;
|
||||
}
|
||||
}
|
||||
for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
|
||||
if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){
|
||||
break;
|
||||
@@ -1613,8 +1634,9 @@ static int zipfileUpdate(
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that we're not inserting a duplicate entry */
|
||||
if( pOld==0 && rc==SQLITE_OK ){
|
||||
/* Check that we're not inserting a duplicate entry -OR- updating an
|
||||
** entry with a path, thereby making it into a duplicate. */
|
||||
if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){
|
||||
ZipfileEntry *p;
|
||||
for(p=pTab->pFirstEntry; p; p=p->pNext){
|
||||
if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){
|
||||
@@ -1623,7 +1645,7 @@ static int zipfileUpdate(
|
||||
goto zipfile_update_done;
|
||||
}
|
||||
case SQLITE_REPLACE: {
|
||||
pOld = p;
|
||||
pOld2 = p;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -1661,18 +1683,17 @@ static int zipfileUpdate(
|
||||
}
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && pOld ){
|
||||
ZipfileEntry **pp;
|
||||
if( rc==SQLITE_OK && (pOld || pOld2) ){
|
||||
ZipfileCsr *pCsr;
|
||||
for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
|
||||
if( pCsr->pCurrent==pOld ){
|
||||
pCsr->pCurrent = pOld->pNext;
|
||||
if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){
|
||||
pCsr->pCurrent = pCsr->pCurrent->pNext;
|
||||
pCsr->bNoop = 1;
|
||||
}
|
||||
}
|
||||
for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext));
|
||||
*pp = (*pp)->pNext;
|
||||
zipfileEntryFree(pOld);
|
||||
|
||||
zipfileRemoveEntryFromList(pTab, pOld);
|
||||
zipfileRemoveEntryFromList(pTab, pOld2);
|
||||
}
|
||||
|
||||
zipfile_update_done:
|
||||
@@ -2040,9 +2061,11 @@ void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
|
||||
p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]);
|
||||
|
||||
/* Append the data to the body of the new archive */
|
||||
if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out;
|
||||
memcpy(&p->body.a[p->body.n], aData, nData);
|
||||
p->body.n += nData;
|
||||
if( nData>0 ){
|
||||
if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out;
|
||||
memcpy(&p->body.a[p->body.n], aData, nData);
|
||||
p->body.n += nData;
|
||||
}
|
||||
|
||||
/* Append the CDS record to the directory of the new archive */
|
||||
nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9;
|
||||
|
||||
@@ -71,6 +71,7 @@ proc step_rbu {target rbu} {
|
||||
}
|
||||
|
||||
proc do_rbu_vacuum_test {tn step} {
|
||||
forcedelete state.db
|
||||
uplevel [list do_test $tn.1 {
|
||||
if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db }
|
||||
while 1 {
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# 2018 March 22
|
||||
#
|
||||
# The author disclaims copyright to this source code. In place of
|
||||
# a legal notice, here is a blessing:
|
||||
#
|
||||
# May you do good and not evil.
|
||||
# May you find forgiveness for yourself and forgive others.
|
||||
# May you share freely, never taking more than you give.
|
||||
#
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
source [file join [file dirname [info script]] rbu_common.tcl]
|
||||
set ::testprefix rbucollate
|
||||
|
||||
ifcapable !icu_collations {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
db close
|
||||
sqlite3_shutdown
|
||||
sqlite3_config_uri 1
|
||||
reset_db
|
||||
|
||||
# Create a simple RBU database. That expects to write to a table:
|
||||
#
|
||||
# CREATE TABLE t1(a PRIMARY KEY, b, c);
|
||||
#
|
||||
proc create_rbu1 {filename} {
|
||||
forcedelete $filename
|
||||
sqlite3 rbu1 $filename
|
||||
rbu1 eval {
|
||||
CREATE TABLE data_t1(a, b, c, rbu_control);
|
||||
INSERT INTO data_t1 VALUES('a', 'one', 1, 0);
|
||||
INSERT INTO data_t1 VALUES('b', 'two', 2, 0);
|
||||
INSERT INTO data_t1 VALUES('c', 'three', 3, 0);
|
||||
}
|
||||
rbu1 close
|
||||
return $filename
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
SELECT icu_load_collation('en_US', 'my-collate');
|
||||
CREATE TABLE t1(a COLLATE "my-collate" PRIMARY KEY, b, c);
|
||||
} {{}}
|
||||
|
||||
do_test 1.2 {
|
||||
create_rbu1 testrbu.db
|
||||
sqlite3rbu rbu test.db testrbu.db
|
||||
rbu dbMain_eval { SELECT icu_load_collation('en_US', 'my-collate') }
|
||||
rbu dbRbu_eval { SELECT icu_load_collation('en_US', 'my-collate') }
|
||||
while 1 {
|
||||
set rc [rbu step]
|
||||
if {$rc!="SQLITE_OK"} break
|
||||
}
|
||||
rbu close
|
||||
db eval { SELECT * FROM t1 }
|
||||
} {a one 1 b two 2 c three 3}
|
||||
|
||||
#forcedelete testrbu.db
|
||||
finish_test
|
||||
|
||||
@@ -1806,7 +1806,7 @@ static void rbuCreateImposterTable2(sqlite3rbu *p, RbuObjIter *pIter){
|
||||
int iCid = sqlite3_column_int(pXInfo, 1);
|
||||
int bDesc = sqlite3_column_int(pXInfo, 3);
|
||||
const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
|
||||
zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma,
|
||||
zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %Q", zCols, zComma,
|
||||
iCid, pIter->azTblType[iCid], zCollate
|
||||
);
|
||||
zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":"");
|
||||
@@ -1867,7 +1867,7 @@ static void rbuCreateImposterTable(sqlite3rbu *p, RbuObjIter *pIter){
|
||||
** "PRIMARY KEY" to the imposter table column declaration. */
|
||||
zPk = "PRIMARY KEY ";
|
||||
}
|
||||
zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s",
|
||||
zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %Q%s",
|
||||
zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl,
|
||||
(pIter->abNotNull[iCol] ? " NOT NULL" : "")
|
||||
);
|
||||
|
||||
+4
-2
@@ -81,6 +81,7 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd(
|
||||
{"close_no_error", 2, ""}, /* 9 */
|
||||
{"temp_size_limit", 3, "LIMIT"}, /* 10 */
|
||||
{"temp_size", 2, ""}, /* 11 */
|
||||
{"dbRbu_eval", 3, "SQL"}, /* 12 */
|
||||
{0,0,0}
|
||||
};
|
||||
int iCmd;
|
||||
@@ -146,8 +147,9 @@ static int SQLITE_TCLAPI test_sqlite3rbu_cmd(
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: /* dbMain_eval */ {
|
||||
sqlite3 *db = sqlite3rbu_db(pRbu, 0);
|
||||
case 12: /* dbRbu_eval */
|
||||
case 4: /* dbMain_eval */ {
|
||||
sqlite3 *db = sqlite3rbu_db(pRbu, (iCmd==12));
|
||||
int rc = sqlite3_exec(db, Tcl_GetString(objv[2]), 0, 0, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(db), -1));
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
# This file implements regression tests for the session module.
|
||||
#
|
||||
|
||||
package require Tcl 8.6
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
|
||||
@@ -169,3 +169,4 @@ proc changeset_to_list {c} {
|
||||
sqlite3session_foreach elem $c { lappend list $elem }
|
||||
lsort $list
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
set testprefix sessionfault2
|
||||
|
||||
if 1 {
|
||||
|
||||
do_execsql_test 1.0.0 {
|
||||
CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
|
||||
INSERT INTO t1 VALUES(1, 1);
|
||||
@@ -103,5 +105,181 @@ do_faultsim_test 2 -faults oom-p* -prep {
|
||||
faultsim_integrity_check
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# OOM when collecting and apply a changeset that uses sqlite_stat1.
|
||||
#
|
||||
reset_db
|
||||
forcedelete test.db2
|
||||
sqlite3 db2 test.db2
|
||||
do_common_sql {
|
||||
CREATE TABLE t1(a PRIMARY KEY, b UNIQUE, c);
|
||||
CREATE INDEX i1 ON t1(c);
|
||||
INSERT INTO t1 VALUES(1, 2, 3);
|
||||
INSERT INTO t1 VALUES(4, 5, 6);
|
||||
INSERT INTO t1 VALUES(7, 8, 9);
|
||||
CREATE TABLE t2(a, b, c);
|
||||
INSERT INTO t2 VALUES(1, 2, 3);
|
||||
INSERT INTO t2 VALUES(4, 5, 6);
|
||||
INSERT INTO t2 VALUES(7, 8, 9);
|
||||
ANALYZE;
|
||||
}
|
||||
faultsim_save_and_close
|
||||
db2 close
|
||||
|
||||
do_faultsim_test 1.1 -faults oom-* -prep {
|
||||
catch {db2 close}
|
||||
catch {db close}
|
||||
faultsim_restore_and_reopen
|
||||
sqlite3 db2 test.db2
|
||||
} -body {
|
||||
do_then_apply_sql {
|
||||
INSERT INTO sqlite_stat1 VALUES('x', 'y', 45);
|
||||
UPDATE sqlite_stat1 SET stat = 123 WHERE tbl='t1' AND idx='i1';
|
||||
UPDATE sqlite_stat1 SET stat = 456 WHERE tbl='t2';
|
||||
}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
|
||||
faultsim_integrity_check
|
||||
if {$testrc==0} { compare_db db db2 }
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# OOM when collecting and using a rebase changeset.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 2.0 {
|
||||
CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c));
|
||||
CREATE TABLE t4(x PRIMARY KEY, y, z);
|
||||
|
||||
INSERT INTO t3 VALUES(1, 2, 3);
|
||||
INSERT INTO t3 VALUES(4, 2, 5);
|
||||
INSERT INTO t3 VALUES(7, 2, 9);
|
||||
|
||||
INSERT INTO t4 VALUES('a', 'b', 'c');
|
||||
INSERT INTO t4 VALUES('d', 'e', 'f');
|
||||
INSERT INTO t4 VALUES('g', 'h', 'i');
|
||||
}
|
||||
faultsim_save_and_close
|
||||
db2 close
|
||||
|
||||
proc xConflict {ret args} { return $ret }
|
||||
|
||||
do_test 2.1 {
|
||||
faultsim_restore_and_reopen
|
||||
set C1 [changeset_from_sql {
|
||||
INSERT INTO t3 VALUES(10, 11, 12);
|
||||
UPDATE t4 SET y='j' WHERE x='g';
|
||||
DELETE FROM t4 WHERE x='a';
|
||||
}]
|
||||
|
||||
faultsim_restore_and_reopen
|
||||
set C2 [changeset_from_sql {
|
||||
INSERT INTO t3 VALUES(1000, 11, 12);
|
||||
DELETE FROM t4 WHERE x='g';
|
||||
}]
|
||||
|
||||
faultsim_restore_and_reopen
|
||||
sqlite3changeset_apply db $C1 [list xConflict OMIT]
|
||||
faultsim_save_and_close
|
||||
} {}
|
||||
|
||||
do_faultsim_test 2.2 -faults oom* -prep {
|
||||
catch {db2 close}
|
||||
catch {db close}
|
||||
faultsim_restore_and_reopen
|
||||
sqlite3 db2 test.db2
|
||||
} -body {
|
||||
set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
|
||||
set {} {}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
|
||||
}
|
||||
do_faultsim_test 2.3 -faults oom* -prep {
|
||||
catch {db2 close}
|
||||
catch {db close}
|
||||
faultsim_restore_and_reopen
|
||||
sqlite3 db2 test.db2
|
||||
} -body {
|
||||
set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]]
|
||||
set {} {}
|
||||
} -test {
|
||||
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
|
||||
}
|
||||
do_faultsim_test 2.4 -faults oom* -prep {
|
||||
catch {db2 close}
|
||||
catch {db close}
|
||||
faultsim_restore_and_reopen
|
||||
set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]]
|
||||
} -body {
|
||||
sqlite3rebaser_create R
|
||||
R configure $::rebase
|
||||
R rebase $::C1
|
||||
set {} {}
|
||||
} -test {
|
||||
catch { R delete }
|
||||
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
|
||||
}
|
||||
do_faultsim_test 2.5 -faults oom* -prep {
|
||||
catch {db2 close}
|
||||
catch {db close}
|
||||
faultsim_restore_and_reopen
|
||||
set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
|
||||
} -body {
|
||||
sqlite3rebaser_create R
|
||||
R configure $::rebase
|
||||
R rebase $::C1
|
||||
set {} {}
|
||||
} -test {
|
||||
catch { R delete }
|
||||
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE t1(x PRIMARY KEY, y, z);
|
||||
INSERT INTO t1 VALUES(3, 1, 4);
|
||||
INSERT INTO t1 VALUES(1, 5, 9);
|
||||
}
|
||||
faultsim_save_and_close
|
||||
|
||||
proc xConflict {ret args} { return $ret }
|
||||
|
||||
do_test 3.1 {
|
||||
faultsim_restore_and_reopen
|
||||
|
||||
execsql { BEGIN; UPDATE t1 SET z=11; }
|
||||
set C1 [changeset_from_sql {
|
||||
UPDATE t1 SET z=10 WHERE x=1;
|
||||
}]
|
||||
execsql { ROLLBACK }
|
||||
|
||||
execsql { BEGIN; UPDATE t1 SET z=11; }
|
||||
set C2 [changeset_from_sql {
|
||||
UPDATE t1 SET z=55 WHERE x=1;
|
||||
}]
|
||||
execsql { ROLLBACK }
|
||||
|
||||
set ::rebase1 [sqlite3changeset_apply_v2 db $::C1 [list xConflict OMIT]]
|
||||
set ::rebase2 [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]]
|
||||
set {} {}
|
||||
execsql { SELECT * FROM t1 }
|
||||
} {3 1 4 1 5 9}
|
||||
|
||||
|
||||
do_faultsim_test 3.2 -faults oom* -prep {
|
||||
faultsim_restore_and_reopen
|
||||
} -body {
|
||||
sqlite3rebaser_create R
|
||||
R configure $::rebase1
|
||||
R configure $::rebase2
|
||||
set {} {}
|
||||
} -test {
|
||||
catch { R delete }
|
||||
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
|
||||
}
|
||||
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
@@ -0,0 +1,477 @@
|
||||
# 2018 March 14
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#***********************************************************************
|
||||
# This file implements regression tests for SQLite library.
|
||||
#
|
||||
|
||||
if {![info exists testdir]} {
|
||||
set testdir [file join [file dirname [info script]] .. .. test]
|
||||
}
|
||||
source [file join [file dirname [info script]] session_common.tcl]
|
||||
source $testdir/tester.tcl
|
||||
ifcapable !session {finish_test; return}
|
||||
|
||||
set testprefix sessionrebase
|
||||
|
||||
set ::lConflict [list]
|
||||
proc xConflict {args} {
|
||||
set res [lindex $::lConflict 0]
|
||||
set ::lConflict [lrange $::lConflict 1 end]
|
||||
return $res
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# The following test cases - 1.* - test that the rebase blobs output by
|
||||
# sqlite3_changeset_apply_v2 look correct in some simple cases. The blob
|
||||
# is itself a changeset, containing records determined as follows:
|
||||
#
|
||||
# * For each conflict resolved with REPLACE, the rebase blob contains
|
||||
# a DELETE record. All fields other than the PK fields are undefined.
|
||||
#
|
||||
# * For each conflict resolved with OMIT, the rebase blob contains an
|
||||
# INSERT record. For an INSERT or UPDATE operation, the indirect flag
|
||||
# is clear and all updated fields are defined. For a DELETE operation,
|
||||
# the indirect flag is set and all non-PK fields left undefined.
|
||||
#
|
||||
proc do_apply_v2_test {tn sql modsql conflict_handler res} {
|
||||
|
||||
execsql BEGIN
|
||||
sqlite3session S db main
|
||||
S attach *
|
||||
execsql $sql
|
||||
set changeset [S changeset]
|
||||
S delete
|
||||
execsql ROLLBACK
|
||||
|
||||
execsql BEGIN
|
||||
execsql $modsql
|
||||
set ::lConflict $conflict_handler
|
||||
set blob [sqlite3changeset_apply_v2 db $changeset xConflict]
|
||||
execsql ROLLBACK
|
||||
|
||||
uplevel [list do_test $tn [list changeset_to_list $blob] [list {*}$res]]
|
||||
}
|
||||
|
||||
|
||||
set ::lConflict [list]
|
||||
proc xConflict {args} {
|
||||
set res [lindex $::lConflict 0]
|
||||
set ::lConflict [lrange $::lConflict 1 end]
|
||||
return $res
|
||||
}
|
||||
|
||||
# Take a copy of database test.db in file test.db2. Execute $sql1
|
||||
# against test.db and $sql2 against test.db2. Capture a changeset
|
||||
# for each. Then send the test.db2 changeset to test.db and apply
|
||||
# it with the conflict handlers in $conflict_handler. Patch the
|
||||
# test.db changeset and then execute it against test.db2. Test that
|
||||
# the two databases come out the same.
|
||||
#
|
||||
proc do_rebase_test {tn sql1 sql2 conflict_handler {testsql ""} {testres ""}} {
|
||||
|
||||
for {set i 1} {$i <= 2} {incr i} {
|
||||
forcedelete test.db2 test.db2-journal test.db2-wal
|
||||
forcecopy test.db test.db2
|
||||
sqlite3 db2 test.db2
|
||||
|
||||
db eval BEGIN
|
||||
|
||||
sqlite3session S1 db main
|
||||
S1 attach *
|
||||
execsql $sql1 db
|
||||
set c1 [S1 changeset]
|
||||
S1 delete
|
||||
|
||||
if {$i==1} {
|
||||
sqlite3session S2 db2 main
|
||||
S2 attach *
|
||||
execsql $sql2 db2
|
||||
set c2 [S2 changeset]
|
||||
S2 delete
|
||||
} else {
|
||||
set c2 [list]
|
||||
foreach sql [split $sql2 ";"] {
|
||||
if {[string is space $sql]} continue
|
||||
sqlite3session S2 db2 main
|
||||
S2 attach *
|
||||
execsql $sql db2
|
||||
lappend c2 [S2 changeset]
|
||||
S2 delete
|
||||
}
|
||||
}
|
||||
|
||||
set ::lConflict $conflict_handler
|
||||
set rebase [list]
|
||||
if {$i==1} {
|
||||
lappend rebase [sqlite3changeset_apply_v2 db $c2 xConflict]
|
||||
} else {
|
||||
foreach c $c2 {
|
||||
#puts "apply_v2: [changeset_to_list $c]"
|
||||
lappend rebase [sqlite3changeset_apply_v2 db $c xConflict]
|
||||
}
|
||||
#puts "llength: [llength $rebase]"
|
||||
}
|
||||
#if {$tn=="2.1.4"} { puts [changeset_to_list $rebase] ; breakpoint }
|
||||
#puts [changeset_to_list [lindex $rebase 0]] ; breakpoint
|
||||
#puts [llength $rebase]
|
||||
|
||||
sqlite3rebaser_create R
|
||||
foreach r $rebase {
|
||||
#puts [changeset_to_list $r]
|
||||
R configure $r
|
||||
}
|
||||
set c1r [R rebase $c1]
|
||||
R delete
|
||||
#if {$tn=="2.1.4"} { puts [changeset_to_list $c1r] }
|
||||
|
||||
sqlite3changeset_apply_v2 db2 $c1r xConflictAbort
|
||||
|
||||
if {[string range $tn end end]!="*"} {
|
||||
uplevel [list do_test $tn.$i.1 [list compare_db db db2] {}]
|
||||
}
|
||||
db2 close
|
||||
|
||||
if {$testsql!=""} {
|
||||
uplevel [list do_execsql_test $tn.$i.2 $testsql $testres]
|
||||
}
|
||||
|
||||
db eval ROLLBACK
|
||||
}
|
||||
}
|
||||
|
||||
do_execsql_test 1.0 {
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||
INSERT INTO t1 VALUES(1, 'value A');
|
||||
}
|
||||
|
||||
do_apply_v2_test 1.1.1 {
|
||||
UPDATE t1 SET b = 'value B' WHERE a=1;
|
||||
} {
|
||||
UPDATE t1 SET b = 'value C' WHERE a=1;
|
||||
} {
|
||||
OMIT
|
||||
} {
|
||||
{INSERT t1 0 X. {} {i 1 t {value B}}}
|
||||
}
|
||||
|
||||
do_apply_v2_test 1.1.2 {
|
||||
UPDATE t1 SET b = 'value B' WHERE a=1;
|
||||
} {
|
||||
UPDATE t1 SET b = 'value C' WHERE a=1;
|
||||
} {
|
||||
REPLACE
|
||||
} {
|
||||
{INSERT t1 1 X. {} {i 1 t {value B}}}
|
||||
}
|
||||
|
||||
do_apply_v2_test 1.2.1 {
|
||||
INSERT INTO t1 VALUES(2, 'first');
|
||||
} {
|
||||
INSERT INTO t1 VALUES(2, 'second');
|
||||
} {
|
||||
OMIT
|
||||
} {
|
||||
{INSERT t1 0 X. {} {i 2 t first}}
|
||||
}
|
||||
do_apply_v2_test 1.2.2 {
|
||||
INSERT INTO t1 VALUES(2, 'first');
|
||||
} {
|
||||
INSERT INTO t1 VALUES(2, 'second');
|
||||
} {
|
||||
REPLACE
|
||||
} {
|
||||
{INSERT t1 1 X. {} {i 2 t first}}
|
||||
}
|
||||
|
||||
do_apply_v2_test 1.3.1 {
|
||||
DELETE FROM t1 WHERE a=1;
|
||||
} {
|
||||
UPDATE t1 SET b='value D' WHERE a=1;
|
||||
} {
|
||||
OMIT
|
||||
} {
|
||||
{DELETE t1 0 X. {i 1 t {value A}} {}}
|
||||
}
|
||||
do_apply_v2_test 1.3.2 {
|
||||
DELETE FROM t1 WHERE a=1;
|
||||
} {
|
||||
UPDATE t1 SET b='value D' WHERE a=1;
|
||||
} {
|
||||
REPLACE
|
||||
} {
|
||||
{DELETE t1 1 X. {i 1 t {value A}} {}}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test cases 2.* - simple tests of rebasing actual changesets.
|
||||
#
|
||||
# 2.1.1 - 1u2u1r
|
||||
# 2.1.2 - 1u2u2r
|
||||
# 2.1.3 - 1d2d
|
||||
# 2.1.4 - 1d2u1r
|
||||
# 2.1.5 - 1d2u2r !!
|
||||
# 2.1.6 - 1u2d1r
|
||||
# 2.1.7 - 1u2d2r
|
||||
#
|
||||
# 2.1.8 - 1i2i2r
|
||||
# 2.1.9 - 1i2i1r
|
||||
#
|
||||
|
||||
proc xConflictAbort {args} {
|
||||
return "ABORT"
|
||||
}
|
||||
|
||||
reset_db
|
||||
do_execsql_test 2.1.0 {
|
||||
CREATE TABLE t1 (a INTEGER PRIMARY KEY, b TEXT);
|
||||
INSERT INTO t1 VALUES(1, 'one');
|
||||
INSERT INTO t1 VALUES(2, 'two');
|
||||
INSERT INTO t1 VALUES(3, 'three');
|
||||
}
|
||||
do_rebase_test 2.1.1 {
|
||||
UPDATE t1 SET b = 'two.1' WHERE a=2
|
||||
} {
|
||||
UPDATE t1 SET b = 'two.2' WHERE a=2;
|
||||
} {
|
||||
OMIT
|
||||
} { SELECT * FROM t1 } {1 one 2 two.1 3 three}
|
||||
|
||||
do_rebase_test 2.1.2 {
|
||||
UPDATE t1 SET b = 'two.1' WHERE a=2
|
||||
} {
|
||||
UPDATE t1 SET b = 'two.2' WHERE a=2;
|
||||
} {
|
||||
REPLACE
|
||||
} { SELECT * FROM t1 } {1 one 2 two.2 3 three}
|
||||
|
||||
do_rebase_test 2.1.3 {
|
||||
DELETE FROM t1 WHERE a=3
|
||||
} {
|
||||
DELETE FROM t1 WHERE a=3;
|
||||
} {
|
||||
OMIT
|
||||
} { SELECT * FROM t1 } {1 one 2 two}
|
||||
|
||||
do_rebase_test 2.1.4 {
|
||||
DELETE FROM t1 WHERE a=1
|
||||
} {
|
||||
UPDATE t1 SET b='one.2' WHERE a=1
|
||||
} {
|
||||
OMIT
|
||||
} { SELECT * FROM t1 } {2 two 3 three}
|
||||
|
||||
#do_rebase_test 2.1.5 {
|
||||
# DELETE FROM t1 WHERE a=1;
|
||||
#} {
|
||||
# UPDATE t1 SET b='one.2' WHERE a=1
|
||||
#} {
|
||||
# REPLACE
|
||||
#} { SELECT * FROM t1 } {2 two 3 three}
|
||||
|
||||
do_rebase_test 2.1.6 {
|
||||
UPDATE t1 SET b='three.1' WHERE a=3
|
||||
} {
|
||||
DELETE FROM t1 WHERE a=3;
|
||||
} {
|
||||
OMIT
|
||||
} { SELECT * FROM t1 } {1 one 2 two 3 three.1}
|
||||
|
||||
do_rebase_test 2.1.7 {
|
||||
UPDATE t1 SET b='three.1' WHERE a=3
|
||||
} {
|
||||
DELETE FROM t1 WHERE a=3;
|
||||
} {
|
||||
REPLACE
|
||||
} { SELECT * FROM t1 } {1 one 2 two}
|
||||
|
||||
do_rebase_test 2.1.8 {
|
||||
INSERT INTO t1 VALUES(4, 'four.1')
|
||||
} {
|
||||
INSERT INTO t1 VALUES(4, 'four.2');
|
||||
} {
|
||||
REPLACE
|
||||
} { SELECT * FROM t1 } {1 one 2 two 3 three 4 four.2}
|
||||
|
||||
do_rebase_test 2.1.9 {
|
||||
INSERT INTO t1 VALUES(4, 'four.1')
|
||||
} {
|
||||
INSERT INTO t1 VALUES(4, 'four.2');
|
||||
} {
|
||||
OMIT
|
||||
} { SELECT * FROM t1 } {1 one 2 two 3 three 4 four.1}
|
||||
|
||||
do_execsql_test 2.2.0 {
|
||||
CREATE TABLE t2(x, y, z PRIMARY KEY);
|
||||
INSERT INTO t2 VALUES('i', 'a', 'A');
|
||||
INSERT INTO t2 VALUES('ii', 'b', 'B');
|
||||
INSERT INTO t2 VALUES('iii', 'c', 'C');
|
||||
|
||||
CREATE TABLE t3(a INTEGER PRIMARY KEY, b, c);
|
||||
INSERT INTO t3 VALUES(-1, 'z', 'Z');
|
||||
INSERT INTO t3 VALUES(-2, 'y', 'Y');
|
||||
}
|
||||
|
||||
do_rebase_test 2.2.1 {
|
||||
UPDATE t2 SET x=1 WHERE z='A'
|
||||
} {
|
||||
UPDATE t2 SET y='one' WHERE z='A';
|
||||
} {
|
||||
} { SELECT * FROM t2 WHERE z='A' } { 1 one A }
|
||||
|
||||
do_rebase_test 2.2.2 {
|
||||
UPDATE t2 SET x=1, y='one' WHERE z='B'
|
||||
} {
|
||||
UPDATE t2 SET y='two' WHERE z='B';
|
||||
} {
|
||||
REPLACE
|
||||
} { SELECT * FROM t2 WHERE z='B' } { 1 two B }
|
||||
|
||||
do_rebase_test 2.2.3 {
|
||||
UPDATE t2 SET x=1, y='one' WHERE z='B'
|
||||
} {
|
||||
UPDATE t2 SET y='two' WHERE z='B';
|
||||
} {
|
||||
OMIT
|
||||
} { SELECT * FROM t2 WHERE z='B' } { 1 one B }
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
reset_db
|
||||
do_execsql_test 3.0 {
|
||||
CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c));
|
||||
CREATE TABLE abcdefghijkl(x PRIMARY KEY, y, z);
|
||||
|
||||
INSERT INTO t3 VALUES(1, 2, 3);
|
||||
INSERT INTO t3 VALUES(4, 2, 5);
|
||||
INSERT INTO t3 VALUES(7, 2, 9);
|
||||
|
||||
INSERT INTO abcdefghijkl VALUES('a', 'b', 'c');
|
||||
INSERT INTO abcdefghijkl VALUES('d', 'e', 'f');
|
||||
INSERT INTO abcdefghijkl VALUES('g', 'h', 'i');
|
||||
}
|
||||
|
||||
breakpoint
|
||||
# do_rebase_test 3.6.tn {
|
||||
# UPDATE abcdefghijkl SET z='X', y='X' WHERE x='d';
|
||||
# } {
|
||||
# UPDATE abcdefghijkl SET y=1 WHERE x='d';
|
||||
# UPDATE abcdefghijkl SET z=1 WHERE x='d';
|
||||
# } [list REPLACE REPLACE REPLACE]
|
||||
|
||||
foreach {tn p} {
|
||||
1 OMIT 2 REPLACE
|
||||
} {
|
||||
do_rebase_test 3.1.$tn {
|
||||
INSERT INTO t3 VALUES(1, 1, 1);
|
||||
UPDATE abcdefghijkl SET y=2;
|
||||
} {
|
||||
INSERT INTO t3 VALUES(4, 1, 1);
|
||||
DELETE FROM abcdefghijkl;
|
||||
} [list $p $p $p $p $p $p $p $p]
|
||||
|
||||
do_rebase_test 3.2.$tn {
|
||||
INSERT INTO abcdefghijkl SELECT * FROM t3;
|
||||
UPDATE t3 SET b=b+1;
|
||||
} {
|
||||
INSERT INTO t3 VALUES(3, 3, 3);
|
||||
INSERT INTO abcdefghijkl SELECT * FROM t3;
|
||||
} [list $p $p $p $p $p $p $p $p]
|
||||
|
||||
do_rebase_test 3.3.$tn {
|
||||
INSERT INTO abcdefghijkl VALUES(22, 23, 24);
|
||||
} {
|
||||
INSERT INTO abcdefghijkl VALUES(22, 25, 26);
|
||||
UPDATE abcdefghijkl SET y=400 WHERE x=22;
|
||||
} [list $p $p $p $p $p $p $p $p]
|
||||
|
||||
do_rebase_test 3.4.$tn {
|
||||
INSERT INTO abcdefghijkl VALUES(22, 23, 24);
|
||||
} {
|
||||
INSERT INTO abcdefghijkl VALUES(22, 25, 26);
|
||||
UPDATE abcdefghijkl SET y=400 WHERE x=22;
|
||||
} [list REPLACE $p]
|
||||
|
||||
do_rebase_test 3.5.$tn* {
|
||||
UPDATE abcdefghijkl SET y='X' WHERE x='d';
|
||||
} {
|
||||
DELETE FROM abcdefghijkl WHERE x='d';
|
||||
INSERT INTO abcdefghijkl VALUES('d', NULL, NULL);
|
||||
} [list $p $p $p]
|
||||
do_rebase_test 3.5.$tn {
|
||||
UPDATE abcdefghijkl SET y='X' WHERE x='d';
|
||||
} {
|
||||
DELETE FROM abcdefghijkl WHERE x='d';
|
||||
INSERT INTO abcdefghijkl VALUES('d', NULL, NULL);
|
||||
} [list REPLACE $p $p]
|
||||
|
||||
do_rebase_test 3.6.$tn {
|
||||
UPDATE abcdefghijkl SET z='X', y='X' WHERE x='d';
|
||||
} {
|
||||
UPDATE abcdefghijkl SET y=1 WHERE x='d';
|
||||
UPDATE abcdefghijkl SET z=1 WHERE x='d';
|
||||
} [list REPLACE $p $p]
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Check that apply_v2() does not create a rebase buffer for a patchset.
|
||||
# And that it is not possible to rebase a patchset.
|
||||
#
|
||||
do_execsql_test 4.0 {
|
||||
CREATE TABLE t5(o PRIMARY KEY, p, q);
|
||||
INSERT INTO t5 VALUES(1, 2, 3);
|
||||
INSERT INTO t5 VALUES(4, 5, 6);
|
||||
}
|
||||
foreach {tn cmd rebasable} {
|
||||
1 patchset 0
|
||||
2 changeset 1
|
||||
} {
|
||||
proc xConflict {args} { return "OMIT" }
|
||||
do_test 4.1.$tn {
|
||||
execsql {
|
||||
BEGIN;
|
||||
DELETE FROM t5 WHERE o=4;
|
||||
}
|
||||
|
||||
sqlite3session S db main
|
||||
S attach *
|
||||
execsql {
|
||||
INSERT INTO t5 VALUES(4, 'five', 'six');
|
||||
}
|
||||
set P [S $cmd]
|
||||
S delete
|
||||
|
||||
execsql ROLLBACK;
|
||||
|
||||
set ::rebase [sqlite3changeset_apply_v2 db $P xConflict]
|
||||
expr [llength $::rebase]>0
|
||||
} $rebasable
|
||||
}
|
||||
|
||||
foreach {tn cmd rebasable} {
|
||||
1 patchset 0
|
||||
2 changeset 1
|
||||
} {
|
||||
do_test 4.2.$tn {
|
||||
sqlite3session S db main
|
||||
S attach *
|
||||
execsql {
|
||||
INSERT INTO t5 VALUES(5+$tn, 'five', 'six');
|
||||
}
|
||||
set P [S $cmd]
|
||||
S delete
|
||||
|
||||
sqlite3rebaser_create R
|
||||
R configure $::rebase
|
||||
expr [catch {R rebase $P}]==0
|
||||
} $rebasable
|
||||
|
||||
catch { R delete }
|
||||
}
|
||||
finish_test
|
||||
|
||||
+588
-66
@@ -232,8 +232,8 @@ struct SessionTable {
|
||||
** statement.
|
||||
**
|
||||
** For a DELETE change, all fields within the record except those associated
|
||||
** with PRIMARY KEY columns are set to "undefined". The PRIMARY KEY fields
|
||||
** contain the values identifying the row to delete.
|
||||
** with PRIMARY KEY columns are omitted. The PRIMARY KEY fields contain the
|
||||
** values identifying the row to delete.
|
||||
**
|
||||
** For an UPDATE change, all fields except those associated with PRIMARY KEY
|
||||
** columns and columns that are modified by the UPDATE are set to "undefined".
|
||||
@@ -516,7 +516,7 @@ static int sessionPreupdateHash(
|
||||
static int sessionSerialLen(u8 *a){
|
||||
int e = *a;
|
||||
int n;
|
||||
if( e==0 ) return 1;
|
||||
if( e==0 || e==0xFF ) return 1;
|
||||
if( e==SQLITE_NULL ) return 1;
|
||||
if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9;
|
||||
return sessionVarintGet(&a[1], &n) + 1 + n;
|
||||
@@ -596,7 +596,7 @@ static int sessionChangeEqual(
|
||||
int n1 = sessionSerialLen(a1);
|
||||
int n2 = sessionSerialLen(a2);
|
||||
|
||||
if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){
|
||||
if( n1!=n2 || memcmp(a1, a2, n1) ){
|
||||
return 0;
|
||||
}
|
||||
a1 += n1;
|
||||
@@ -839,7 +839,7 @@ static int sessionPreupdateEqual(
|
||||
}else{
|
||||
z = sqlite3_value_blob(pVal);
|
||||
}
|
||||
if( memcmp(a, z, n) ) return 0;
|
||||
if( n>0 && memcmp(a, z, n) ) return 0;
|
||||
a += n;
|
||||
}
|
||||
}
|
||||
@@ -2183,6 +2183,7 @@ static int sessionSelectStmt(
|
||||
"SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND "
|
||||
"idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb
|
||||
);
|
||||
if( zSql==0 ) rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
int i;
|
||||
const char *zSep = "";
|
||||
@@ -2918,7 +2919,8 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){
|
||||
static int sessionChangesetNext(
|
||||
sqlite3_changeset_iter *p, /* Changeset iterator */
|
||||
u8 **paRec, /* If non-NULL, store record pointer here */
|
||||
int *pnRec /* If non-NULL, store size of record here */
|
||||
int *pnRec, /* If non-NULL, store size of record here */
|
||||
int *pbNew /* If non-NULL, true if new table */
|
||||
){
|
||||
int i;
|
||||
u8 op;
|
||||
@@ -2953,6 +2955,7 @@ static int sessionChangesetNext(
|
||||
|
||||
op = p->in.aData[p->in.iNext++];
|
||||
while( op=='T' || op=='P' ){
|
||||
if( pbNew ) *pbNew = 1;
|
||||
p->bPatchset = (op=='P');
|
||||
if( sessionChangesetReadTblhdr(p) ) return p->rc;
|
||||
if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc;
|
||||
@@ -3031,7 +3034,7 @@ static int sessionChangesetNext(
|
||||
** callback by changeset_apply().
|
||||
*/
|
||||
int sqlite3changeset_next(sqlite3_changeset_iter *p){
|
||||
return sessionChangesetNext(p, 0, 0);
|
||||
return sessionChangesetNext(p, 0, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3410,6 +3413,8 @@ struct SessionApplyCtx {
|
||||
int bStat1; /* True if table is sqlite_stat1 */
|
||||
int bDeferConstraints; /* True to defer constraints */
|
||||
SessionBuffer constraints; /* Deferred constraints are stored here */
|
||||
SessionBuffer rebase; /* Rebase information (if any) here */
|
||||
int bRebaseStarted; /* If table header is already in rebase */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -3676,7 +3681,6 @@ static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
|
||||
"AND (?4 OR stat IS ?3)"
|
||||
);
|
||||
}
|
||||
assert( rc==SQLITE_OK );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -3791,6 +3795,54 @@ static int sessionSeekToRow(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is called from within sqlite3changset_apply_v2() when
|
||||
** a conflict is encountered and resolved using conflict resolution
|
||||
** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE)..
|
||||
** It adds a conflict resolution record to the buffer in
|
||||
** SessionApplyCtx.rebase, which will eventually be returned to the caller
|
||||
** of apply_v2() as the "rebase" buffer.
|
||||
**
|
||||
** Return SQLITE_OK if successful, or an SQLite error code otherwise.
|
||||
*/
|
||||
static int sessionRebaseAdd(
|
||||
SessionApplyCtx *p, /* Apply context */
|
||||
int eType, /* Conflict resolution (OMIT or REPLACE) */
|
||||
sqlite3_changeset_iter *pIter /* Iterator pointing at current change */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
int i;
|
||||
int eOp = pIter->op;
|
||||
if( p->bRebaseStarted==0 ){
|
||||
/* Append a table-header to the rebase buffer */
|
||||
const char *zTab = pIter->zTab;
|
||||
sessionAppendByte(&p->rebase, 'T', &rc);
|
||||
sessionAppendVarint(&p->rebase, p->nCol, &rc);
|
||||
sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc);
|
||||
sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc);
|
||||
p->bRebaseStarted = 1;
|
||||
}
|
||||
|
||||
assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT );
|
||||
assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE );
|
||||
|
||||
sessionAppendByte(&p->rebase,
|
||||
(eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc
|
||||
);
|
||||
sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc);
|
||||
for(i=0; i<p->nCol; i++){
|
||||
sqlite3_value *pVal = 0;
|
||||
if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){
|
||||
sqlite3changeset_old(pIter, i, &pVal);
|
||||
}else{
|
||||
sqlite3changeset_new(pIter, i, &pVal);
|
||||
}
|
||||
sessionAppendValue(&p->rebase, pVal, &rc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Invoke the conflict handler for the change that the changeset iterator
|
||||
** currently points to.
|
||||
@@ -3866,7 +3918,7 @@ static int sessionConflictHandler(
|
||||
u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent];
|
||||
int nBlob = pIter->in.iNext - pIter->in.iCurrent;
|
||||
sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc);
|
||||
res = SQLITE_CHANGESET_OMIT;
|
||||
return SQLITE_OK;
|
||||
}else{
|
||||
/* No other row with the new.* primary key. */
|
||||
res = xConflict(pCtx, eType+1, pIter);
|
||||
@@ -3892,6 +3944,9 @@ static int sessionConflictHandler(
|
||||
rc = SQLITE_MISUSE;
|
||||
break;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionRebaseAdd(p, res, pIter);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -4067,42 +4122,42 @@ static int sessionApplyOneWithRetry(
|
||||
int rc;
|
||||
|
||||
rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry);
|
||||
assert( rc==SQLITE_OK || (bRetry==0 && bReplace==0) );
|
||||
|
||||
/* If the bRetry flag is set, the change has not been applied due to an
|
||||
** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and
|
||||
** a row with the correct PK is present in the db, but one or more other
|
||||
** fields do not contain the expected values) and the conflict handler
|
||||
** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation,
|
||||
** but pass NULL as the final argument so that sessionApplyOneOp() ignores
|
||||
** the SQLITE_CHANGESET_DATA problem. */
|
||||
if( bRetry ){
|
||||
assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE );
|
||||
rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
|
||||
}
|
||||
|
||||
/* If the bReplace flag is set, the change is an INSERT that has not
|
||||
** been performed because the database already contains a row with the
|
||||
** specified primary key and the conflict handler returned
|
||||
** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row
|
||||
** before reattempting the INSERT. */
|
||||
else if( bReplace ){
|
||||
assert( pIter->op==SQLITE_INSERT );
|
||||
rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionBindRow(pIter,
|
||||
sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete);
|
||||
sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_step(pApply->pDelete);
|
||||
rc = sqlite3_reset(pApply->pDelete);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
if( rc==SQLITE_OK ){
|
||||
/* If the bRetry flag is set, the change has not been applied due to an
|
||||
** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and
|
||||
** a row with the correct PK is present in the db, but one or more other
|
||||
** fields do not contain the expected values) and the conflict handler
|
||||
** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation,
|
||||
** but pass NULL as the final argument so that sessionApplyOneOp() ignores
|
||||
** the SQLITE_CHANGESET_DATA problem. */
|
||||
if( bRetry ){
|
||||
assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE );
|
||||
rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0);
|
||||
|
||||
/* If the bReplace flag is set, the change is an INSERT that has not
|
||||
** been performed because the database already contains a row with the
|
||||
** specified primary key and the conflict handler returned
|
||||
** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row
|
||||
** before reattempting the INSERT. */
|
||||
else if( bReplace ){
|
||||
assert( pIter->op==SQLITE_INSERT );
|
||||
rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionBindRow(pIter,
|
||||
sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete);
|
||||
sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_step(pApply->pDelete);
|
||||
rc = sqlite3_reset(pApply->pDelete);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4178,7 +4233,8 @@ static int sessionChangesetApply(
|
||||
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||
sqlite3_changeset_iter *p /* Handle describing change and conflict */
|
||||
),
|
||||
void *pCtx /* First argument passed to xConflict */
|
||||
void *pCtx, /* First argument passed to xConflict */
|
||||
void **ppRebase, int *pnRebase /* OUT: Rebase information */
|
||||
){
|
||||
int schemaMismatch = 0;
|
||||
int rc; /* Return code */
|
||||
@@ -4216,9 +4272,18 @@ static int sessionChangesetApply(
|
||||
sqlite3_finalize(sApply.pUpdate);
|
||||
sqlite3_finalize(sApply.pInsert);
|
||||
sqlite3_finalize(sApply.pSelect);
|
||||
memset(&sApply, 0, sizeof(sApply));
|
||||
sApply.db = db;
|
||||
sApply.pDelete = 0;
|
||||
sApply.pUpdate = 0;
|
||||
sApply.pInsert = 0;
|
||||
sApply.pSelect = 0;
|
||||
sApply.nCol = 0;
|
||||
sApply.azCol = 0;
|
||||
sApply.abPK = 0;
|
||||
sApply.bStat1 = 0;
|
||||
sApply.bDeferConstraints = 1;
|
||||
sApply.bRebaseStarted = 0;
|
||||
memset(&sApply.constraints, 0, sizeof(SessionBuffer));
|
||||
|
||||
/* If an xFilter() callback was specified, invoke it now. If the
|
||||
** xFilter callback returns zero, skip this table. If it returns
|
||||
@@ -4328,16 +4393,52 @@ static int sessionChangesetApply(
|
||||
sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK && bPatchset==0 && ppRebase && pnRebase ){
|
||||
*ppRebase = (void*)sApply.rebase.aBuf;
|
||||
*pnRebase = sApply.rebase.nBuf;
|
||||
sApply.rebase.aBuf = 0;
|
||||
}
|
||||
sqlite3_finalize(sApply.pInsert);
|
||||
sqlite3_finalize(sApply.pDelete);
|
||||
sqlite3_finalize(sApply.pUpdate);
|
||||
sqlite3_finalize(sApply.pSelect);
|
||||
sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */
|
||||
sqlite3_free((char*)sApply.constraints.aBuf);
|
||||
sqlite3_free((char*)sApply.rebase.aBuf);
|
||||
sqlite3_mutex_leave(sqlite3_db_mutex(db));
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Apply the changeset passed via pChangeset/nChangeset to the main
|
||||
** database attached to handle "db".
|
||||
*/
|
||||
int sqlite3changeset_apply_v2(
|
||||
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||
int nChangeset, /* Size of changeset in bytes */
|
||||
void *pChangeset, /* Changeset blob */
|
||||
int(*xFilter)(
|
||||
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||
const char *zTab /* Table name */
|
||||
),
|
||||
int(*xConflict)(
|
||||
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||
sqlite3_changeset_iter *p /* Handle describing change and conflict */
|
||||
),
|
||||
void *pCtx, /* First argument passed to xConflict */
|
||||
void **ppRebase, int *pnRebase
|
||||
){
|
||||
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
|
||||
int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionChangesetApply(
|
||||
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase
|
||||
);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Apply the changeset passed via pChangeset/nChangeset to the main database
|
||||
** attached to handle "db". Invoke the supplied conflict handler callback
|
||||
@@ -4358,12 +4459,9 @@ int sqlite3changeset_apply(
|
||||
),
|
||||
void *pCtx /* First argument passed to xConflict */
|
||||
){
|
||||
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
|
||||
int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx);
|
||||
}
|
||||
return rc;
|
||||
return sqlite3changeset_apply_v2(
|
||||
db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4371,6 +4469,31 @@ int sqlite3changeset_apply(
|
||||
** attached to handle "db". Invoke the supplied conflict handler callback
|
||||
** to resolve any conflicts encountered while applying the change.
|
||||
*/
|
||||
int sqlite3changeset_apply_v2_strm(
|
||||
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
|
||||
void *pIn, /* First arg for xInput */
|
||||
int(*xFilter)(
|
||||
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||
const char *zTab /* Table name */
|
||||
),
|
||||
int(*xConflict)(
|
||||
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||
sqlite3_changeset_iter *p /* Handle describing change and conflict */
|
||||
),
|
||||
void *pCtx, /* First argument passed to xConflict */
|
||||
void **ppRebase, int *pnRebase
|
||||
){
|
||||
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
|
||||
int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionChangesetApply(
|
||||
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase
|
||||
);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
int sqlite3changeset_apply_strm(
|
||||
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
|
||||
@@ -4386,12 +4509,9 @@ int sqlite3changeset_apply_strm(
|
||||
),
|
||||
void *pCtx /* First argument passed to xConflict */
|
||||
){
|
||||
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
|
||||
int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx);
|
||||
}
|
||||
return rc;
|
||||
return sqlite3changeset_apply_v2_strm(
|
||||
db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4410,6 +4530,7 @@ struct sqlite3_changegroup {
|
||||
*/
|
||||
static int sessionChangeMerge(
|
||||
SessionTable *pTab, /* Table structure */
|
||||
int bRebase, /* True for a rebase hash-table */
|
||||
int bPatchset, /* True for patchsets */
|
||||
SessionChange *pExist, /* Existing change */
|
||||
int op2, /* Second change operation */
|
||||
@@ -4419,6 +4540,7 @@ static int sessionChangeMerge(
|
||||
SessionChange **ppNew /* OUT: Merged change */
|
||||
){
|
||||
SessionChange *pNew = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
if( !pExist ){
|
||||
pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec);
|
||||
@@ -4428,9 +4550,66 @@ static int sessionChangeMerge(
|
||||
memset(pNew, 0, sizeof(SessionChange));
|
||||
pNew->op = op2;
|
||||
pNew->bIndirect = bIndirect;
|
||||
pNew->nRecord = nRec;
|
||||
pNew->aRecord = (u8*)&pNew[1];
|
||||
memcpy(pNew->aRecord, aRec, nRec);
|
||||
if( bIndirect==0 || bRebase==0 ){
|
||||
pNew->nRecord = nRec;
|
||||
memcpy(pNew->aRecord, aRec, nRec);
|
||||
}else{
|
||||
int i;
|
||||
u8 *pIn = aRec;
|
||||
u8 *pOut = pNew->aRecord;
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
int nIn = sessionSerialLen(pIn);
|
||||
if( *pIn==0 ){
|
||||
*pOut++ = 0;
|
||||
}else if( pTab->abPK[i]==0 ){
|
||||
*pOut++ = 0xFF;
|
||||
}else{
|
||||
memcpy(pOut, pIn, nIn);
|
||||
pOut += nIn;
|
||||
}
|
||||
pIn += nIn;
|
||||
}
|
||||
pNew->nRecord = pOut - pNew->aRecord;
|
||||
}
|
||||
}else if( bRebase ){
|
||||
if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){
|
||||
*ppNew = pExist;
|
||||
}else{
|
||||
int nByte = nRec + pExist->nRecord + sizeof(SessionChange);
|
||||
pNew = (SessionChange*)sqlite3_malloc(nByte);
|
||||
if( pNew==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
int i;
|
||||
u8 *a1 = pExist->aRecord;
|
||||
u8 *a2 = aRec;
|
||||
u8 *pOut;
|
||||
|
||||
memset(pNew, 0, nByte);
|
||||
pNew->bIndirect = bIndirect || pExist->bIndirect;
|
||||
pNew->op = op2;
|
||||
pOut = pNew->aRecord = (u8*)&pNew[1];
|
||||
|
||||
for(i=0; i<pTab->nCol; i++){
|
||||
int n1 = sessionSerialLen(a1);
|
||||
int n2 = sessionSerialLen(a2);
|
||||
if( *a1==0xFF || (pTab->abPK[i]==0 && bIndirect) ){
|
||||
*pOut++ = 0xFF;
|
||||
}else if( *a2==0 ){
|
||||
memcpy(pOut, a1, n1);
|
||||
pOut += n1;
|
||||
}else{
|
||||
memcpy(pOut, a2, n2);
|
||||
pOut += n2;
|
||||
}
|
||||
a1 += n1;
|
||||
a2 += n2;
|
||||
}
|
||||
pNew->nRecord = pOut - pNew->aRecord;
|
||||
}
|
||||
sqlite3_free(pExist);
|
||||
}
|
||||
}else{
|
||||
int op1 = pExist->op;
|
||||
|
||||
@@ -4524,7 +4703,7 @@ static int sessionChangeMerge(
|
||||
}
|
||||
|
||||
*ppNew = pNew;
|
||||
return SQLITE_OK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4533,15 +4712,15 @@ static int sessionChangeMerge(
|
||||
*/
|
||||
static int sessionChangesetToHash(
|
||||
sqlite3_changeset_iter *pIter, /* Iterator to read from */
|
||||
sqlite3_changegroup *pGrp /* Changegroup object to add changeset to */
|
||||
sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */
|
||||
int bRebase /* True if hash table is for rebasing */
|
||||
){
|
||||
u8 *aRec;
|
||||
int nRec;
|
||||
int rc = SQLITE_OK;
|
||||
SessionTable *pTab = 0;
|
||||
|
||||
|
||||
while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec) ){
|
||||
while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){
|
||||
const char *zNew;
|
||||
int nCol;
|
||||
int op;
|
||||
@@ -4621,7 +4800,7 @@ static int sessionChangesetToHash(
|
||||
}
|
||||
}
|
||||
|
||||
rc = sessionChangeMerge(pTab,
|
||||
rc = sessionChangeMerge(pTab, bRebase,
|
||||
pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange
|
||||
);
|
||||
if( rc ) break;
|
||||
@@ -4729,7 +4908,7 @@ int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){
|
||||
|
||||
rc = sqlite3changeset_start(&pIter, nData, pData);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionChangesetToHash(pIter, pGrp);
|
||||
rc = sessionChangesetToHash(pIter, pGrp, 0);
|
||||
}
|
||||
sqlite3changeset_finalize(pIter);
|
||||
return rc;
|
||||
@@ -4760,7 +4939,7 @@ int sqlite3changegroup_add_strm(
|
||||
|
||||
rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionChangesetToHash(pIter, pGrp);
|
||||
rc = sessionChangesetToHash(pIter, pGrp, 0);
|
||||
}
|
||||
sqlite3changeset_finalize(pIter);
|
||||
return rc;
|
||||
@@ -4845,4 +5024,347 @@ int sqlite3changeset_concat_strm(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Changeset rebaser handle.
|
||||
*/
|
||||
struct sqlite3_rebaser {
|
||||
sqlite3_changegroup grp; /* Hash table */
|
||||
};
|
||||
|
||||
/*
|
||||
** Buffers a1 and a2 must both contain a sessions module record nCol
|
||||
** fields in size. This function appends an nCol sessions module
|
||||
** record to buffer pBuf that is a copy of a1, except that for
|
||||
** each field that is undefined in a1[], swap in the field from a2[].
|
||||
*/
|
||||
static void sessionAppendRecordMerge(
|
||||
SessionBuffer *pBuf, /* Buffer to append to */
|
||||
int nCol, /* Number of columns in each record */
|
||||
u8 *a1, int n1, /* Record 1 */
|
||||
u8 *a2, int n2, /* Record 2 */
|
||||
int *pRc /* IN/OUT: error code */
|
||||
){
|
||||
sessionBufferGrow(pBuf, n1+n2, pRc);
|
||||
if( *pRc==SQLITE_OK ){
|
||||
int i;
|
||||
u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
|
||||
for(i=0; i<nCol; i++){
|
||||
int nn1 = sessionSerialLen(a1);
|
||||
int nn2 = sessionSerialLen(a2);
|
||||
if( *a1==0 || *a1==0xFF ){
|
||||
memcpy(pOut, a2, nn2);
|
||||
pOut += nn2;
|
||||
}else{
|
||||
memcpy(pOut, a1, nn1);
|
||||
pOut += nn1;
|
||||
}
|
||||
a1 += nn1;
|
||||
a2 += nn2;
|
||||
}
|
||||
|
||||
pBuf->nBuf = pOut-pBuf->aBuf;
|
||||
assert( pBuf->nBuf<=pBuf->nAlloc );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is called when rebasing a local UPDATE change against one
|
||||
** or more remote UPDATE changes. The aRec/nRec buffer contains the current
|
||||
** old.* and new.* records for the change. The rebase buffer (a single
|
||||
** record) is in aChange/nChange. The rebased change is appended to buffer
|
||||
** pBuf.
|
||||
**
|
||||
** Rebasing the UPDATE involves:
|
||||
**
|
||||
** * Removing any changes to fields for which the corresponding field
|
||||
** in the rebase buffer is set to "replaced" (type 0xFF). If this
|
||||
** means the UPDATE change updates no fields, nothing is appended
|
||||
** to the output buffer.
|
||||
**
|
||||
** * For each field modified by the local change for which the
|
||||
** corresponding field in the rebase buffer is not "undefined" (0x00)
|
||||
** or "replaced" (0xFF), the old.* value is replaced by the value
|
||||
** in the rebase buffer.
|
||||
*/
|
||||
static void sessionAppendPartialUpdate(
|
||||
SessionBuffer *pBuf, /* Append record here */
|
||||
sqlite3_changeset_iter *pIter, /* Iterator pointed at local change */
|
||||
u8 *aRec, int nRec, /* Local change */
|
||||
u8 *aChange, int nChange, /* Record to rebase against */
|
||||
int *pRc /* IN/OUT: Return Code */
|
||||
){
|
||||
sessionBufferGrow(pBuf, 2+nRec+nChange, pRc);
|
||||
if( *pRc==SQLITE_OK ){
|
||||
int bData = 0;
|
||||
u8 *pOut = &pBuf->aBuf[pBuf->nBuf];
|
||||
int i;
|
||||
u8 *a1 = aRec;
|
||||
u8 *a2 = aChange;
|
||||
|
||||
*pOut++ = SQLITE_UPDATE;
|
||||
*pOut++ = pIter->bIndirect;
|
||||
for(i=0; i<pIter->nCol; i++){
|
||||
int n1 = sessionSerialLen(a1);
|
||||
int n2 = sessionSerialLen(a2);
|
||||
if( pIter->abPK[i] || a2[0]==0 ){
|
||||
if( !pIter->abPK[i] ) bData = 1;
|
||||
memcpy(pOut, a1, n1);
|
||||
pOut += n1;
|
||||
}else if( a2[0]!=0xFF ){
|
||||
bData = 1;
|
||||
memcpy(pOut, a2, n2);
|
||||
pOut += n2;
|
||||
}else{
|
||||
*pOut++ = '\0';
|
||||
}
|
||||
a1 += n1;
|
||||
a2 += n2;
|
||||
}
|
||||
if( bData ){
|
||||
a2 = aChange;
|
||||
for(i=0; i<pIter->nCol; i++){
|
||||
int n1 = sessionSerialLen(a1);
|
||||
int n2 = sessionSerialLen(a2);
|
||||
if( pIter->abPK[i] || a2[0]!=0xFF ){
|
||||
memcpy(pOut, a1, n1);
|
||||
pOut += n1;
|
||||
}else{
|
||||
*pOut++ = '\0';
|
||||
}
|
||||
a1 += n1;
|
||||
a2 += n2;
|
||||
}
|
||||
pBuf->nBuf = (pOut - pBuf->aBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** pIter is configured to iterate through a changeset. This function rebases
|
||||
** that changeset according to the current configuration of the rebaser
|
||||
** object passed as the first argument. If no error occurs and argument xOutput
|
||||
** is not NULL, then the changeset is returned to the caller by invoking
|
||||
** xOutput zero or more times and SQLITE_OK returned. Or, if xOutput is NULL,
|
||||
** then (*ppOut) is set to point to a buffer containing the rebased changeset
|
||||
** before this function returns. In this case (*pnOut) is set to the size of
|
||||
** the buffer in bytes. It is the responsibility of the caller to eventually
|
||||
** free the (*ppOut) buffer using sqlite3_free().
|
||||
**
|
||||
** If an error occurs, an SQLite error code is returned. If ppOut and
|
||||
** pnOut are not NULL, then the two output parameters are set to 0 before
|
||||
** returning.
|
||||
*/
|
||||
static int sessionRebase(
|
||||
sqlite3_rebaser *p, /* Rebaser hash table */
|
||||
sqlite3_changeset_iter *pIter, /* Input data */
|
||||
int (*xOutput)(void *pOut, const void *pData, int nData),
|
||||
void *pOut, /* Context for xOutput callback */
|
||||
int *pnOut, /* OUT: Number of bytes in output changeset */
|
||||
void **ppOut /* OUT: Inverse of pChangeset */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
u8 *aRec = 0;
|
||||
int nRec = 0;
|
||||
int bNew = 0;
|
||||
SessionTable *pTab = 0;
|
||||
SessionBuffer sOut = {0,0,0};
|
||||
|
||||
while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, &bNew) ){
|
||||
SessionChange *pChange = 0;
|
||||
int bDone = 0;
|
||||
|
||||
if( bNew ){
|
||||
const char *zTab = pIter->zTab;
|
||||
for(pTab=p->grp.pList; pTab; pTab=pTab->pNext){
|
||||
if( 0==sqlite3_stricmp(pTab->zName, zTab) ) break;
|
||||
}
|
||||
bNew = 0;
|
||||
|
||||
/* A patchset may not be rebased */
|
||||
if( pIter->bPatchset ){
|
||||
rc = SQLITE_ERROR;
|
||||
}
|
||||
|
||||
/* Append a table header to the output for this new table */
|
||||
sessionAppendByte(&sOut, pIter->bPatchset ? 'P' : 'T', &rc);
|
||||
sessionAppendVarint(&sOut, pIter->nCol, &rc);
|
||||
sessionAppendBlob(&sOut, pIter->abPK, pIter->nCol, &rc);
|
||||
sessionAppendBlob(&sOut,(u8*)pIter->zTab,(int)strlen(pIter->zTab)+1,&rc);
|
||||
}
|
||||
|
||||
if( pTab && rc==SQLITE_OK ){
|
||||
int iHash = sessionChangeHash(pTab, 0, aRec, pTab->nChange);
|
||||
|
||||
for(pChange=pTab->apChange[iHash]; pChange; pChange=pChange->pNext){
|
||||
if( sessionChangeEqual(pTab, 0, aRec, 0, pChange->aRecord) ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pChange ){
|
||||
assert( pChange->op==SQLITE_DELETE || pChange->op==SQLITE_INSERT );
|
||||
switch( pIter->op ){
|
||||
case SQLITE_INSERT:
|
||||
if( pChange->op==SQLITE_INSERT ){
|
||||
bDone = 1;
|
||||
if( pChange->bIndirect==0 ){
|
||||
sessionAppendByte(&sOut, SQLITE_UPDATE, &rc);
|
||||
sessionAppendByte(&sOut, pIter->bIndirect, &rc);
|
||||
sessionAppendBlob(&sOut, pChange->aRecord, pChange->nRecord, &rc);
|
||||
sessionAppendBlob(&sOut, aRec, nRec, &rc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SQLITE_UPDATE:
|
||||
bDone = 1;
|
||||
if( pChange->op==SQLITE_DELETE ){
|
||||
if( pChange->bIndirect==0 ){
|
||||
u8 *pCsr = aRec;
|
||||
sessionSkipRecord(&pCsr, pIter->nCol);
|
||||
sessionAppendByte(&sOut, SQLITE_INSERT, &rc);
|
||||
sessionAppendByte(&sOut, pIter->bIndirect, &rc);
|
||||
sessionAppendRecordMerge(&sOut, pIter->nCol,
|
||||
pCsr, nRec-(pCsr-aRec),
|
||||
pChange->aRecord, pChange->nRecord, &rc
|
||||
);
|
||||
}
|
||||
}else{
|
||||
sessionAppendPartialUpdate(&sOut, pIter,
|
||||
aRec, nRec, pChange->aRecord, pChange->nRecord, &rc
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert( pIter->op==SQLITE_DELETE );
|
||||
bDone = 1;
|
||||
if( pChange->op==SQLITE_INSERT ){
|
||||
sessionAppendByte(&sOut, SQLITE_DELETE, &rc);
|
||||
sessionAppendByte(&sOut, pIter->bIndirect, &rc);
|
||||
sessionAppendRecordMerge(&sOut, pIter->nCol,
|
||||
pChange->aRecord, pChange->nRecord, aRec, nRec, &rc
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( bDone==0 ){
|
||||
sessionAppendByte(&sOut, pIter->op, &rc);
|
||||
sessionAppendByte(&sOut, pIter->bIndirect, &rc);
|
||||
sessionAppendBlob(&sOut, aRec, nRec, &rc);
|
||||
}
|
||||
if( rc==SQLITE_OK && xOutput && sOut.nBuf>SESSIONS_STRM_CHUNK_SIZE ){
|
||||
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
|
||||
sOut.nBuf = 0;
|
||||
}
|
||||
if( rc ) break;
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_free(sOut.aBuf);
|
||||
memset(&sOut, 0, sizeof(sOut));
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
if( xOutput ){
|
||||
if( sOut.nBuf>0 ){
|
||||
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
|
||||
}
|
||||
}else{
|
||||
*ppOut = (void*)sOut.aBuf;
|
||||
*pnOut = sOut.nBuf;
|
||||
sOut.aBuf = 0;
|
||||
}
|
||||
}
|
||||
sqlite3_free(sOut.aBuf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Create a new rebaser object.
|
||||
*/
|
||||
int sqlite3rebaser_create(sqlite3_rebaser **ppNew){
|
||||
int rc = SQLITE_OK;
|
||||
sqlite3_rebaser *pNew;
|
||||
|
||||
pNew = sqlite3_malloc(sizeof(sqlite3_rebaser));
|
||||
if( pNew==0 ){
|
||||
rc = SQLITE_NOMEM;
|
||||
}else{
|
||||
memset(pNew, 0, sizeof(sqlite3_rebaser));
|
||||
}
|
||||
*ppNew = pNew;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Call this one or more times to configure a rebaser.
|
||||
*/
|
||||
int sqlite3rebaser_configure(
|
||||
sqlite3_rebaser *p,
|
||||
int nRebase, const void *pRebase
|
||||
){
|
||||
sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */
|
||||
int rc; /* Return code */
|
||||
rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionChangesetToHash(pIter, &p->grp, 1);
|
||||
}
|
||||
sqlite3changeset_finalize(pIter);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Rebase a changeset according to current rebaser configuration
|
||||
*/
|
||||
int sqlite3rebaser_rebase(
|
||||
sqlite3_rebaser *p,
|
||||
int nIn, const void *pIn,
|
||||
int *pnOut, void **ppOut
|
||||
){
|
||||
sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */
|
||||
int rc = sqlite3changeset_start(&pIter, nIn, (void*)pIn);
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionRebase(p, pIter, 0, 0, pnOut, ppOut);
|
||||
sqlite3changeset_finalize(pIter);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Rebase a changeset according to current rebaser configuration
|
||||
*/
|
||||
int sqlite3rebaser_rebase_strm(
|
||||
sqlite3_rebaser *p,
|
||||
int (*xInput)(void *pIn, void *pData, int *pnData),
|
||||
void *pIn,
|
||||
int (*xOutput)(void *pOut, const void *pData, int nData),
|
||||
void *pOut
|
||||
){
|
||||
sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */
|
||||
int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn);
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sessionRebase(p, pIter, xOutput, pOut, 0, 0);
|
||||
sqlite3changeset_finalize(pIter);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Destroy a rebaser object
|
||||
*/
|
||||
void sqlite3rebaser_delete(sqlite3_rebaser *p){
|
||||
if( p ){
|
||||
sessionDeleteTable(p->grp.pList);
|
||||
sqlite3_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
|
||||
|
||||
+215
-12
@@ -948,19 +948,18 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
|
||||
/*
|
||||
** CAPI3REF: Apply A Changeset To A Database
|
||||
**
|
||||
** Apply a changeset to a database. This function attempts to update the
|
||||
** "main" database attached to handle db with the changes found in the
|
||||
** changeset passed via the second and third arguments.
|
||||
** Apply a changeset or patchset to a database. These functions attempt to
|
||||
** update the "main" database attached to handle db with the changes found in
|
||||
** the changeset passed via the second and third arguments.
|
||||
**
|
||||
** The fourth argument (xFilter) passed to this function is the "filter
|
||||
** The fourth argument (xFilter) passed to these functions is the "filter
|
||||
** callback". If it is not NULL, then for each table affected by at least one
|
||||
** change in the changeset, the filter callback is invoked with
|
||||
** the table name as the second argument, and a copy of the context pointer
|
||||
** passed as the sixth argument to this function as the first. If the "filter
|
||||
** callback" returns zero, then no attempt is made to apply any changes to
|
||||
** the table. Otherwise, if the return value is non-zero or the xFilter
|
||||
** argument to this function is NULL, all changes related to the table are
|
||||
** attempted.
|
||||
** passed as the sixth argument as the first. If the "filter callback"
|
||||
** returns zero, then no attempt is made to apply any changes to the table.
|
||||
** Otherwise, if the return value is non-zero or the xFilter argument to
|
||||
** is NULL, all changes related to the table are attempted.
|
||||
**
|
||||
** For each table that is not excluded by the filter callback, this function
|
||||
** tests that the target database contains a compatible table. A table is
|
||||
@@ -1005,7 +1004,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
|
||||
**
|
||||
** <dl>
|
||||
** <dt>DELETE Changes<dd>
|
||||
** For each DELETE change, this function checks if the target database
|
||||
** For each DELETE change, the function checks if the target database
|
||||
** contains a row with the same primary key value (or values) as the
|
||||
** original row values stored in the changeset. If it does, and the values
|
||||
** stored in all non-primary key columns also match the values stored in
|
||||
@@ -1050,7 +1049,7 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
|
||||
** [SQLITE_CHANGESET_REPLACE].
|
||||
**
|
||||
** <dt>UPDATE Changes<dd>
|
||||
** For each UPDATE change, this function checks if the target database
|
||||
** For each UPDATE change, the function checks if the target database
|
||||
** contains a row with the same primary key value (or values) as the
|
||||
** original row values stored in the changeset. If it does, and the values
|
||||
** stored in all modified non-primary key columns also match the values
|
||||
@@ -1081,11 +1080,21 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
|
||||
** This can be used to further customize the applications conflict
|
||||
** resolution strategy.
|
||||
**
|
||||
** All changes made by this function are enclosed in a savepoint transaction.
|
||||
** All changes made by these functions are enclosed in a savepoint transaction.
|
||||
** If any other error (aside from a constraint failure when attempting to
|
||||
** write to the target database) occurs, then the savepoint transaction is
|
||||
** rolled back, restoring the target database to its original state, and an
|
||||
** SQLite error code returned.
|
||||
**
|
||||
** If the output parameters (ppRebase) and (pnRebase) are non-NULL and
|
||||
** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()
|
||||
** may set (*ppRebase) to point to a "rebase" that may be used with the
|
||||
** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)
|
||||
** is set to the size of the buffer in bytes. It is the responsibility of the
|
||||
** caller to eventually free any such buffer using sqlite3_free(). The buffer
|
||||
** is only allocated and populated if one or more conflicts were encountered
|
||||
** while applying the patchset. See comments surrounding the sqlite3_rebaser
|
||||
** APIs for further details.
|
||||
*/
|
||||
int sqlite3changeset_apply(
|
||||
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||
@@ -1102,6 +1111,22 @@ int sqlite3changeset_apply(
|
||||
),
|
||||
void *pCtx /* First argument passed to xConflict */
|
||||
);
|
||||
int sqlite3changeset_apply_v2(
|
||||
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||
int nChangeset, /* Size of changeset in bytes */
|
||||
void *pChangeset, /* Changeset blob */
|
||||
int(*xFilter)(
|
||||
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||
const char *zTab /* Table name */
|
||||
),
|
||||
int(*xConflict)(
|
||||
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||
sqlite3_changeset_iter *p /* Handle describing change and conflict */
|
||||
),
|
||||
void *pCtx, /* First argument passed to xConflict */
|
||||
void **ppRebase, int *pnRebase
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Constants Passed To The Conflict Handler
|
||||
@@ -1199,6 +1224,161 @@ int sqlite3changeset_apply(
|
||||
#define SQLITE_CHANGESET_REPLACE 1
|
||||
#define SQLITE_CHANGESET_ABORT 2
|
||||
|
||||
/*
|
||||
** CAPI3REF: Rebasing changesets
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** Suppose there is a site hosting a database in state S0. And that
|
||||
** modifications are made that move that database to state S1 and a
|
||||
** changeset recorded (the "local" changeset). Then, a changeset based
|
||||
** on S0 is received from another site (the "remote" changeset) and
|
||||
** applied to the database. The database is then in state
|
||||
** (S1+"remote"), where the exact state depends on any conflict
|
||||
** resolution decisions (OMIT or REPLACE) made while applying "remote".
|
||||
** Rebasing a changeset is to update it to take those conflict
|
||||
** resolution decisions into account, so that the same conflicts
|
||||
** do not have to be resolved elsewhere in the network.
|
||||
**
|
||||
** For example, if both the local and remote changesets contain an
|
||||
** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)":
|
||||
**
|
||||
** local: INSERT INTO t1 VALUES(1, 'v1');
|
||||
** remote: INSERT INTO t1 VALUES(1, 'v2');
|
||||
**
|
||||
** and the conflict resolution is REPLACE, then the INSERT change is
|
||||
** removed from the local changeset (it was overridden). Or, if the
|
||||
** conflict resolution was "OMIT", then the local changeset is modified
|
||||
** to instead contain:
|
||||
**
|
||||
** UPDATE t1 SET b = 'v2' WHERE a=1;
|
||||
**
|
||||
** Changes within the local changeset are rebased as follows:
|
||||
**
|
||||
** <dl>
|
||||
** <dt>Local INSERT<dd>
|
||||
** This may only conflict with a remote INSERT. If the conflict
|
||||
** resolution was OMIT, then add an UPDATE change to the rebased
|
||||
** changeset. Or, if the conflict resolution was REPLACE, add
|
||||
** nothing to the rebased changeset.
|
||||
**
|
||||
** <dt>Local DELETE<dd>
|
||||
** This may conflict with a remote UPDATE or DELETE. In both cases the
|
||||
** only possible resolution is OMIT. If the remote operation was a
|
||||
** DELETE, then add no change to the rebased changeset. If the remote
|
||||
** operation was an UPDATE, then the old.* fields of change are updated
|
||||
** to reflect the new.* values in the UPDATE.
|
||||
**
|
||||
** <dt>Local UPDATE<dd>
|
||||
** This may conflict with a remote UPDATE or DELETE. If it conflicts
|
||||
** with a DELETE, and the conflict resolution was OMIT, then the update
|
||||
** is changed into an INSERT. Any undefined values in the new.* record
|
||||
** from the update change are filled in using the old.* values from
|
||||
** the conflicting DELETE. Or, if the conflict resolution was REPLACE,
|
||||
** the UPDATE change is simply omitted from the rebased changeset.
|
||||
**
|
||||
** If conflict is with a remote UPDATE and the resolution is OMIT, then
|
||||
** the old.* values are rebased using the new.* values in the remote
|
||||
** change. Or, if the resolution is REPLACE, then the change is copied
|
||||
** into the rebased changeset with updates to columns also updated by
|
||||
** the conflicting remote UPDATE removed. If this means no columns would
|
||||
** be updated, the change is omitted.
|
||||
** </dl>
|
||||
**
|
||||
** A local change may be rebased against multiple remote changes
|
||||
** simultaneously. If a single key is modified by multiple remote
|
||||
** changesets, they are combined as follows before the local changeset
|
||||
** is rebased:
|
||||
**
|
||||
** <ul>
|
||||
** <li> If there has been one or more REPLACE resolutions on a
|
||||
** key, it is rebased according to a REPLACE.
|
||||
**
|
||||
** <li> If there have been no REPLACE resolutions on a key, then
|
||||
** the local changeset is rebased according to the most recent
|
||||
** of the OMIT resolutions.
|
||||
** </ul>
|
||||
**
|
||||
** Note that conflict resolutions from multiple remote changesets are
|
||||
** combined on a per-field basis, not per-row. This means that in the
|
||||
** case of multiple remote UPDATE operations, some fields of a single
|
||||
** local change may be rebased for REPLACE while others are rebased for
|
||||
** OMIT.
|
||||
**
|
||||
** In order to rebase a local changeset, the remote changeset must first
|
||||
** be applied to the local database using sqlite3changeset_apply_v2() and
|
||||
** the buffer of rebase information captured. Then:
|
||||
**
|
||||
** <ol>
|
||||
** <li> An sqlite3_rebaser object is created by calling
|
||||
** sqlite3rebaser_create().
|
||||
** <li> The new object is configured with the rebase buffer obtained from
|
||||
** sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure().
|
||||
** If the local changeset is to be rebased against multiple remote
|
||||
** changesets, then sqlite3rebaser_configure() should be called
|
||||
** multiple times, in the same order that the multiple
|
||||
** sqlite3changeset_apply_v2() calls were made.
|
||||
** <li> Each local changeset is rebased by calling sqlite3rebaser_rebase().
|
||||
** <li> The sqlite3_rebaser object is deleted by calling
|
||||
** sqlite3rebaser_delete().
|
||||
** </ol>
|
||||
*/
|
||||
typedef struct sqlite3_rebaser sqlite3_rebaser;
|
||||
|
||||
/*
|
||||
** CAPI3REF: Create a changeset rebaser object.
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** Allocate a new changeset rebaser object. If successful, set (*ppNew) to
|
||||
** point to the new object and return SQLITE_OK. Otherwise, if an error
|
||||
** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew)
|
||||
** to NULL.
|
||||
*/
|
||||
int sqlite3rebaser_create(sqlite3_rebaser **ppNew);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Configure a changeset rebaser object.
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** Configure the changeset rebaser object to rebase changesets according
|
||||
** to the conflict resolutions described by buffer pRebase (size nRebase
|
||||
** bytes), which must have been obtained from a previous call to
|
||||
** sqlite3changeset_apply_v2().
|
||||
*/
|
||||
int sqlite3rebaser_configure(
|
||||
sqlite3_rebaser*,
|
||||
int nRebase, const void *pRebase
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Rebase a changeset
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** Argument pIn must point to a buffer containing a changeset nIn bytes
|
||||
** in size. This function allocates and populates a buffer with a copy
|
||||
** of the changeset rebased rebased according to the configuration of the
|
||||
** rebaser object passed as the first argument. If successful, (*ppOut)
|
||||
** is set to point to the new buffer containing the rebased changset and
|
||||
** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
|
||||
** responsibility of the caller to eventually free the new buffer using
|
||||
** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
|
||||
** are set to zero and an SQLite error code returned.
|
||||
*/
|
||||
int sqlite3rebaser_rebase(
|
||||
sqlite3_rebaser*,
|
||||
int nIn, const void *pIn,
|
||||
int *pnOut, void **ppOut
|
||||
);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Delete a changeset rebaser object.
|
||||
** EXPERIMENTAL
|
||||
**
|
||||
** Delete the changeset rebaser object and all associated resources. There
|
||||
** should be one call to this function for each successful invocation
|
||||
** of sqlite3rebaser_create().
|
||||
*/
|
||||
void sqlite3rebaser_delete(sqlite3_rebaser *p);
|
||||
|
||||
/*
|
||||
** CAPI3REF: Streaming Versions of API functions.
|
||||
**
|
||||
@@ -1303,6 +1483,22 @@ int sqlite3changeset_apply_strm(
|
||||
),
|
||||
void *pCtx /* First argument passed to xConflict */
|
||||
);
|
||||
int sqlite3changeset_apply_v2_strm(
|
||||
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
|
||||
void *pIn, /* First arg for xInput */
|
||||
int(*xFilter)(
|
||||
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||
const char *zTab /* Table name */
|
||||
),
|
||||
int(*xConflict)(
|
||||
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||
sqlite3_changeset_iter *p /* Handle describing change and conflict */
|
||||
),
|
||||
void *pCtx, /* First argument passed to xConflict */
|
||||
void **ppRebase, int *pnRebase
|
||||
);
|
||||
int sqlite3changeset_concat_strm(
|
||||
int (*xInputA)(void *pIn, void *pData, int *pnData),
|
||||
void *pInA,
|
||||
@@ -1340,6 +1536,13 @@ int sqlite3changegroup_output_strm(sqlite3_changegroup*,
|
||||
int (*xOutput)(void *pOut, const void *pData, int nData),
|
||||
void *pOut
|
||||
);
|
||||
int sqlite3rebaser_rebase_strm(
|
||||
sqlite3_rebaser *pRebaser,
|
||||
int (*xInput)(void *pIn, void *pData, int *pnData),
|
||||
void *pIn,
|
||||
int (*xOutput)(void *pOut, const void *pData, int nData),
|
||||
void *pOut
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
+180
-11
@@ -14,6 +14,10 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
typedef unsigned char u8;
|
||||
#endif
|
||||
|
||||
typedef struct TestSession TestSession;
|
||||
struct TestSession {
|
||||
sqlite3_session *pSession;
|
||||
@@ -711,10 +715,8 @@ static int testStreamInput(
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** sqlite3changeset_apply DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_sqlite3changeset_apply(
|
||||
static int SQLITE_TCLAPI testSqlite3changesetApply(
|
||||
int bV2,
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
@@ -727,6 +729,8 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply(
|
||||
int nChangeset; /* Size of buffer aChangeset in bytes */
|
||||
TestConflictHandler ctx;
|
||||
TestStreamInput sStr;
|
||||
void *pRebase = 0;
|
||||
int nRebase = 0;
|
||||
|
||||
memset(&sStr, 0, sizeof(sStr));
|
||||
sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR);
|
||||
@@ -748,24 +752,68 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply(
|
||||
ctx.interp = interp;
|
||||
|
||||
if( sStr.nStream==0 ){
|
||||
rc = sqlite3changeset_apply(db, nChangeset, pChangeset,
|
||||
(objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx
|
||||
);
|
||||
if( bV2==0 ){
|
||||
rc = sqlite3changeset_apply(db, nChangeset, pChangeset,
|
||||
(objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx
|
||||
);
|
||||
}else{
|
||||
rc = sqlite3changeset_apply_v2(db, nChangeset, pChangeset,
|
||||
(objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx,
|
||||
&pRebase, &nRebase
|
||||
);
|
||||
}
|
||||
}else{
|
||||
sStr.aData = (unsigned char*)pChangeset;
|
||||
sStr.nData = nChangeset;
|
||||
rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr,
|
||||
(objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx
|
||||
);
|
||||
if( bV2==0 ){
|
||||
rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr,
|
||||
(objc==5) ? test_filter_handler : 0,
|
||||
test_conflict_handler, (void *)&ctx
|
||||
);
|
||||
}else{
|
||||
rc = sqlite3changeset_apply_v2_strm(db, testStreamInput, (void*)&sStr,
|
||||
(objc==5) ? test_filter_handler : 0,
|
||||
test_conflict_handler, (void *)&ctx,
|
||||
&pRebase, &nRebase
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
return test_session_error(interp, rc, 0);
|
||||
}else{
|
||||
Tcl_ResetResult(interp);
|
||||
if( bV2 && pRebase ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pRebase, nRebase));
|
||||
}
|
||||
}
|
||||
Tcl_ResetResult(interp);
|
||||
sqlite3_free(pRebase);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3changeset_apply DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_sqlite3changeset_apply(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
return testSqlite3changesetApply(0, clientData, interp, objc, objv);
|
||||
}
|
||||
/*
|
||||
** sqlite3changeset_apply_v2 DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_sqlite3changeset_apply_v2(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
return testSqlite3changesetApply(1, clientData, interp, objc, objv);
|
||||
}
|
||||
|
||||
/*
|
||||
** sqlite3changeset_apply_replace_all DB CHANGESET
|
||||
*/
|
||||
@@ -1019,6 +1067,125 @@ static int SQLITE_TCLAPI test_sqlite3session_foreach(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: CMD configure REBASE-BLOB
|
||||
** tclcmd: CMD rebase CHANGESET
|
||||
** tclcmd: CMD delete
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_rebaser_cmd(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
struct RebaseSubcmd {
|
||||
const char *zSub;
|
||||
int nArg;
|
||||
const char *zMsg;
|
||||
int iSub;
|
||||
} aSub[] = {
|
||||
{ "configure", 1, "REBASE-BLOB" }, /* 0 */
|
||||
{ "delete", 0, "" }, /* 1 */
|
||||
{ "rebase", 1, "CHANGESET" }, /* 2 */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
sqlite3_rebaser *p = (sqlite3_rebaser*)clientData;
|
||||
int iSub;
|
||||
int rc;
|
||||
|
||||
if( objc<2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = Tcl_GetIndexFromObjStruct(interp,
|
||||
objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub
|
||||
);
|
||||
if( rc!=TCL_OK ) return rc;
|
||||
if( objc!=2+aSub[iSub].nArg ){
|
||||
Tcl_WrongNumArgs(interp, 2, objv, aSub[iSub].zMsg);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
assert( iSub==0 || iSub==1 || iSub==2 );
|
||||
assert( rc==SQLITE_OK );
|
||||
switch( iSub ){
|
||||
case 0: { /* configure */
|
||||
int nRebase = 0;
|
||||
unsigned char *pRebase = Tcl_GetByteArrayFromObj(objv[2], &nRebase);
|
||||
rc = sqlite3rebaser_configure(p, nRebase, pRebase);
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: /* delete */
|
||||
Tcl_DeleteCommand(interp, Tcl_GetString(objv[0]));
|
||||
break;
|
||||
|
||||
default: { /* rebase */
|
||||
TestStreamInput sStr; /* Input stream */
|
||||
TestSessionsBlob sOut; /* Output blob */
|
||||
|
||||
memset(&sStr, 0, sizeof(sStr));
|
||||
memset(&sOut, 0, sizeof(sOut));
|
||||
sStr.aData = Tcl_GetByteArrayFromObj(objv[2], &sStr.nData);
|
||||
sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR);
|
||||
|
||||
if( sStr.nStream ){
|
||||
rc = sqlite3rebaser_rebase_strm(p,
|
||||
testStreamInput, (void*)&sStr,
|
||||
testStreamOutput, (void*)&sOut
|
||||
);
|
||||
}else{
|
||||
rc = sqlite3rebaser_rebase(p, sStr.nData, sStr.aData, &sOut.n, &sOut.p);
|
||||
}
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(sOut.p, sOut.n));
|
||||
}
|
||||
sqlite3_free(sOut.p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
return test_session_error(interp, rc, 0);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static void SQLITE_TCLAPI test_rebaser_del(void *clientData){
|
||||
sqlite3_rebaser *p = (sqlite3_rebaser*)clientData;
|
||||
sqlite3rebaser_delete(p);
|
||||
}
|
||||
|
||||
/*
|
||||
** tclcmd: sqlite3rebaser_create NAME
|
||||
*/
|
||||
static int SQLITE_TCLAPI test_sqlite3rebaser_create(
|
||||
void * clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
int rc;
|
||||
sqlite3_rebaser *pNew = 0;
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "NAME");
|
||||
return SQLITE_ERROR;
|
||||
}
|
||||
|
||||
rc = sqlite3rebaser_create(&pNew);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return test_session_error(interp, rc, 0);
|
||||
}
|
||||
|
||||
Tcl_CreateObjCommand(interp, Tcl_GetString(objv[1]), test_rebaser_cmd,
|
||||
(ClientData)pNew, test_rebaser_del
|
||||
);
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int TestSession_Init(Tcl_Interp *interp){
|
||||
struct Cmd {
|
||||
const char *zCmd;
|
||||
@@ -1029,9 +1196,11 @@ int TestSession_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3changeset_invert", test_sqlite3changeset_invert },
|
||||
{ "sqlite3changeset_concat", test_sqlite3changeset_concat },
|
||||
{ "sqlite3changeset_apply", test_sqlite3changeset_apply },
|
||||
{ "sqlite3changeset_apply_v2", test_sqlite3changeset_apply_v2 },
|
||||
{ "sqlite3changeset_apply_replace_all",
|
||||
test_sqlite3changeset_apply_replace_all },
|
||||
{ "sql_exec_changeset", test_sql_exec_changeset },
|
||||
{ "sqlite3rebaser_create", test_sqlite3rebaser_create },
|
||||
};
|
||||
int i;
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
C Avoid\swriting\sthe\ssqlite_sequence\stable\swhen\sit\shas\snot\sactually\schanged.
|
||||
D 2018-03-16T18:46:30.654
|
||||
C Do\snot\sinject\sOOM\serrors\son\sSQLITE_FCNTL_LOCK_TIMEOUT\scalls\sas\san\sOOM\sis\nnot\spossible\sin\sthat\scontext.
|
||||
D 2018-03-26T21:05:47.026
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F Makefile.in 7016fc56c6b9bfe5daac4f34be8be38d8c0b5fab79ccbfb764d3b23bf1c6fff3
|
||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||
F Makefile.msc 8a6727b41a4626a5552016f4b0088b43fb14a32f53db1f47e83a0fefcb63c49a
|
||||
F Makefile.msc bdcad21b027a56a73e54a1121cfb9edd0a35c0abfa53aa12c2f996006ff99960
|
||||
F README.md 1d5342ebda97420f114283e604e5fe99b0da939d63b76d492eabbaae23488276
|
||||
F VERSION cdf91ac446255ecf3d8f6d8c3ee40d64123235ae5b3cef29d344e61b45ec3759
|
||||
F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50
|
||||
@@ -272,12 +272,12 @@ F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb
|
||||
F ext/misc/btreeinfo.c 78c8c57d325185ccc04b7679e5b020e34a4d9c87453e6b7ac943d0a26cee3256
|
||||
F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005
|
||||
F ext/misc/closure.c 0d2a038df8fbae7f19de42e7c7d71f2e4dc88704
|
||||
F ext/misc/completion.c 52c3f01523e3e387eb321b4739a89d1fe47cbe6025aa1f2d8d3685e9e365df0f
|
||||
F ext/misc/completion.c 0d0bd16378415b982e7119baddef52a0d2cc25860c238a9d2832b0cc6a84a16d
|
||||
F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189
|
||||
F ext/misc/csv.c 1a009b93650732e22334edc92459c4630b9fa703397cbb3c8ca279921a36ca11
|
||||
F ext/misc/dbdump.c 22018e00eb50e9ebf9067c92d4e7162dc5006a3efc4e0c19bc3829825a1043b0
|
||||
F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2
|
||||
F ext/misc/fileio.c 673d6bde25cab00ad40cc95b89fa99c9f00870c565de3beaab9d6a9658bbc3e0
|
||||
F ext/misc/fileio.c 48c7751c78fc4cdd29d8c862fd2f3f98bbfefa2a3cf1ca1496df4bf02eb8cded
|
||||
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
|
||||
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
|
||||
F ext/misc/json1.c dbe086615b9546c156bf32b9378fc09383b58bd17513b866cfd24c1e15281984
|
||||
@@ -304,7 +304,7 @@ F ext/misc/vfsstat.c bf10ef0bc51e1ad6756629e1edb142f7a8db1178
|
||||
F ext/misc/vtablog.c 31d0d8f4406795679dcd3a67917c213d3a2a5fb3ea5de35f6e773491ed7e13c9
|
||||
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
|
||||
F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
|
||||
F ext/misc/zipfile.c e4e4f8289a8dee7e4f78547dacfb6548bcd83a02b52c0bc9205d8fbfb7f4b8a1
|
||||
F ext/misc/zipfile.c c4de8f0ad446ce4a49aae11ff7b771cd7af60d7136c0bcfb53da1475b9075e79
|
||||
F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64
|
||||
F ext/rbu/rbu.c ea7d1b7eb44c123a2a619332e19fe5313500705c4a58aaa1887905c0d83ffc2e
|
||||
F ext/rbu/rbu1.test 43836fac8c7179a358eaf38a8a1ef3d6e6285842
|
||||
@@ -322,7 +322,8 @@ F ext/rbu/rbu9.test 0806d1772c9f4981774ff028de6656e4183082af
|
||||
F ext/rbu/rbuA.test 4e58e46e60d4064248614c43303d71f1b18cc804dd834ce6a913b3861828b28d
|
||||
F ext/rbu/rbuB.test c25bc325b8072a766e56bb76c001866b405925c2
|
||||
F ext/rbu/rbuC.test efe47db508a0269b683cb2a1913a425ffd39a831
|
||||
F ext/rbu/rbu_common.tcl a38e8e2d4a50fd6aaf151633714c1b1d2fae3ead
|
||||
F ext/rbu/rbu_common.tcl ebb8d81f44dc20e360cff1f34eb2ad0def33128805c5b36afcc44ab338509589
|
||||
F ext/rbu/rbucollate.test 86d6fc9b8f59a27b7b5a6e20b5e29816d338a0dbdea8c54bfcc549a0d437f3ea
|
||||
F ext/rbu/rbucrash.test 61470d977a06a0abc2ec35b05d82a1d7d87d10f4ffabad14c1c231edc942ad66
|
||||
F ext/rbu/rbucrash2.test b2ecbdd7bb72c88bd217c65bd00dafa07f7f2d4d
|
||||
F ext/rbu/rbudiff.test 3e605cf624d00d04d0fb1316a3acec4fbe3b3ac5
|
||||
@@ -339,9 +340,9 @@ F ext/rbu/rbusave.test 0f43b6686084f426ddd040b878426452fd2c2f48
|
||||
F ext/rbu/rbutemplimit.test cd553a9288d515d0b5f87d277e76fd18c4aa740b761e7880fab11ce986ea18d1
|
||||
F ext/rbu/rbuvacuum.test ff357e9b556ca7ad4673da0ff7f244def919ff858e0f9f350d3e30fdd83a62a8
|
||||
F ext/rbu/rbuvacuum2.test 2074ab14fe66e1c7e7210c62562650dcd215bbaa
|
||||
F ext/rbu/sqlite3rbu.c 64bd08c1011456f90564ed167abce3a9c2af421a924b21eb57231e078da04feb
|
||||
F ext/rbu/sqlite3rbu.c f6e9ca388b5d4680fbf266a4d10a21aec11d6baf48f6d06fd53f6b205fad959f
|
||||
F ext/rbu/sqlite3rbu.h b42bcd4d8357268c6c39ab2a60b29c091e89328fa8cc49c8fac5ab8d007e79b2
|
||||
F ext/rbu/test_rbu.c 7073979b9cc80912bb03599ac8d85ab5d3bf03cfacd3463f2dcdd7822997533a
|
||||
F ext/rbu/test_rbu.c baa23eb28457580673d2175e5f0c29ced0cd320ee819b13ad362398c53b96e90
|
||||
F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15
|
||||
F ext/repair/checkfreelist.c 0dbae18c1b552f58d64f8969e4fb1e7f11930c60a8c2a9a8d50b7f15bdfd54bd
|
||||
F ext/repair/checkindex.c 7d28c01a2e012ac64257d230fc452b2cafb78311a91a343633d01d95220f66f3
|
||||
@@ -381,7 +382,7 @@ F ext/session/changeset.c 4ccbaa4531944c24584bf6a61ba3a39c62b6267a
|
||||
F ext/session/session1.test 736d7ff178662f0b717c37f46531b84a5ce0210ccb0c4edf629c55dbcbbc3ea1
|
||||
F ext/session/session2.test 284de45abae4cc1082bc52012ee81521d5ac58e0
|
||||
F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479
|
||||
F ext/session/session4.test 3eea8058643e5adbd3293a5c553255c35e774ed90e7cbec09c9b010d176ad396
|
||||
F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40
|
||||
F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169
|
||||
F ext/session/session6.test 443789bc2fca12e4f7075cf692c60b8a2bea1a26
|
||||
F ext/session/session8.test 8e194b3f655d861ca36de5d4de53f702751bab3b
|
||||
@@ -394,17 +395,18 @@ F ext/session/sessionE.test 0a616c4ad8fd2c05f23217ebb6212ef80b7fef30f5f086a6633a
|
||||
F ext/session/sessionF.test c2f178d4dfd723a5fd94a730ea2ccb44c669e3ce
|
||||
F ext/session/sessionG.test 63f9a744341d670775af29e4f19c1ef09a4810798400f28cd76704803a2e56ff
|
||||
F ext/session/sessionH.test 332b60e4c2e0a680105e11936201cabe378216f307e2747803cea56fa7d9ebae
|
||||
F ext/session/session_common.tcl 7776eda579773113b30c7abfd4545c445228cb73
|
||||
F ext/session/session_common.tcl 748141b02042b942e04a7afad9ffb2212a3997de536ed95f6dec7bb5018ede2c
|
||||
F ext/session/session_speed_test.c edc1f96fd5e0e4b16eb03e2a73041013d59e8723
|
||||
F ext/session/sessionat.test efe88965e74ff1bc2af9c310b28358c02d420c1fb2705cc7a28f0c1cc142c3ec
|
||||
F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec
|
||||
F ext/session/sessionfault.test da273f2712b6411e85e71465a1733b8501dbf6f7
|
||||
F ext/session/sessionfault2.test 04aa0bc9aa70ea43d8de82c4f648db4de1e990b0
|
||||
F ext/session/sessionfault2.test 555a8504de03d59b369ef20209585da5aeb2671dedabc4584e9ffe6269689185
|
||||
F ext/session/sessionrebase.test 4e1bcfd26fd8ed8ac571746f56cceeb45184f4d65490ea0d405227cfc8a9cba8
|
||||
F ext/session/sessionstat1.test 41cd97c2e48619a41cdf8ae749e1b25f34719de638689221aa43971be693bf4e
|
||||
F ext/session/sessionwor.test 2f3744236dc8b170a695b7d8ddc8c743c7e79fdc
|
||||
F ext/session/sqlite3session.c 9edfaaa74977ddecd7bbd94e8f844d9b0f6eec22d1d547e806361670db814c1e
|
||||
F ext/session/sqlite3session.h 2e1584b030fbd841cefdce15ba984871978d305f586da2d1972f6e1958fa10b1
|
||||
F ext/session/test_session.c eb0bd6c1ea791c1d66ee4ef94c16500dad936386
|
||||
F ext/session/sqlite3session.c 4e21db8d2abb7960ded6f66e745671442e3ae2156a5ff8f7cf07567c507c324e
|
||||
F ext/session/sqlite3session.h 85fd2dc3df1532b0695beb345e2ff375c2745a4654b405fcbe33afa18baa6cc7
|
||||
F ext/session/test_session.c f253742ea01b089326f189b5ae15a5b55c1c9e97452e4a195ee759ba51b404d5
|
||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f
|
||||
@@ -424,24 +426,24 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c cf7a8af45cb0ace672f47a1b29ab24092a9e8cd8d945a9974e3b5d925f548594
|
||||
F src/analyze.c 6b42e36a5dcc2703a771f2411bd5e99524bd62c7ecde209bb88dfb04c72f046e
|
||||
F src/analyze.c 71fbbeb7b25417592f54d869fe90c28b48e4cecb9926ef9b06d90fb0aec48941
|
||||
F src/attach.c f6f212c43dddba79dfcb723fb9470785f3ff55bde8953cd9d2546f3022070a41
|
||||
F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73
|
||||
F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
|
||||
F src/btree.c 18a53540aa35dbdf77f715ea928422a4ed9011dc16ea7b50f803fd1617fcc4f5
|
||||
F src/btree.c 9eb9531c65346bbfccf5325384b7db1849daf4db6601dcfe21ba5c5b20623b64
|
||||
F src/btree.h 0866c0a08255142ea0e754aabd211c843cab32045c978a592a43152405ed0c84
|
||||
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
|
||||
F src/build.c 672022c06e1a5c2653f80c77a687de11f7e65ce81d20fe2825aadfa13a875c33
|
||||
F src/build.c 8b53aacc26944bb7fd9ab5ddeedecb4cc7c4b84df3a420cf6d2b8f772ad421df
|
||||
F src/callback.c fe677cb5f5abb02f7a772a62a98c2f516426081df68856e8f2d5f950929b966a
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0
|
||||
F src/ctime.c bd9da3f1ff21b432564a16ef0b154cff03585dc43742842e99c58907c6cb4bef
|
||||
F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
|
||||
F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6
|
||||
F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720
|
||||
F src/delete.c 20c8788451dc737a967c87ea53ad43544d617f5b57d32ccce8bd52a0daf9e89b
|
||||
F src/expr.c 904f85e5f5fa232488cbb662fcf3306ae203728751468670fb9840a9b1886abc
|
||||
F src/expr.c 51500461dcd4d0873a938bf188d03076d6712d70ff00a0f0d65621edf4e521c6
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
|
||||
F src/func.c 94f42cba2cc1c34aeaa441022ba0170ec3fec4bba54db4e0ded085c6dc0fdc51
|
||||
@@ -453,7 +455,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c b9ff71cc2913d1d57698a1e22bf853261a9a642baf62bdf40ddeb3809adb85b5
|
||||
F src/legacy.c 134ab3e3fae00a0f67a5187981d6935b24b337bcf0f4b3e5c9fa5763da95bf4e
|
||||
F src/loadext.c f6e4e416a736369f9e80eba609f0acda97148a8b0453784d670c78d3eed2f302
|
||||
F src/main.c c1e97e4c6fffff1fb1a6f1c48807386819af78657b4ae4acfd6d6d17353b8277
|
||||
F src/main.c ffe71c007fc943adfdc638796a80581fb8e2f035bcfa2312b579a2e852d836ec
|
||||
F src/malloc.c 07295435093ce354c6d9063ac05a2eeae28bd251d2e63c48b3d67c12c76f7e18
|
||||
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
|
||||
F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
|
||||
@@ -469,32 +471,32 @@ F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4
|
||||
F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58
|
||||
F src/mutex_w32.c 7670d770c94bbfe8289bec9d7f1394c5a00a57c37f892aab6b6612d085255235
|
||||
F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
|
||||
F src/os.c 22d31db3ca5a96a408fbf1ceeaaebcaf64c87024d2ff9fe1cf2ddbec3e75c104
|
||||
F src/os.c 750d7dca7eff3d76566fc71057e6960316914e3557776e8f50d4314f01090317
|
||||
F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
|
||||
F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
|
||||
F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
|
||||
F src/os_unix.c 928586cbde31890538854f1657463392d63b2d7794f577774573ae53ec283d7b
|
||||
F src/os_unix.c 2b53b0b8ddc580db096252c721729e5f5f2f355b4fc056f8f3fb328aeb3c9e8a
|
||||
F src/os_win.c eb03c6d52f893bcd7fdd4c6006674c13c1b5e49543fec98d605201af2997171c
|
||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||
F src/pager.c 3e3b659b6b3f40b5a5efef6b8890ced490c397a81d96feb5266fde1f7362e608
|
||||
F src/pager.h 581698f2177e8bd4008fe4760898ce20b6133d1df22139b9101b5155f900df7a
|
||||
F src/parse.y 3be4b2b5e33ef7dab3128b765898ee786fc6cd698a7f053f756a68f2f238f0aa
|
||||
F src/pager.c 8f2611ef1eb92a18e1605cb4ff37dfcc05acc6000eb6c6c263105ef5aba54661
|
||||
F src/pager.h c571b064df842ec8f2e90855dead9acf4cbe0d1b2c05afe0ef0d0145f7fd0388
|
||||
F src/parse.y 140bbc53b5f67f731239f7fc8704a4f1e60cbbc10fb84bf9577322f974725f19
|
||||
F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd
|
||||
F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
|
||||
F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
|
||||
F src/pragma.c bea56df3ae0637768c0da4fbbb8f2492f780980d95000034a105ff291bf7ca69
|
||||
F src/pragma.h bb83728944b42f6d409c77f5838a8edbdb0fe83046c5496ffc9602b40340a324
|
||||
F src/prepare.c 259f4e7960c47082c9653f3d5f0c294abd68bb9c3aab86de7630700cba1c20fb
|
||||
F src/prepare.c b086fea6a1952db88beca31fdd621201ee5e4ce3f02905248cc3035a8174aa89
|
||||
F src/printf.c d3b7844ddeb11fbbdd38dd84d09c9c1ac171d21fb038473c3aa97981201cc660
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c 66c73fcb7719b8ff0e841b58338f13604ff3e2b50a723f9b8f383595735262f6
|
||||
F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
|
||||
F src/select.c f02352ac5cbb6fad3804add825743b924cfb6c742ba2e8666d726828a9985d73
|
||||
F src/shell.c.in 9b7e7ac1ccdbc045e285e745ff6d21dbec6ce91330f2bdd5db50d5c39f40679e
|
||||
F src/sqlite.h.in 2619d00bccc0454e875bce5e90b1dc986f87975c267dd7bbbe251f1be297d2f3
|
||||
F src/select.c 2c408ab9b4bfc807e6a9d3d45337d20ebe72a8b7ac793854710bf9d572e7ab6d
|
||||
F src/shell.c.in d6a07811aa9f3b10200c15ab8dd4b6b998849a3b0c8b125bfa980329a33c26a6
|
||||
F src/sqlite.h.in 56e6c8fb785b09dac31331d19680f7133d84cb96fc073a47847f1066e03fc2ff
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 83a3c4ce93d650bedfd1aa558cb85a516bd6d094445ee989740827d0d944368d
|
||||
F src/sqliteInt.h 2ef60a6d9a50e6eef224e9eae71b29a9fb91c301e882d9fbbb77afd50b6cf815
|
||||
F src/sqliteInt.h a4837c57f9a3e2af100bc59f4be60d16b823f18131f8cef6a6685440f775eebd
|
||||
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
|
||||
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@@ -552,13 +554,13 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c 5b0c661a85f783d35b9883830736eeb63be4aefc4f6b7d9cd081d48782c041e2
|
||||
F src/treeview.c e0d62678314abf0e1e6d09ea405f4de3f404a17b4641c2169c304b5edf509320
|
||||
F src/treeview.c 14d5d1254702ec96876aa52642cb31548612384134970409fae333b25b39d6bb
|
||||
F src/trigger.c a34539c69433276d37b0da9a89c117726ff2d292c0902895af1f393a983cd3a1
|
||||
F src/update.c a90a32ffc0100265b0693dbbdbe490756447af181f5ea2c138cce515b08c8795
|
||||
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
|
||||
F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
|
||||
F src/vacuum.c 762ee9bbf8733d87d8cd06f58d950e881982e416f8c767334a40ffd341b6bff5
|
||||
F src/vdbe.c 88d8e0797bf49624d056014f34f302a7370cc119915cc0ece8f2b7bf5e7c30fb
|
||||
F src/vdbe.c 066a4e1de2ed83e253adfd2e97a684cf562eaa41d31ee7f3d3e4c8aea4485a55
|
||||
F src/vdbe.h 134beb7a12a6213c00eba58febaede33447cc4441bc568a0d9c144b33fc3720a
|
||||
F src/vdbeInt.h 95f7adfdc5c8f1353321f55a6c5ec00a90877e3b85af5159e393afb41ff54110
|
||||
F src/vdbeapi.c 29d2baf9c1233131ec467d7bed1b7c8a03c27579048d768c4b04acf427838858
|
||||
@@ -589,7 +591,7 @@ F test/alter3.test 4d79934d812eaeacc6f22781a080f8cfe012fdc3
|
||||
F test/alter4.test b6d7b86860111864f6cddb54af313f5862dda23b
|
||||
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
|
||||
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
|
||||
F test/analyze.test 3eb35a4af972f98422e5dc0586501b17d103d321
|
||||
F test/analyze.test b3a9c67d00e1df7588a5b7be9a0292899f94fe8cac1f94a017277474ca2e59df
|
||||
F test/analyze3.test 8b3ef8ba6d1096b76c40e0925c0fe51e700d2b779cdda40914580de3f9b9d80f
|
||||
F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
|
||||
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
|
||||
@@ -736,13 +738,13 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
|
||||
F test/csv01.test 526fc6aefd052badd5a0283f86b4b395c3df76bfe98d96c801f494f5e2c7836c
|
||||
F test/ctime.test 78749e6c9a5f0010d67985be80788f841e3cd2da18114e2ed6010399a7d807f3
|
||||
F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
|
||||
F test/cursorhint2.test 8457e93d97f665f23f97cdbc8477d16e3480331b
|
||||
F test/cursorhint2.test 0078ae1ded4afcf5eb80d06e3a72b6e1c3f1a646aab26eeb583b0a9ec6f0d56e
|
||||
F test/date.test 9b73bbeb1b82d9c1f44dec5cf563bf7da58d2373
|
||||
F test/date2.test 74c234bece1b016e94dd4ef9c8cc7a199a8806c0e2291cab7ba64bace6350b10
|
||||
F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e
|
||||
F test/dbpage.test dbf50a4d361f9e45a979432c727506065113124478a7d2db12074fa655e65d6c
|
||||
F test/dbstatus.test c15fa97f743dac7ce996814c84b56317e138895ee15ce27f15b608aa6924c90a
|
||||
F test/dbstatus2.test 35a987036fefbbc696e65b6a3fbd860864cfd54941c52f50c61b55d4778ac66c
|
||||
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
|
||||
F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d
|
||||
F test/delete.test acc38fca8ee4851467705b1c2cfea64cd26667e5
|
||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||
@@ -771,7 +773,7 @@ F test/e_fts3.test 8cf40550bb088a6aa187c818c00fabe26ef82900a4cd5c66b427ccafe28be
|
||||
F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e
|
||||
F test/e_reindex.test 2bebf7b393e519198b7c654407221cf171a439b8
|
||||
F test/e_resolve.test a61751c368b109db73df0f20fc75fb47e166b1d8
|
||||
F test/e_select.test 16651bb681e83a1a2875ff4a595ed2b4b4dee375
|
||||
F test/e_select.test 6fd45fd4a59ec82b6dda7468699dcc0ec1a72538577750b4f90357a62c1d2723
|
||||
F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f
|
||||
F test/e_totalchanges.test b12ee5809d3e63aeb83238dd501a7bca7fd72c10
|
||||
F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528
|
||||
@@ -1002,12 +1004,12 @@ F test/ioerr3.test d3cec5e1a11ad6d27527d0d38573fbff14c71bdd
|
||||
F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c
|
||||
F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4
|
||||
F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b
|
||||
F test/istrue.test 2d89873d72248b7a0ef7b5457120100cce75a19181bcf4b30e90a3f96a5c5558
|
||||
F test/join.test 442c462eea85cf065d70a663c626b780a95af6e11585d909bb63b87598afe678
|
||||
F test/join2.test f1b5ba94ba70a791df2d99e61adcebf62edacad1eca57881c97eb3e2ca718595
|
||||
F test/istrue.test d6e659764da5ccc03adcdba18fe77d7917ba5e4abd04ef14bd4e4cf43e024b5b
|
||||
F test/join.test 730e3e8d511289531efca01f8684f98da1e6de51eacf95c5960d0c46e77719e3
|
||||
F test/join2.test 2339e3a8089178607a718c7fa1f6c3826579132396f5304a0f8e9dbefa60c84f
|
||||
F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0
|
||||
F test/join4.test 1a352e4e267114444c29266ce79e941af5885916
|
||||
F test/join5.test bc98ea4b4e5003f5b1453701ebb8cd7d1c01a550
|
||||
F test/join5.test c6bd62effc37a152bea735f9ef241b19bb967bd4593dc99b20e2fc55ae707e38
|
||||
F test/join6.test cfe6503791ceb0cbb509966740286ec423cbf10b
|
||||
F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
|
||||
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
|
||||
@@ -1110,6 +1112,9 @@ F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1
|
||||
F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823
|
||||
F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2
|
||||
F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
|
||||
F test/optfuzz-db01.c a0c256905c8ac79f9a5de2f374a3d9f757bef0dca2a238dc7c10cc8a38031834
|
||||
F test/optfuzz-db01.txt 21f6bdeadc701cf11528276e2a55c70bfcb846ba42df327f979bd9e7b6ce7041
|
||||
F test/optfuzz.c 50e330304eb1992e15ddd11f3daaad9bcc0d9aaad09cb2bcc77f9515df2e88b1
|
||||
F test/orderby1.test 4d22a7c75f6a83fc1f188cc7bb5192285fdf2552
|
||||
F test/orderby2.test bc11009f7cd99d96b1b11e57b199b00633eb5b04
|
||||
F test/orderby3.test 8619d06a3debdcd80a27c0fdea5c40b468854b99
|
||||
@@ -1229,7 +1234,7 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69
|
||||
F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e
|
||||
F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939
|
||||
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
|
||||
F test/shell1.test 9f8b8da05a79b134e252a5e1d8d411245ad83ac7126c262900b9f42b43108ffd
|
||||
F test/shell1.test e2f7d375ae80eb16590af23d6c40cd0140b6d1f92642c1b71eb94630a144ee08
|
||||
F test/shell2.test e242a9912f44f4c23c3d1d802a83e934e84c853b
|
||||
F test/shell3.test ac8c2b744014c3e9a0e26bfd829ab65f00923dc1a91ffd044863e9423cc91494
|
||||
F test/shell4.test 89ad573879a745974ff2df20ff97c5d6ffffbd5d
|
||||
@@ -1464,7 +1469,7 @@ F test/tokenize.test ce430a7aed48fc98301611429595883fdfcab5d7
|
||||
F test/tpch01.test 04adbf8d8300fa60a222f28d901abd76e7be6dd4
|
||||
F test/trace.test a659a9862957f4789e37a92b3bf6d2caf5c86b02cdeefc41e850ae53acf6992a
|
||||
F test/trace2.test f5cb67ad3bc09e0c58e8cca78dfd0b5639259983
|
||||
F test/trace3.test b41076f536876b6edf661c0cf8f9216771316efd0fe78905576cc23ce269e7f2
|
||||
F test/trace3.test 1dff966888773ff1bfea01c080caf15417892b3f998408fe920c4791f7337144
|
||||
F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6
|
||||
F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76
|
||||
F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94
|
||||
@@ -1611,8 +1616,8 @@ F test/wordcount.c cb589cec469a1d90add05b1f8cee75c7210338d87a5afd65260ed5c0f4bbf
|
||||
F test/writecrash.test f1da7f7adfe8d7f09ea79b42e5ca6dcc41102f27f8e334ad71539501ddd910cc
|
||||
F test/zeroblob.test 3857870fe681b8185654414a9bccfde80b62a0fa
|
||||
F test/zerodamage.test 9c41628db7e8d9e8a0181e59ea5f189df311a9f6ce99cc376dc461f66db6f8dc
|
||||
F test/zipfile.test fd865048725bb138ef3024cee704cd9da9250de4b6f78ad27ff8e7e6d46caefe
|
||||
F test/zipfile2.test 67d5f08a202796d4b7a71dfa4b8dcb74aa7a9d1f42c5f17bedff9855c1ba7aa5
|
||||
F test/zipfile.test 2a923f6ead6a0f9b61d936881f3ee2aeaabe15fc65c196456f58ea9b4b450f9b
|
||||
F test/zipfile2.test fc2f08d5ec19c18c83289fbed32e378dc5116519972166e57a244da7bf2e5805
|
||||
F test/zipfilefault.test 44d4d7a7f7cca7521d569d7f71026b241d65a6b1757aa409c1a168827edbbc2c
|
||||
F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5
|
||||
F tool/GetTclKit.bat 8995df40c4209808b31f24de0b58f90930239a234f7591e3675d45bfbb990c5d
|
||||
@@ -1651,7 +1656,7 @@ F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b6074
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
F tool/mksqlite3c-noext.tcl fef88397668ae83166735c41af99d79f56afaabb
|
||||
F tool/mksqlite3c.tcl a03cee30de81a2e67b93e5c659f24113a003677c557daeb008205c8e6d4345d6
|
||||
F tool/mksqlite3h.tcl f92f994d9709aeb9e2b6e6f9fc8b069d2f55202c8e23f453edc44390a25982dc
|
||||
F tool/mksqlite3h.tcl 080873e3856eceb9d289a08a00c4b30f875ea3feadcbece796bd509b1532792c
|
||||
F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b
|
||||
F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5
|
||||
F tool/offsets.c fe4262fdfa378e8f5499a42136d17bf3b98f6091
|
||||
@@ -1712,10 +1717,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 1774f1c3baf0bc3d83a53c52702696ff21814fa1de07cc38fd098832e6757b09
|
||||
R d0bd8d3f666390fa87cc4ce598933023
|
||||
T *branch * autoinc-enhancement
|
||||
T *sym-autoinc-enhancement *
|
||||
T -sym-trunk *
|
||||
P b81960561b47a1b49646f2f8870dd0684dc4ca7c0b9e11076fd713de66b75972
|
||||
R 0d3c70b064d7081aae7c053c9180f1ca
|
||||
U drh
|
||||
Z 5d34c90db248f39c50f1168b98361d2f
|
||||
Z 20d1835935e71c19ea4ee96db7282960
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
3e3849a9d1a06673e6c713a42194f5da339fbf6533fa418c38f63d09bc045867
|
||||
5474e560eeb0269964b70bcd876bb86b4197c4fb164bc13454fb8204f083062c
|
||||
+1
-1
@@ -1015,7 +1015,7 @@ static void analyzeOneTable(
|
||||
/* Do not gather statistics on views or virtual tables */
|
||||
return;
|
||||
}
|
||||
if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){
|
||||
if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){
|
||||
/* Do not gather statistics on system tables */
|
||||
return;
|
||||
}
|
||||
|
||||
+4
-2
@@ -2231,7 +2231,8 @@ static int btreeInvokeBusyHandler(void *pArg){
|
||||
BtShared *pBt = (BtShared*)pArg;
|
||||
assert( pBt->db );
|
||||
assert( sqlite3_mutex_held(pBt->db->mutex) );
|
||||
return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
|
||||
return sqlite3InvokeBusyHandler(&pBt->db->busyHandler,
|
||||
sqlite3PagerFile(pBt->pPager));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2409,7 +2410,7 @@ int sqlite3BtreeOpen(
|
||||
}
|
||||
pBt->openFlags = (u8)flags;
|
||||
pBt->db = db;
|
||||
sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt);
|
||||
sqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt);
|
||||
p->pBt = pBt;
|
||||
|
||||
pBt->pCursor = 0;
|
||||
@@ -3372,6 +3373,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
||||
}
|
||||
}while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
|
||||
btreeInvokeBusyHandler(pBt) );
|
||||
sqlite3PagerResetLockTimeout(pBt->pPager);
|
||||
|
||||
if( rc==SQLITE_OK ){
|
||||
if( p->inTrans==TRANS_NONE ){
|
||||
|
||||
+4
-2
@@ -1870,8 +1870,6 @@ void sqlite3EndTable(
|
||||
p = pParse->pNewTable;
|
||||
if( p==0 ) return;
|
||||
|
||||
assert( !db->init.busy || !pSelect );
|
||||
|
||||
/* If the db->init.busy is 1 it means we are reading the SQL off the
|
||||
** "sqlite_master" or "sqlite_temp_master" table on the disk.
|
||||
** So do not write to the disk again. Extract the root page number
|
||||
@@ -1882,6 +1880,10 @@ void sqlite3EndTable(
|
||||
** table itself. So mark it read-only.
|
||||
*/
|
||||
if( db->init.busy ){
|
||||
if( pSelect ){
|
||||
sqlite3ErrorMsg(pParse, "");
|
||||
return;
|
||||
}
|
||||
p->tnum = db->init.newTnum;
|
||||
if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
|
||||
}
|
||||
|
||||
+1
-1
@@ -188,7 +188,7 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
"ENABLE_BATCH_ATOMIC_WRITE",
|
||||
#endif
|
||||
#if SQLITE_ENABLE_CEROD
|
||||
"ENABLE_CEROD",
|
||||
"ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
|
||||
#endif
|
||||
#if SQLITE_ENABLE_COLUMN_METADATA
|
||||
"ENABLE_COLUMN_METADATA",
|
||||
|
||||
+74
@@ -5001,6 +5001,80 @@ int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** This is the Expr node callback for sqlite3ExprImpliesNotNullRow().
|
||||
** If the expression node requires that the table at pWalker->iCur
|
||||
** have a non-NULL column, then set pWalker->eCode to 1 and abort.
|
||||
*/
|
||||
static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
|
||||
/* This routine is only called for WHERE clause expressions and so it
|
||||
** cannot have any TK_AGG_COLUMN entries because those are only found
|
||||
** in HAVING clauses. We can get a TK_AGG_FUNCTION in a WHERE clause,
|
||||
** but that is an illegal construct and the query will be rejected at
|
||||
** a later stage of processing, so the TK_AGG_FUNCTION case does not
|
||||
** need to be considered here. */
|
||||
assert( pExpr->op!=TK_AGG_COLUMN );
|
||||
testcase( pExpr->op==TK_AGG_FUNCTION );
|
||||
|
||||
if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune;
|
||||
switch( pExpr->op ){
|
||||
case TK_ISNULL:
|
||||
case TK_IS:
|
||||
case TK_OR:
|
||||
case TK_CASE:
|
||||
case TK_IN:
|
||||
case TK_FUNCTION:
|
||||
testcase( pExpr->op==TK_ISNULL );
|
||||
testcase( pExpr->op==TK_IS );
|
||||
testcase( pExpr->op==TK_OR );
|
||||
testcase( pExpr->op==TK_CASE );
|
||||
testcase( pExpr->op==TK_IN );
|
||||
testcase( pExpr->op==TK_FUNCTION );
|
||||
return WRC_Prune;
|
||||
case TK_COLUMN:
|
||||
if( pWalker->u.iCur==pExpr->iTable ){
|
||||
pWalker->eCode = 1;
|
||||
return WRC_Abort;
|
||||
}
|
||||
return WRC_Prune;
|
||||
default:
|
||||
return WRC_Continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true (non-zero) if expression p can only be true if at least
|
||||
** one column of table iTab is non-null. In other words, return true
|
||||
** if expression p will always be NULL or false if every column of iTab
|
||||
** is NULL.
|
||||
**
|
||||
** False negatives are acceptable. In other words, it is ok to return
|
||||
** zero even if expression p will never be true of every column of iTab
|
||||
** is NULL. A false negative is merely a missed optimization opportunity.
|
||||
**
|
||||
** False positives are not allowed, however. A false positive may result
|
||||
** in an incorrect answer.
|
||||
**
|
||||
** Terms of p that are marked with EP_FromJoin (and hence that come from
|
||||
** the ON or USING clauses of LEFT JOINS) are excluded from the analysis.
|
||||
**
|
||||
** This routine is used to check if a LEFT JOIN can be converted into
|
||||
** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE
|
||||
** clause requires that some column of the right table of the LEFT JOIN
|
||||
** be non-NULL, then the LEFT JOIN can be safely converted into an
|
||||
** ordinary join.
|
||||
*/
|
||||
int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
|
||||
Walker w;
|
||||
w.xExprCallback = impliesNotNullRow;
|
||||
w.xSelectCallback = 0;
|
||||
w.xSelectCallback2 = 0;
|
||||
w.eCode = 0;
|
||||
w.u.iCur = iTab;
|
||||
sqlite3WalkExpr(&w, p);
|
||||
return w.eCode;
|
||||
}
|
||||
|
||||
/*
|
||||
** An instance of the following structure is used by the tree walker
|
||||
** to determine if an expression can be evaluated by reference to the
|
||||
|
||||
+47
-14
@@ -1476,21 +1476,38 @@ const char *sqlite3ErrStr(int rc){
|
||||
** again until a timeout value is reached. The timeout value is
|
||||
** an integer number of milliseconds passed in as the first
|
||||
** argument.
|
||||
**
|
||||
** Return non-zero to retry the lock. Return zero to stop trying
|
||||
** and cause SQLite to return SQLITE_BUSY.
|
||||
*/
|
||||
static int sqliteDefaultBusyCallback(
|
||||
void *ptr, /* Database connection */
|
||||
int count /* Number of times table has been busy */
|
||||
void *ptr, /* Database connection */
|
||||
int count, /* Number of times table has been busy */
|
||||
sqlite3_file *pFile /* The file on which the lock occurred */
|
||||
){
|
||||
#if SQLITE_OS_WIN || HAVE_USLEEP
|
||||
/* This case is for systems that have support for sleeping for fractions of
|
||||
** a second. Examples: All windows systems, unix systems with usleep() */
|
||||
static const u8 delays[] =
|
||||
{ 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 };
|
||||
static const u8 totals[] =
|
||||
{ 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 };
|
||||
# define NDELAY ArraySize(delays)
|
||||
sqlite3 *db = (sqlite3 *)ptr;
|
||||
int timeout = db->busyTimeout;
|
||||
int tmout = db->busyTimeout;
|
||||
int delay, prior;
|
||||
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){
|
||||
if( count ){
|
||||
tmout = 0;
|
||||
sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout);
|
||||
return 0;
|
||||
}else{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
assert( count>=0 );
|
||||
if( count < NDELAY ){
|
||||
delay = delays[count];
|
||||
@@ -1499,16 +1516,18 @@ static int sqliteDefaultBusyCallback(
|
||||
delay = delays[NDELAY-1];
|
||||
prior = totals[NDELAY-1] + delay*(count-(NDELAY-1));
|
||||
}
|
||||
if( prior + delay > timeout ){
|
||||
delay = timeout - prior;
|
||||
if( prior + delay > tmout ){
|
||||
delay = tmout - prior;
|
||||
if( delay<=0 ) return 0;
|
||||
}
|
||||
sqlite3OsSleep(db->pVfs, delay*1000);
|
||||
return 1;
|
||||
#else
|
||||
/* This case for unix systems that lack usleep() support. Sleeping
|
||||
** must be done in increments of whole seconds */
|
||||
sqlite3 *db = (sqlite3 *)ptr;
|
||||
int timeout = ((sqlite3 *)ptr)->busyTimeout;
|
||||
if( (count+1)*1000 > timeout ){
|
||||
int tmout = ((sqlite3 *)ptr)->busyTimeout;
|
||||
if( (count+1)*1000 > tmout ){
|
||||
return 0;
|
||||
}
|
||||
sqlite3OsSleep(db->pVfs, 1000000);
|
||||
@@ -1519,14 +1538,25 @@ static int sqliteDefaultBusyCallback(
|
||||
/*
|
||||
** Invoke the given busy handler.
|
||||
**
|
||||
** This routine is called when an operation failed with a lock.
|
||||
** This routine is called when an operation failed to acquire a
|
||||
** lock on VFS file pFile.
|
||||
**
|
||||
** If this routine returns non-zero, the lock is retried. If it
|
||||
** returns 0, the operation aborts with an SQLITE_BUSY error.
|
||||
*/
|
||||
int sqlite3InvokeBusyHandler(BusyHandler *p){
|
||||
int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){
|
||||
int rc;
|
||||
if( NEVER(p==0) || p->xFunc==0 || p->nBusy<0 ) return 0;
|
||||
rc = p->xFunc(p->pArg, p->nBusy);
|
||||
if( p->xBusyHandler==0 || p->nBusy<0 ) return 0;
|
||||
if( p->bExtraFileArg ){
|
||||
/* Add an extra parameter with the pFile pointer to the end of the
|
||||
** callback argument list */
|
||||
int (*xTra)(void*,int,sqlite3_file*);
|
||||
xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler;
|
||||
rc = xTra(p->pBusyArg, p->nBusy, pFile);
|
||||
}else{
|
||||
/* Legacy style busy handler callback */
|
||||
rc = p->xBusyHandler(p->pBusyArg, p->nBusy);
|
||||
}
|
||||
if( rc==0 ){
|
||||
p->nBusy = -1;
|
||||
}else{
|
||||
@@ -1548,9 +1578,10 @@ int sqlite3_busy_handler(
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
sqlite3_mutex_enter(db->mutex);
|
||||
db->busyHandler.xFunc = xBusy;
|
||||
db->busyHandler.pArg = pArg;
|
||||
db->busyHandler.xBusyHandler = xBusy;
|
||||
db->busyHandler.pBusyArg = pArg;
|
||||
db->busyHandler.nBusy = 0;
|
||||
db->busyHandler.bExtraFileArg = 0;
|
||||
db->busyTimeout = 0;
|
||||
sqlite3_mutex_leave(db->mutex);
|
||||
return SQLITE_OK;
|
||||
@@ -1598,8 +1629,10 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
|
||||
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
||||
#endif
|
||||
if( ms>0 ){
|
||||
sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
|
||||
sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback,
|
||||
(void*)db);
|
||||
db->busyTimeout = ms;
|
||||
db->busyHandler.bExtraFileArg = 1;
|
||||
}else{
|
||||
sqlite3_busy_handler(db, 0, 0);
|
||||
}
|
||||
|
||||
@@ -126,7 +126,9 @@ int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
|
||||
*/
|
||||
int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
#ifdef SQLITE_TEST
|
||||
if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
|
||||
if( op!=SQLITE_FCNTL_COMMIT_PHASETWO
|
||||
&& op!=SQLITE_FCNTL_LOCK_TIMEOUT
|
||||
){
|
||||
/* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
|
||||
** is using a regular VFS, it is called after the corresponding
|
||||
** transaction has been committed. Injecting a fault at this point
|
||||
|
||||
+49
-3
@@ -229,6 +229,9 @@ struct unixFile {
|
||||
#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
|
||||
unsigned fsFlags; /* cached details from statfs() */
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
unsigned iBusyTimeout; /* Wait this many millisec on locks */
|
||||
#endif
|
||||
#if OS_VXWORKS
|
||||
struct vxworksFileId *pId; /* Unique file ID */
|
||||
#endif
|
||||
@@ -1465,6 +1468,43 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Set a posix-advisory-lock.
|
||||
**
|
||||
** There are two versions of this routine. If compiled with
|
||||
** SQLITE_ENABLE_SETLK_TIMEOUT then the routine has an extra parameter
|
||||
** which is a pointer to a unixFile. If the unixFile->iBusyTimeout
|
||||
** value is set, then it is the number of milliseconds to wait before
|
||||
** failing the lock. The iBusyTimeout value is always reset back to
|
||||
** zero on each call.
|
||||
**
|
||||
** If SQLITE_ENABLE_SETLK_TIMEOUT is not defined, then do a non-blocking
|
||||
** attempt to set the lock.
|
||||
*/
|
||||
#ifndef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x)
|
||||
#else
|
||||
static int osSetPosixAdvisoryLock(
|
||||
int h, /* The file descriptor on which to take the lock */
|
||||
struct flock *pLock, /* The description of the lock */
|
||||
unixFile *pFile /* Structure holding timeout value */
|
||||
){
|
||||
int rc = osFcntl(h,F_SETLK,pLock);
|
||||
while( rc<0 && pFile->iBusyTimeout>0 ){
|
||||
/* On systems that support some kind of blocking file lock with a timeout,
|
||||
** make appropriate changes here to invoke that blocking file lock. On
|
||||
** generic posix, however, there is no such API. So we simply try the
|
||||
** lock once every millisecond until either the timeout expires, or until
|
||||
** the lock is obtained. */
|
||||
usleep(1000);
|
||||
rc = osFcntl(h,F_SETLK,pLock);
|
||||
pFile->iBusyTimeout--;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
|
||||
|
||||
|
||||
/*
|
||||
** Attempt to set a system-lock on the file pFile. The lock is
|
||||
** described by pLock.
|
||||
@@ -1497,7 +1537,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
|
||||
lock.l_start = SHARED_FIRST;
|
||||
lock.l_len = SHARED_SIZE;
|
||||
lock.l_type = F_WRLCK;
|
||||
rc = osFcntl(pFile->h, F_SETLK, &lock);
|
||||
rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile);
|
||||
if( rc<0 ) return rc;
|
||||
pInode->bProcessLock = 1;
|
||||
pInode->nLock++;
|
||||
@@ -1505,7 +1545,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){
|
||||
rc = 0;
|
||||
}
|
||||
}else{
|
||||
rc = osFcntl(pFile->h, F_SETLK, pLock);
|
||||
rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -3865,6 +3905,12 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
*(int*)pArg = fileHasMoved(pFile);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
case SQLITE_FCNTL_LOCK_TIMEOUT: {
|
||||
pFile->iBusyTimeout = *(int*)pArg;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
#if SQLITE_MAX_MMAP_SIZE>0
|
||||
case SQLITE_FCNTL_MMAP_SIZE: {
|
||||
i64 newLimit = *(i64*)pArg;
|
||||
@@ -4184,7 +4230,7 @@ static int unixShmSystemLock(
|
||||
f.l_whence = SEEK_SET;
|
||||
f.l_start = ofst;
|
||||
f.l_len = n;
|
||||
rc = osFcntl(pShmNode->h, F_SETLK, &f);
|
||||
rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile);
|
||||
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
|
||||
}
|
||||
|
||||
|
||||
+15
-1
@@ -3704,7 +3704,7 @@ static int pagerOpentemp(
|
||||
** retried. If it returns zero, then the SQLITE_BUSY error is
|
||||
** returned to the caller of the pager API function.
|
||||
*/
|
||||
void sqlite3PagerSetBusyhandler(
|
||||
void sqlite3PagerSetBusyHandler(
|
||||
Pager *pPager, /* Pager object */
|
||||
int (*xBusyHandler)(void *), /* Pointer to busy-handler function */
|
||||
void *pBusyHandlerArg /* Argument to pass to xBusyHandler */
|
||||
@@ -5693,6 +5693,7 @@ void sqlite3PagerUnrefPageOne(DbPage *pPg){
|
||||
assert( pPg->pgno==1 );
|
||||
assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */
|
||||
pPager = pPg->pPager;
|
||||
sqlite3PagerResetLockTimeout(pPager);
|
||||
sqlite3PcacheRelease(pPg);
|
||||
pagerUnlockIfUnused(pPager);
|
||||
}
|
||||
@@ -6970,6 +6971,18 @@ sqlite3_file *sqlite3PagerFile(Pager *pPager){
|
||||
return pPager->fd;
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
/*
|
||||
** Reset the lock timeout for pager.
|
||||
*/
|
||||
void sqlite3PagerResetLockTimeout(Pager *pPager){
|
||||
if( isOpen(pPager->fd) ){
|
||||
int x = 0;
|
||||
sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return the file handle for the journal file (if it exists).
|
||||
** This will be either the rollback journal or the WAL file.
|
||||
@@ -7430,6 +7443,7 @@ int sqlite3PagerCheckpoint(
|
||||
pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
|
||||
pnLog, pnCkpt
|
||||
);
|
||||
sqlite3PagerResetLockTimeout(pPager);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
+6
-1
@@ -126,7 +126,7 @@ int sqlite3PagerClose(Pager *pPager, sqlite3*);
|
||||
int sqlite3PagerReadFileheader(Pager*, int, unsigned char*);
|
||||
|
||||
/* Functions used to configure a Pager object. */
|
||||
void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *);
|
||||
void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *);
|
||||
int sqlite3PagerSetPagesize(Pager*, u32*, int);
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
void sqlite3PagerAlignReserve(Pager*,Pager*);
|
||||
@@ -212,6 +212,11 @@ int sqlite3PagerIsMemdb(Pager*);
|
||||
void sqlite3PagerCacheStat(Pager *, int, int, int *);
|
||||
void sqlite3PagerClearCache(Pager*);
|
||||
int sqlite3SectorSize(sqlite3_file *);
|
||||
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
|
||||
void sqlite3PagerResetLockTimeout(Pager *pPager);
|
||||
#else
|
||||
# define sqlite3PagerResetLockTimeout(X)
|
||||
#endif
|
||||
|
||||
/* Functions used to truncate the database file. */
|
||||
void sqlite3PagerTruncateImage(Pager*,Pgno);
|
||||
|
||||
+1
-2
@@ -523,8 +523,7 @@ oneselect(A) ::= SELECT(S) distinct(D) selcollist(W) from(X) where_opt(Y)
|
||||
if( A!=0 ){
|
||||
const char *z = s.z+6;
|
||||
int i;
|
||||
sqlite3_snprintf(sizeof(A->zSelName), A->zSelName, "#%d",
|
||||
++pParse->nSelect);
|
||||
sqlite3_snprintf(sizeof(A->zSelName), A->zSelName,"#%d",++pParse->nSelect);
|
||||
while( z[0]==' ' ) z++;
|
||||
if( z[0]=='/' && z[1]=='*' ){
|
||||
z += 2;
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ static void corruptSchema(
|
||||
char *z;
|
||||
if( zObj==0 ) zObj = "?";
|
||||
z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj);
|
||||
if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
|
||||
if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra);
|
||||
sqlite3DbFree(db, *pData->pzErrMsg);
|
||||
*pData->pzErrMsg = z;
|
||||
}
|
||||
|
||||
+81
-38
@@ -21,8 +21,7 @@
|
||||
/***/ int sqlite3SelectTrace = 0;
|
||||
# define SELECTTRACE(K,P,S,X) \
|
||||
if(sqlite3SelectTrace&(K)) \
|
||||
sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",\
|
||||
(S)->zSelName,(S)),\
|
||||
sqlite3DebugPrintf("%s/%p: ",(S)->zSelName,(S)),\
|
||||
sqlite3DebugPrintf X
|
||||
#else
|
||||
# define SELECTTRACE(K,P,S,X)
|
||||
@@ -383,6 +382,29 @@ static void setJoinExpr(Expr *p, int iTable){
|
||||
}
|
||||
}
|
||||
|
||||
/* Undo the work of setJoinExpr(). In the expression tree p, convert every
|
||||
** term that is marked with EP_FromJoin and iRightJoinTable==iTable into
|
||||
** an ordinary term that omits the EP_FromJoin mark.
|
||||
**
|
||||
** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
|
||||
*/
|
||||
static void unsetJoinExpr(Expr *p, int iTable){
|
||||
while( p ){
|
||||
if( ExprHasProperty(p, EP_FromJoin)
|
||||
&& (iTable<0 || p->iRightJoinTable==iTable) ){
|
||||
ExprClearProperty(p, EP_FromJoin);
|
||||
}
|
||||
if( p->op==TK_FUNCTION && p->x.pList ){
|
||||
int i;
|
||||
for(i=0; i<p->x.pList->nExpr; i++){
|
||||
unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
|
||||
}
|
||||
}
|
||||
unsetJoinExpr(p->pLeft, iTable);
|
||||
p = p->pRight;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** This routine processes the join information for a SELECT statement.
|
||||
** ON and USING clauses are converted into extra terms of the WHERE clause.
|
||||
@@ -3835,12 +3857,21 @@ static int flattenSubquery(
|
||||
** (3) The inner query has a LIMIT clause (since the changes to the WHERE
|
||||
** close would change the meaning of the LIMIT).
|
||||
**
|
||||
** (4) The inner query is the right operand of a LEFT JOIN. (The caller
|
||||
** enforces this restriction since this routine does not have enough
|
||||
** information to know.)
|
||||
** (4) (** This restriction was removed on 2018-03-21. It used to read:
|
||||
** The inner query is the right operand of a LEFT JOIN. **)
|
||||
**
|
||||
** (5) The WHERE clause expression originates in the ON or USING clause
|
||||
** of a LEFT JOIN.
|
||||
** of a LEFT JOIN where iCursor is not the right-hand table of that
|
||||
** left join. An example:
|
||||
**
|
||||
** SELECT *
|
||||
** FROM (SELECT 1 AS a1 UNION ALL SELECT 2) AS aa
|
||||
** JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2)
|
||||
** LEFT JOIN (SELECT 8 AS c3 UNION ALL SELECT 9) AS cc ON (b2=2);
|
||||
**
|
||||
** The correct answer is three rows: (1,1,NULL),(2,2,8),(2,2,9).
|
||||
** But if the (b2=2) term were to be pushed down into the bb subquery,
|
||||
** then the (1,1,NULL) row would be suppressed.
|
||||
**
|
||||
** Return 0 if no changes are made and non-zero if one or more WHERE clause
|
||||
** terms are duplicated into the subquery.
|
||||
@@ -3876,12 +3907,15 @@ static int pushDownWhereTerms(
|
||||
nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, iCursor);
|
||||
pWhere = pWhere->pLeft;
|
||||
}
|
||||
if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction (5) */
|
||||
if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){
|
||||
return 0; /* restriction (5) */
|
||||
}
|
||||
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){
|
||||
nChng++;
|
||||
while( pSubq ){
|
||||
SubstContext x;
|
||||
pNew = sqlite3ExprDup(pParse->db, pWhere, 0);
|
||||
unsetJoinExpr(pNew, -1);
|
||||
x.pParse = pParse;
|
||||
x.iTable = iCursor;
|
||||
x.iNewTable = iCursor;
|
||||
@@ -4913,14 +4947,6 @@ static void explainSimpleCount(
|
||||
# define explainSimpleCount(a,b,c)
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Context object for havingToWhereExprCb().
|
||||
*/
|
||||
struct HavingToWhereCtx {
|
||||
Expr **ppWhere;
|
||||
ExprList *pGroupBy;
|
||||
};
|
||||
|
||||
/*
|
||||
** sqlite3WalkExpr() callback used by havingToWhere().
|
||||
**
|
||||
@@ -4934,15 +4960,16 @@ struct HavingToWhereCtx {
|
||||
*/
|
||||
static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
|
||||
if( pExpr->op!=TK_AND ){
|
||||
struct HavingToWhereCtx *p = pWalker->u.pHavingCtx;
|
||||
if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){
|
||||
Select *pS = pWalker->u.pSelect;
|
||||
if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){
|
||||
sqlite3 *db = pWalker->pParse->db;
|
||||
Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0);
|
||||
if( pNew ){
|
||||
Expr *pWhere = *(p->ppWhere);
|
||||
Expr *pWhere = pS->pWhere;
|
||||
SWAP(Expr, *pNew, *pExpr);
|
||||
pNew = sqlite3ExprAnd(db, pWhere, pNew);
|
||||
*(p->ppWhere) = pNew;
|
||||
pS->pWhere = pNew;
|
||||
pWalker->eCode = 1;
|
||||
}
|
||||
}
|
||||
return WRC_Prune;
|
||||
@@ -4965,23 +4992,19 @@ static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){
|
||||
** entirely of constants and expressions that are also GROUP BY terms that
|
||||
** use the "BINARY" collation sequence.
|
||||
*/
|
||||
static void havingToWhere(
|
||||
Parse *pParse,
|
||||
ExprList *pGroupBy,
|
||||
Expr *pHaving,
|
||||
Expr **ppWhere
|
||||
){
|
||||
struct HavingToWhereCtx sCtx;
|
||||
static void havingToWhere(Parse *pParse, Select *p){
|
||||
Walker sWalker;
|
||||
|
||||
sCtx.ppWhere = ppWhere;
|
||||
sCtx.pGroupBy = pGroupBy;
|
||||
|
||||
memset(&sWalker, 0, sizeof(sWalker));
|
||||
sWalker.pParse = pParse;
|
||||
sWalker.xExprCallback = havingToWhereExprCb;
|
||||
sWalker.u.pHavingCtx = &sCtx;
|
||||
sqlite3WalkExpr(&sWalker, pHaving);
|
||||
sWalker.u.pSelect = p;
|
||||
sqlite3WalkExpr(&sWalker, p->pHaving);
|
||||
#if SELECTTRACE_ENABLED
|
||||
if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){
|
||||
SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n"));
|
||||
sqlite3TreeViewSelect(0, p, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -5142,7 +5165,6 @@ int sqlite3Select(
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
|
||||
memset(&sAggInfo, 0, sizeof(sAggInfo));
|
||||
#if SELECTTRACE_ENABLED
|
||||
pParse->nSelectIndent++;
|
||||
SELECTTRACE(1,pParse,p, ("begin processing:\n"));
|
||||
if( sqlite3SelectTrace & 0x100 ){
|
||||
sqlite3TreeViewSelect(0, p, 0);
|
||||
@@ -5188,13 +5210,29 @@ int sqlite3Select(
|
||||
generateColumnNames(pParse, p);
|
||||
}
|
||||
|
||||
/* Try to flatten subqueries in the FROM clause up into the main query
|
||||
/* Try to various optimizations (flattening subqueries, and strength
|
||||
** reduction of join operators) in the FROM clause up into the main query
|
||||
*/
|
||||
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
|
||||
for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
|
||||
struct SrcList_item *pItem = &pTabList->a[i];
|
||||
Select *pSub = pItem->pSelect;
|
||||
Table *pTab = pItem->pTab;
|
||||
|
||||
/* Convert LEFT JOIN into JOIN if there are terms of the right table
|
||||
** of the LEFT JOIN used in the WHERE clause.
|
||||
*/
|
||||
if( (pItem->fg.jointype & JT_LEFT)!=0
|
||||
&& sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor)
|
||||
&& OptimizationEnabled(db, SQLITE_SimplifyJoin)
|
||||
){
|
||||
SELECTTRACE(0x100,pParse,p,
|
||||
("LEFT-JOIN simplifies to JOIN on term %d\n",i));
|
||||
pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER);
|
||||
unsetJoinExpr(p->pWhere, pItem->iCursor);
|
||||
}
|
||||
|
||||
/* No futher action if this term of the FROM clause is no a subquery */
|
||||
if( pSub==0 ) continue;
|
||||
|
||||
/* Catch mismatch in the declared columns of a view and the number of
|
||||
@@ -5263,7 +5301,6 @@ int sqlite3Select(
|
||||
explainSetInteger(pParse->iSelectId, iRestoreSelectId);
|
||||
#if SELECTTRACE_ENABLED
|
||||
SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
|
||||
pParse->nSelectIndent--;
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
@@ -5336,7 +5373,7 @@ int sqlite3Select(
|
||||
/* Make copies of constant WHERE-clause terms in the outer query down
|
||||
** inside the subquery. This can help the subquery to run more efficiently.
|
||||
*/
|
||||
if( (pItem->fg.jointype & JT_OUTER)==0
|
||||
if( OptimizationEnabled(db, SQLITE_PushDown)
|
||||
&& pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor)
|
||||
){
|
||||
#if SELECTTRACE_ENABLED
|
||||
@@ -5345,6 +5382,8 @@ int sqlite3Select(
|
||||
sqlite3TreeViewSelect(0, p, 0);
|
||||
}
|
||||
#endif
|
||||
}else{
|
||||
SELECTTRACE(0x100,pParse,p,("Push-down not possible\n"));
|
||||
}
|
||||
|
||||
zSavedAuthContext = pParse->zAuthContext;
|
||||
@@ -5547,6 +5586,7 @@ int sqlite3Select(
|
||||
wctrlFlags |= p->selFlags & SF_FixedLimit;
|
||||
|
||||
/* Begin the database scan. */
|
||||
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy,
|
||||
p->pEList, wctrlFlags, p->nSelectRow);
|
||||
if( pWInfo==0 ) goto select_end;
|
||||
@@ -5648,7 +5688,9 @@ int sqlite3Select(
|
||||
if( pHaving ){
|
||||
if( pGroupBy ){
|
||||
assert( pWhere==p->pWhere );
|
||||
havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere);
|
||||
assert( pHaving==p->pHaving );
|
||||
assert( pGroupBy==p->pGroupBy );
|
||||
havingToWhere(pParse, p);
|
||||
pWhere = p->pWhere;
|
||||
}
|
||||
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
|
||||
@@ -5735,6 +5777,7 @@ int sqlite3Select(
|
||||
** in the right order to begin with.
|
||||
*/
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
|
||||
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0,
|
||||
WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0
|
||||
);
|
||||
@@ -5990,6 +6033,7 @@ int sqlite3Select(
|
||||
assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 );
|
||||
assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 );
|
||||
|
||||
SELECTTRACE(1,pParse,p,("WhereBegin\n"));
|
||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy,
|
||||
0, minMaxFlag, 0);
|
||||
if( pWInfo==0 ){
|
||||
@@ -6045,7 +6089,6 @@ select_end:
|
||||
sqlite3DbFree(db, sAggInfo.aFunc);
|
||||
#if SELECTTRACE_ENABLED
|
||||
SELECTTRACE(1,pParse,p,("end processing\n"));
|
||||
pParse->nSelectIndent--;
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
+28
-11
@@ -132,6 +132,9 @@ typedef unsigned char u8;
|
||||
# ifndef access
|
||||
# define access(f,m) _access((f),(m))
|
||||
# endif
|
||||
# ifndef unlink
|
||||
# define unlink _unlink
|
||||
# endif
|
||||
# undef popen
|
||||
# define popen _popen
|
||||
# undef pclose
|
||||
@@ -2286,18 +2289,20 @@ static int display_stats(
|
||||
for(i=0; i<nCol; i++){
|
||||
sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
|
||||
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
|
||||
#ifndef SQLITE_OMIT_DECLTYPE
|
||||
sqlite3_snprintf(30, z+x, "declared type:");
|
||||
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i));
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
#endif
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
sqlite3_snprintf(30, z+x, "database name:");
|
||||
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_database_name(pStmt,i));
|
||||
sqlite3_snprintf(30, z+x, "table name:");
|
||||
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i));
|
||||
sqlite3_snprintf(30, z+x, "origin name:");
|
||||
utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
displayStatLine(pArg, "Memory Used:",
|
||||
"%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset);
|
||||
@@ -2877,7 +2882,12 @@ static int shell_exec(
|
||||
sqlite3_finalize(pExplain);
|
||||
sqlite3_free(zEQP);
|
||||
}
|
||||
sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, triggerEQP, 0);
|
||||
if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){
|
||||
sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0);
|
||||
/* Reprepare pStmt before reactiving trace modes */
|
||||
sqlite3_finalize(pStmt);
|
||||
sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||
}
|
||||
restore_debug_trace_modes();
|
||||
}
|
||||
|
||||
@@ -5329,11 +5339,11 @@ static int arCreateOrUpdateCommand(
|
||||
rc = arExecSql(pAr, zCreate);
|
||||
}
|
||||
for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
|
||||
char *zSql = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab,
|
||||
char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab,
|
||||
pAr->bVerbose ? "shell_putsnl(name)" : "name",
|
||||
pAr->azArg[i], pAr->zDir);
|
||||
rc = arExecSql(pAr, zSql);
|
||||
sqlite3_free(zSql);
|
||||
rc = arExecSql(pAr, zSql2);
|
||||
sqlite3_free(zSql2);
|
||||
}
|
||||
end_ar_transaction:
|
||||
if( rc!=SQLITE_OK ){
|
||||
@@ -6611,8 +6621,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}
|
||||
}
|
||||
if( zName!=0 ){
|
||||
int isMaster = sqlite3_strlike(zName, "sqlite_master", 0)==0;
|
||||
if( isMaster || sqlite3_strlike(zName,"sqlite_temp_master",0)==0 ){
|
||||
int isMaster = sqlite3_strlike(zName, "sqlite_master", '\\')==0;
|
||||
if( isMaster || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0 ){
|
||||
char *new_argv[2], *new_colv[2];
|
||||
new_argv[0] = sqlite3_mprintf(
|
||||
"CREATE TABLE %s (\n"
|
||||
@@ -6672,13 +6682,18 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
appendText(&sSelect, ") WHERE ", 0);
|
||||
if( zName ){
|
||||
char *zQarg = sqlite3_mprintf("%Q", zName);
|
||||
int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 ||
|
||||
strchr(zName, '[') != 0;
|
||||
if( strchr(zName, '.') ){
|
||||
appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0);
|
||||
}else{
|
||||
appendText(&sSelect, "lower(tbl_name)", 0);
|
||||
}
|
||||
appendText(&sSelect, strchr(zName, '*') ? " GLOB " : " LIKE ", 0);
|
||||
appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0);
|
||||
appendText(&sSelect, zQarg, 0);
|
||||
if( !bGlob ){
|
||||
appendText(&sSelect, " ESCAPE '\\' ", 0);
|
||||
}
|
||||
appendText(&sSelect, " AND ", 0);
|
||||
sqlite3_free(zQarg);
|
||||
}
|
||||
@@ -7093,7 +7108,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
||||
}else{
|
||||
zLike = z;
|
||||
bSeparate = 1;
|
||||
if( sqlite3_strlike("sqlite_%", zLike, 0)==0 ) bSchema = 1;
|
||||
if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1;
|
||||
}
|
||||
}
|
||||
if( bSchema ){
|
||||
@@ -8399,6 +8414,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
|
||||
#endif
|
||||
}else if( strcmp(z,"-append")==0 ){
|
||||
data.openMode = SHELL_OPEN_APPENDVFS;
|
||||
}else if( strcmp(z,"-readonly")==0 ){
|
||||
data.openMode = SHELL_OPEN_READONLY;
|
||||
}else if( strcmp(z,"-ascii")==0 ){
|
||||
data.mode = MODE_Ascii;
|
||||
sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
|
||||
|
||||
+21
-4
@@ -1064,6 +1064,12 @@ struct sqlite3_io_methods {
|
||||
** so that all subsequent write operations are independent.
|
||||
** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without
|
||||
** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]
|
||||
** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain
|
||||
** a file lock using the xLock or xShmLock methods of the VFS to wait
|
||||
** for up to M milliseconds before failing, where M is the single
|
||||
** unsigned integer parameter.
|
||||
** </ul>
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
@@ -1098,6 +1104,8 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31
|
||||
#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
|
||||
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
|
||||
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
|
||||
#define SQLITE_FCNTL_LAST 34 /* Last value */
|
||||
|
||||
/* deprecated names */
|
||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||
@@ -2054,11 +2062,13 @@ struct sqlite3_mem_methods {
|
||||
** connections at all to the database. If so, it performs a checkpoint
|
||||
** operation before closing the connection. This option may be used to
|
||||
** override this behaviour. The first parameter passed to this operation
|
||||
** is an integer - non-zero to disable checkpoints-on-close, or zero (the
|
||||
** default) to enable them. The second parameter is a pointer to an integer
|
||||
** is an integer - positive to disable checkpoints-on-close, or zero (the
|
||||
** default) to enable them, and negative to leave the setting unchanged.
|
||||
** The second parameter is a pointer to an integer
|
||||
** into which is written 0 or 1 to indicate whether checkpoints-on-close
|
||||
** have been disabled - 0 if they are not disabled, 1 if they are.
|
||||
** </dd>
|
||||
**
|
||||
** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt>
|
||||
** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates
|
||||
** the [query planner stability guarantee] (QPSG). When the QPSG is active,
|
||||
@@ -2068,13 +2078,20 @@ struct sqlite3_mem_methods {
|
||||
** slower. But the QPSG has the advantage of more predictable behavior. With
|
||||
** the QPSG active, SQLite will always use the same query plan in the field as
|
||||
** was used during testing in the lab.
|
||||
** The first argument to this setting is an integer which is 0 to disable
|
||||
** the QPSG, positive to enable QPSG, or negative to leave the setting
|
||||
** unchanged. The second parameter is a pointer to an integer into which
|
||||
** is written 0 or 1 to indicate whether the QPSG is disabled or enabled
|
||||
** following this call.
|
||||
** </dd>
|
||||
**
|
||||
** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt>
|
||||
** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not
|
||||
** include output for any operations performed by trigger programs. This
|
||||
** option is used to set or clear (the default) a flag that governs this
|
||||
** behavior. The first parameter passed to this operation is an integer -
|
||||
** non-zero to enable output for trigger programs, or zero to disable it.
|
||||
** positive to enable output for trigger programs, or zero to disable it,
|
||||
** or negative to leave the setting unchanged.
|
||||
** The second parameter is a pointer to an integer into which is written
|
||||
** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
|
||||
** it is not disabled, 1 if it is.
|
||||
@@ -8802,7 +8819,7 @@ unsigned char *sqlite3_serialize(
|
||||
** CAPI3REF: Deserialize a database
|
||||
**
|
||||
** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the
|
||||
** [database connection] D to disconnection from database S and then
|
||||
** [database connection] D to disconnect from database S and then
|
||||
** reopen S as an in-memory database based on the serialization contained
|
||||
** in P. The serialized database P is N bytes in size. M is the size of
|
||||
** the buffer P, which might be larger than N. If M is larger than N, and
|
||||
|
||||
+10
-7
@@ -961,9 +961,10 @@ typedef INT16_TYPE LogEst;
|
||||
*/
|
||||
typedef struct BusyHandler BusyHandler;
|
||||
struct BusyHandler {
|
||||
int (*xFunc)(void *,int); /* The busy callback */
|
||||
void *pArg; /* First arg to busy callback */
|
||||
int nBusy; /* Incremented with each busy call */
|
||||
int (*xBusyHandler)(void *,int); /* The busy callback */
|
||||
void *pBusyArg; /* First arg to busy callback */
|
||||
int nBusy; /* Incremented with each busy call */
|
||||
u8 bExtraFileArg; /* Include sqlite3_file as callback arg */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1532,6 +1533,8 @@ struct sqlite3 {
|
||||
#define SQLITE_CursorHints 0x0400 /* Add OP_CursorHint opcodes */
|
||||
#define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */
|
||||
/* TH3 expects the Stat34 ^^^^^^ value to be 0x0800. Don't change it */
|
||||
#define SQLITE_PushDown 0x1000 /* The push-down optimization */
|
||||
#define SQLITE_SimplifyJoin 0x2000 /* Convert LEFT JOIN to JOIN */
|
||||
#define SQLITE_AllOpts 0xffff /* All optimizations */
|
||||
|
||||
/*
|
||||
@@ -2993,7 +2996,6 @@ struct Parse {
|
||||
int nMaxArg; /* Max args passed to user function by sub-program */
|
||||
#if SELECTTRACE_ENABLED
|
||||
int nSelect; /* Number of SELECT statements seen */
|
||||
int nSelectIndent; /* How far to indent SELECTTRACE() output */
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
int nTableLock; /* Number of locks in aTableLock */
|
||||
@@ -3357,9 +3359,9 @@ struct Walker {
|
||||
struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
|
||||
int *aiCol; /* array of column indexes */
|
||||
struct IdxCover *pIdxCover; /* Check for index coverage */
|
||||
struct IdxExprTrans *pIdxTrans; /* Convert indexed expr to column */
|
||||
struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
|
||||
ExprList *pGroupBy; /* GROUP BY clause */
|
||||
struct HavingToWhereCtx *pHavingCtx; /* HAVING to WHERE clause ctx */
|
||||
Select *pSelect; /* HAVING to WHERE clause ctx */
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -3823,6 +3825,7 @@ int sqlite3ExprCompare(Parse*,Expr*, Expr*, int);
|
||||
int sqlite3ExprCompareSkip(Expr*, Expr*, int);
|
||||
int sqlite3ExprListCompare(ExprList*, ExprList*, int);
|
||||
int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int);
|
||||
int sqlite3ExprImpliesNonNullRow(Expr*,int);
|
||||
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
|
||||
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
|
||||
int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
|
||||
@@ -4101,7 +4104,7 @@ void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
|
||||
CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
|
||||
char sqlite3AffinityType(const char*, u8*);
|
||||
void sqlite3Analyze(Parse*, Token*, Token*);
|
||||
int sqlite3InvokeBusyHandler(BusyHandler*);
|
||||
int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*);
|
||||
int sqlite3FindDb(sqlite3*, Token*);
|
||||
int sqlite3FindDbName(sqlite3 *, const char *);
|
||||
int sqlite3AnalysisLoad(sqlite3*,int iDB);
|
||||
|
||||
@@ -137,11 +137,21 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
|
||||
sqlite3TreeViewPush(pView, 1);
|
||||
}
|
||||
do{
|
||||
#if SELECTTRACE_ENABLED
|
||||
sqlite3TreeViewLine(pView,
|
||||
"SELECT%s%s (%s/%p) selFlags=0x%x nSelectRow=%d",
|
||||
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
|
||||
((p->selFlags & SF_Aggregate) ? " agg_flag" : ""),
|
||||
p->zSelName, p, p->selFlags,
|
||||
(int)p->nSelectRow
|
||||
);
|
||||
#else
|
||||
sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d",
|
||||
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
|
||||
((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags,
|
||||
(int)p->nSelectRow
|
||||
);
|
||||
#endif
|
||||
if( cnt++ ) sqlite3TreeViewPop(pView);
|
||||
if( p->pPrior ){
|
||||
n = 1000;
|
||||
|
||||
@@ -4287,6 +4287,10 @@ case OP_NewRowid: { /* out2 */
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
|
||||
pC = p->apCsr[pOp->p1];
|
||||
if( !pC->isTable ){
|
||||
rc = SQLITE_CORRUPT_BKPT;
|
||||
goto abort_due_to_error;
|
||||
}
|
||||
assert( pC!=0 );
|
||||
assert( pC->eCurType==CURTYPE_BTREE );
|
||||
assert( pC->uc.pCursor!=0 );
|
||||
|
||||
+17
-1
@@ -349,7 +349,7 @@ ifcapable stat4||stat3 {
|
||||
# This test corrupts the database file so it must be the last test
|
||||
# in the series.
|
||||
#
|
||||
do_test analyze-99.1 {
|
||||
do_test analyze-5.99 {
|
||||
execsql {
|
||||
PRAGMA writable_schema=on;
|
||||
UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1';
|
||||
@@ -361,4 +361,20 @@ do_test analyze-99.1 {
|
||||
}
|
||||
} {1 {malformed database schema (sqlite_stat1)}}
|
||||
|
||||
# Verify that tables whose names begin with "sqlite" but not
|
||||
# "sqlite_" are analyzed.
|
||||
#
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
do_execsql_test analyze-6.1 {
|
||||
CREATE TABLE sqliteDemo(a);
|
||||
INSERT INTO sqliteDemo(a) VALUES(1),(2),(3),(4),(5);
|
||||
CREATE TABLE SQLiteDemo2(a INTEGER PRIMARY KEY AUTOINCREMENT);
|
||||
INSERT INTO SQLiteDemo2 SELECT * FROM sqliteDemo;
|
||||
CREATE TABLE t1(b);
|
||||
INSERT INTO t1(b) SELECT a FROM sqliteDemo;
|
||||
ANALYZE;
|
||||
SELECT tbl FROM sqlite_stat1 WHERE idx IS NULL ORDER BY tbl;
|
||||
} {SQLiteDemo2 sqliteDemo t1}
|
||||
|
||||
finish_test
|
||||
|
||||
+41
-36
@@ -136,45 +136,50 @@ do_extract_hints_test 2.5 {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.6 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT NULL)
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.7 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT +NULL)
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.8 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NOT +NULL
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.9 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE CASE b WHEN 0 THEN 0 ELSE 1 END;
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.10 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b = 32+32
|
||||
} {
|
||||
x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))}
|
||||
}
|
||||
|
||||
ifcapable !icu {
|
||||
# This test only works using the built-in LIKE, not the ICU LIKE extension.
|
||||
do_extract_hints_test 2.11 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%'
|
||||
if {0} {
|
||||
# These tests no longer work due to the LEFT-JOIN strength reduction
|
||||
# optimization
|
||||
do_extract_hints_test 2.6 {
|
||||
SELECT * FROM x1 CROSS JOIN x2 ON (a=x) WHERE 0 = (b IS NOT NULL)
|
||||
} {
|
||||
x2 {AND(expr,EQ(c0,r[2]))}
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.7 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT +NULL)
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.8 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NOT +NULL
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.9 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x)
|
||||
WHERE CASE b WHEN 0 THEN 0 ELSE 1 END;
|
||||
} {
|
||||
x2 {EQ(c0,r[2])}
|
||||
}
|
||||
|
||||
do_extract_hints_test 2.10 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b = 32+32
|
||||
} {
|
||||
x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))}
|
||||
}
|
||||
|
||||
ifcapable !icu {
|
||||
# This test only works using the built-in LIKE, not the ICU LIKE extension.
|
||||
do_extract_hints_test 2.11 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%'
|
||||
} {
|
||||
x2 {AND(expr,EQ(c0,r[2]))}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
do_extract_hints_test 2.12 {
|
||||
SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE coalesce(x2.b, 1)
|
||||
} {
|
||||
|
||||
+1
-1
@@ -110,6 +110,6 @@ do_execsql_test 3.2 {
|
||||
PRAGMA cache_size=3;
|
||||
UPDATE t1 SET b=randomblob(1000);
|
||||
} {delete}
|
||||
do_test 3.2 { db_spill db 0 } {0 8 0}
|
||||
do_test 3.3 { db_spill db 0 } {0 8 0}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -748,7 +748,7 @@ do_execsql_test e_select-3.2.1a {
|
||||
SELECT k FROM x1 LEFT JOIN x2 USING(k)
|
||||
} {1 2 3 4 5 6}
|
||||
do_execsql_test e_select-3.2.1b {
|
||||
SELECT k FROM x1 LEFT JOIN x2 USING(k) WHERE x2.k
|
||||
SELECT k FROM x1 LEFT JOIN x2 USING(k) WHERE x2.k ORDER BY +k
|
||||
} {1 3 5}
|
||||
do_execsql_test e_select-3.2.2 {
|
||||
SELECT k FROM x1 LEFT JOIN x2 USING(k) WHERE x2.k IS NULL
|
||||
|
||||
@@ -123,4 +123,24 @@ do_catchsql_test istrue-524 {
|
||||
INSERT INTO t2 VALUES(2,true,false,null,false);
|
||||
} {1 {CHECK constraint failed: t2}}
|
||||
|
||||
foreach {tn val} [list 1 NaN 2 -NaN 3 NaN0 4 -NaN0 5 Inf 6 -Inf] {
|
||||
do_execsql_test istrue-600.$tn.1 {
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(x);
|
||||
}
|
||||
do_test istrue-600.$tn.2 {
|
||||
set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL]
|
||||
sqlite3_bind_double $::STMT 1 $val
|
||||
sqlite3_step $::STMT
|
||||
sqlite3_reset $::STMT
|
||||
sqlite3_finalize $::STMT
|
||||
} {SQLITE_OK}
|
||||
do_execsql_test istrue-600.$tn.3 {
|
||||
SELECT x IS TRUE FROM t1;
|
||||
} [expr {$tn in [list 5 6] ? {1} : {0}}]
|
||||
do_execsql_test istrue-600.$tn.4 {
|
||||
SELECT x IS FALSE FROM t1;
|
||||
} {0}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
@@ -780,4 +780,58 @@ do_execsql_test join-14.20 {
|
||||
LEFT JOIN t3 AS x3 ON x2.id=x3.c3;
|
||||
} {456 {} {}}
|
||||
|
||||
# 2018-03-24.
|
||||
# E.Pasma discovered that the LEFT JOIN strength reduction optimization
|
||||
# was misbehaving. The problem turned out to be that the
|
||||
# sqlite3ExprImpliesNotNull() routine was saying that CASE expressions
|
||||
# like
|
||||
#
|
||||
# CASE WHEN true THEN true ELSE x=0 END
|
||||
#
|
||||
# could never be true if x is NULL. The following test cases verify
|
||||
# that this error has been resolved.
|
||||
#
|
||||
db close
|
||||
sqlite3 db :memory:
|
||||
do_execsql_test join-15.100 {
|
||||
CREATE TABLE t1(a INT, b INT);
|
||||
INSERT INTO t1 VALUES(1,2),(3,4);
|
||||
CREATE TABLE t2(x INT, y INT);
|
||||
SELECT *, 'x'
|
||||
FROM t1 LEFT JOIN t2
|
||||
WHERE CASE WHEN FALSE THEN a=x ELSE 1 END;
|
||||
} {1 2 {} {} x 3 4 {} {} x}
|
||||
do_execsql_test join-15.105 {
|
||||
SELECT *, 'x'
|
||||
FROM t1 LEFT JOIN t2
|
||||
WHERE a IN (1,3,x,y);
|
||||
} {1 2 {} {} x 3 4 {} {} x}
|
||||
do_execsql_test join-15.110 {
|
||||
DROP TABLE t1;
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER);
|
||||
INSERT INTO t1(a,b) VALUES(1,0),(11,1),(12,1),(13,1),(121,12);
|
||||
CREATE INDEX t1b ON t1(b);
|
||||
CREATE TABLE t2(x INTEGER PRIMARY KEY);
|
||||
INSERT INTO t2(x) VALUES(0),(1);
|
||||
SELECT a1, a2, a3, a4, a5
|
||||
FROM (SELECT a AS a1 FROM t1 WHERE b=0)
|
||||
JOIN (SELECT x AS x1 FROM t2)
|
||||
LEFT JOIN (SELECT a AS a2, b AS b2 FROM t1)
|
||||
ON x1 IS TRUE AND b2=a1
|
||||
JOIN (SELECT x AS x2 FROM t2)
|
||||
ON x2<=CASE WHEN x1 THEN CASE WHEN a2 THEN 1 ELSE -1 END ELSE 0 END
|
||||
LEFT JOIN (SELECT a AS a3, b AS b3 FROM t1)
|
||||
ON x2 IS TRUE AND b3=a2
|
||||
JOIN (SELECT x AS x3 FROM t2)
|
||||
ON x3<=CASE WHEN x2 THEN CASE WHEN a3 THEN 1 ELSE -1 END ELSE 0 END
|
||||
LEFT JOIN (SELECT a AS a4, b AS b4 FROM t1)
|
||||
ON x3 IS TRUE AND b4=a3
|
||||
JOIN (SELECT x AS x4 FROM t2)
|
||||
ON x4<=CASE WHEN x3 THEN CASE WHEN a4 THEN 1 ELSE -1 END ELSE 0 END
|
||||
LEFT JOIN (SELECT a AS a5, b AS b5 FROM t1)
|
||||
ON x4 IS TRUE AND b5=a4
|
||||
ORDER BY a1, a2, a3, a4, a5;
|
||||
} {1 {} {} {} {} 1 11 {} {} {} 1 12 {} {} {} 1 12 121 {} {} 1 13 {} {} {}}
|
||||
|
||||
finish_test
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ do_execsql_test 2.0 {
|
||||
}
|
||||
|
||||
do_catchsql_test 2.1 {
|
||||
SELECT * FROM aa LEFT JOIN cc ON (a=b) JOIN bb ON (b=c);
|
||||
SELECT * FROM aa LEFT JOIN cc ON (a=b) JOIN bb ON (b=coalesce(c,1));
|
||||
} {1 {ON clause references tables to its right}}
|
||||
do_catchsql_test 2.2 {
|
||||
SELECT * FROM aa JOIN cc ON (a=b) JOIN bb ON (b=c);
|
||||
|
||||
+2
-2
@@ -164,7 +164,7 @@ do_execsql_test join5-3.3 {
|
||||
# Ticket https://www.sqlite.org/src/tktview/c2a19d81652f40568c770c43 on
|
||||
# 2015-08-20. LEFT JOIN and the push-down optimization.
|
||||
#
|
||||
do_execsql_test join6-4.1 {
|
||||
do_execsql_test join5-4.1 {
|
||||
SELECT *
|
||||
FROM (
|
||||
SELECT 'apple' fruit
|
||||
@@ -178,7 +178,7 @@ do_execsql_test join6-4.1 {
|
||||
SELECT 1 isyellow
|
||||
) c ON b.fruit='banana';
|
||||
} {apple apple {} banana banana 1}
|
||||
do_execsql_test join6-4.2 {
|
||||
do_execsql_test join5-4.2 {
|
||||
SELECT *
|
||||
FROM (SELECT 'apple' fruit UNION ALL SELECT 'banana')
|
||||
LEFT JOIN (SELECT 1) ON fruit='banana';
|
||||
|
||||
@@ -0,0 +1,948 @@
|
||||
/* content of file testdb01.db */
|
||||
unsigned char data001[] = {
|
||||
83, 81, 76,105,116,101, 32,102,111,114,109, 97,116, 32, 51, 0, 2, 0, 1,
|
||||
1, 0, 64, 32, 32, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 31, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 0, 46, 32,152, 5, 0, 0, 0, 7, 1,221, 0, 0, 0, 0, 35, 1,251,
|
||||
1,246, 1,241, 1,236, 1,231, 1,226, 1,221, 84, 4, 7, 23, 17, 17, 1,
|
||||
129, 19,116, 97, 98,108,101,116, 52,116, 52, 5, 67, 82, 69, 65, 84, 69, 32,
|
||||
84, 65, 66, 76, 69, 32,116, 52, 40, 97, 32, 73, 78, 84, 32, 85, 78, 73, 81,
|
||||
85, 69, 32, 78, 79, 84, 32, 78, 85, 76, 76, 44, 32, 98, 32, 73, 78, 84, 32,
|
||||
85, 78, 73, 81, 85, 69, 32, 78, 79, 84, 32, 78, 85, 76, 76, 44, 99, 44,100,
|
||||
44,101, 41, 35, 6, 6, 23, 55, 17, 1, 0,105,110,100,101,120,115,113,108,
|
||||
105,116,101, 95, 97,117,116,111,105,110,100,101,120, 95,116, 52, 95, 50,116,
|
||||
52, 7, 35, 5, 6, 23, 55, 17, 1, 0,105,110,100,101,120,115,113,108,105,
|
||||
116,101, 95, 97,117,116,111,105,110,100,101,120, 95,116, 52, 95, 49,116, 52,
|
||||
6, 42, 3, 6, 23, 17, 17, 1, 65,116, 97, 98,108,101,116, 51,116, 51, 4,
|
||||
67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 51, 40, 97, 44, 98,
|
||||
44, 99, 44,100, 44,101, 41, 95, 2, 7, 23, 17, 17, 1,129, 41,116, 97, 98,
|
||||
108,101,116, 50,116, 50, 3, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69,
|
||||
32,116, 50, 40, 97, 32, 73, 78, 84, 44, 32, 98, 32, 73, 78, 84, 44, 32, 99,
|
||||
32, 73, 78, 84, 44,100, 32, 73, 78, 84, 44,101, 32, 73, 78, 84, 44, 80, 82,
|
||||
73, 77, 65, 82, 89, 32, 75, 69, 89, 40, 98, 44, 97, 41, 41, 87, 73, 84, 72,
|
||||
79, 85, 84, 32, 82, 79, 87, 73, 68, 83, 1, 7, 23, 17, 17, 1,129, 17,116,
|
||||
97, 98,108,101,116, 49,116, 49, 2, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66,
|
||||
76, 69, 32,116, 49, 40, 97, 32, 73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73,
|
||||
77, 65, 0, 0, 0, 34, 32, 0, 0, 0, 33, 29, 0, 0, 0, 32, 26, 0, 0,
|
||||
0, 31, 23, 0, 0, 0, 30, 19, 0, 0, 0, 11, 14, 0, 0, 0, 9, 7, 5,
|
||||
0, 0, 0, 1, 1,251, 0, 0, 0, 0, 16, 1,251, 1,195, 1,180, 1,166,
|
||||
1,151, 1,136, 1,121, 1,105, 1, 91, 1, 76, 1, 61, 1, 46, 1, 29, 1,
|
||||
14, 0,252, 0,238, 0,224, 0,209, 0,194, 0,177, 0,157, 0,143, 0,128,
|
||||
0,110, 0, 94, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 14, 28, 6, 0, 1, 1, 1, 23, 17, 67, 31,119,111,114,107,115, 14, 27,
|
||||
6, 0, 1, 1, 1, 23, 22, 71, 3, 97,110,103,101,108, 16, 26, 6, 0, 1,
|
||||
1, 1, 27, 40, 98, 17,109,111,114,110,105,110,103, 13, 25, 6, 0, 1, 1,
|
||||
1, 21, 10, 7, 19,103,111,110,101, 12, 24, 6, 0, 1, 1, 9, 21, 43, 46,
|
||||
119, 97,121,115, 18, 23, 6, 0, 1, 1, 1, 31, 6, 37, 31,115, 97, 99,114,
|
||||
105,102,105, 99,101, 15, 22, 6, 0, 1, 1, 1, 25, 45, 71, 28,116,104,111,
|
||||
117,103,104, 13, 21, 6, 0, 1, 1, 1, 21, 22, 92, 18,115,111,109,101, 13,
|
||||
20, 6, 0, 9, 1, 1, 23, 2, 45, 97, 98,111,118,101, 12, 19, 6, 0, 1,
|
||||
1, 8, 21, 4, 58,119, 97,121,115, 12, 18, 6, 0, 1, 1, 1, 19, 44, 19,
|
||||
43,119, 97,114, 16, 17, 6, 0, 1, 1, 1, 27, 29, 74, 36, 98,101,116,119,
|
||||
101,101,110, 13, 16, 6, 0, 1, 1, 1, 21, 44, 52, 19,112,111,111,114, 15,
|
||||
15, 6, 0, 1, 1, 1, 25, 6, 3, 11,116,101,109,112,108,101, 13, 14, 6,
|
||||
0, 1, 1, 1, 21, 35, 48, 27,100,105,101,100, 13, 13, 6, 0, 1, 1, 1,
|
||||
21, 4, 21, 39,100,111,116,104, 13, 12, 6, 0, 1, 1, 1, 21, 4, 38, 36,
|
||||
115,101,110,100, 12, 11, 6, 0, 1, 1, 1, 19, 13, 48, 22,115,105,120, 14,
|
||||
10, 6, 0, 1, 1, 1, 23, 41, 89, 14,115,101,114,118,101, 13, 9, 6, 0,
|
||||
8, 1, 1, 23, 16, 50, 98,101,103, 97,116, 13, 8, 6, 0, 1, 1, 1, 21,
|
||||
42, 49, 34,115,101,110,100, 13, 7, 6, 0, 1, 1, 1, 21, 21, 91, 38,110,
|
||||
101, 97,114, 12, 6, 6, 0, 1, 1, 1, 19, 2, 37, 11, 99, 97,110, 13, 5,
|
||||
6, 0, 1, 1, 1, 21, 25, 27, 28,103,111,110,101, 13, 4, 6, 0, 1, 1,
|
||||
1, 21, 41, 32, 35,110,101, 97,114, 14, 3, 6, 0, 1, 1, 1, 23, 32, 24,
|
||||
26,115,101,114,118,101, 13, 2, 6, 0, 1, 1, 1, 21, 45, 14, 39,115, 97,
|
||||
118,101, 13, 1, 6, 0, 1, 1, 1, 21, 40, 68, 0, 0, 0, 15, 28, 2, 0,
|
||||
0, 0, 1, 1,238, 0, 0, 0, 0, 22, 1,238, 1,197, 1,181, 1,166, 1,
|
||||
151, 1,137, 1,121, 1,104, 1, 84, 1, 73, 1, 59, 1, 41, 1, 26, 1, 11,
|
||||
0,253, 0,238, 0,223, 0,207, 0,191, 0,175, 0,159, 0,144, 0,129, 0,
|
||||
113, 0, 97, 0, 82, 0, 68, 0, 0, 13, 6, 1, 1, 1, 1, 19, 26, 34, 15,
|
||||
20, 97,114,107, 14, 6, 1, 1, 1, 1, 21, 25, 5, 27, 28,103,111,110,101,
|
||||
15, 6, 1, 1, 1, 1, 23, 22, 47, 16, 40, 97,110,103,101,114, 15, 6, 1,
|
||||
1, 1, 1, 23, 22, 27, 71, 3, 97,110,103,101,108, 14, 6, 1, 1, 1, 1,
|
||||
21, 22, 21, 92, 18,115,111,109,101, 14, 6, 1, 1, 1, 1, 21, 21, 7, 91,
|
||||
38,110,101, 97,114, 15, 6, 1, 1, 1, 1, 23, 20, 42, 18, 5, 98,101,103,
|
||||
97,116, 15, 6, 1, 1, 1, 1, 23, 17, 37, 66, 18,100,119,101,108,116, 15,
|
||||
6, 1, 1, 1, 1, 23, 17, 28, 67, 31,119,111,114,107,115, 15, 6, 1, 1,
|
||||
1, 8, 25, 16, 32, 7,112,108, 97, 99,101,115, 14, 6, 1, 1, 1, 1, 21,
|
||||
16, 30, 81, 25,119, 97,108,107, 14, 6, 1, 1, 1, 1, 21, 14, 40, 30, 26,
|
||||
115,101,110,100, 13, 6, 1, 1, 1, 1, 19, 13, 11, 48, 22,115,105,120, 14,
|
||||
6, 1, 1, 1, 1, 21, 10, 38, 97, 34,115,104,101,119, 14, 6, 1, 1, 1,
|
||||
1, 21, 10, 25, 7, 19,103,111,110,101, 17, 6, 1, 1, 1, 1, 27, 9, 50,
|
||||
92, 29,116,104,101,114,101,105,110, 13, 6, 1, 1, 1, 1, 19, 9, 49, 51,
|
||||
38,111,105,108, 10, 6, 1, 1, 1, 1, 0, 7, 33, 72, 31, 19, 6, 1, 1,
|
||||
1, 1, 31, 6, 23, 37, 31,115, 97, 99,114,105,102,105, 99,101, 16, 6, 1,
|
||||
1, 1, 1, 25, 6, 15, 3, 11,116,101,109,112,108,101, 15, 6, 1, 1, 1,
|
||||
1, 23, 5, 43, 23, 41, 98,101,103, 97,116, 13, 6, 1, 1, 1, 8, 21, 4,
|
||||
19, 58,119, 97,121,115, 14, 6, 1, 1, 1, 1, 21, 4, 13, 21, 39,100,111,
|
||||
116,104, 14, 6, 1, 1, 1, 1, 21, 4, 12, 38, 36,115,101,110,100, 15, 6,
|
||||
1, 1, 1, 1, 23, 3, 39, 21, 45, 98,101,103, 97,116, 13, 6, 1, 1, 1,
|
||||
1, 19, 2, 6, 37, 11, 99, 97,110, 14, 6, 9, 1, 1, 1, 23, 20, 2, 45,
|
||||
97, 98,111,118,101, 14, 6, 8, 1, 1, 1, 23, 36, 52, 17, 99,104, 0, 0,
|
||||
0, 21, 13, 6, 1, 1, 1, 1, 19, 26, 34, 15, 20, 97,114,107, 13, 0, 0,
|
||||
0, 35, 0, 92, 0, 1,244, 1,232, 1,216, 1,204, 1,186, 1,171, 1,160,
|
||||
1,149, 1,138, 1,128, 1,117, 1,106, 1, 92, 1, 76, 1, 65, 1, 49, 1,
|
||||
32, 1, 21, 1, 10, 0,255, 0,241, 0,225, 0,214, 0,203, 0,192, 0,180,
|
||||
0,168, 0,156, 0,144, 0,132, 0,124, 0,116, 0,108, 0,100, 0, 92, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 35, 6, 0, 0, 0,
|
||||
0, 0, 6, 34, 6, 0, 0, 0, 0, 0, 6, 33, 6, 0, 0, 0, 0, 0, 6,
|
||||
32, 6, 0, 0, 0, 0, 0, 6, 31, 6, 0, 0, 0, 0, 0, 10, 30, 6, 1,
|
||||
1, 1, 1, 0, 48, 37, 93, 7, 10, 29, 6, 1, 1, 1, 1, 0, 28, 17, 67,
|
||||
31, 10, 28, 6, 1, 1, 1, 1, 0, 22, 45, 71, 28, 10, 27, 6, 1, 1, 1,
|
||||
1, 0, 12, 4, 38, 36, 10, 26, 6, 1, 1, 1, 1, 0, 49, 9, 51, 38, 9,
|
||||
25, 6, 1, 1, 1, 0, 0, 17, 29, 74, 9, 24, 6, 1, 1, 1, 0, 0, 47,
|
||||
22, 16, 9, 23, 6, 1, 1, 1, 0, 0, 32, 16, 7, 14, 22, 6, 1, 1, 1,
|
||||
0, 23, 42, 20, 18, 98,101,103, 97,116, 12, 21, 6, 1, 1, 1, 0, 19, 34,
|
||||
26, 15, 97,114,107, 9, 20, 6, 1, 1, 0, 1, 0, 49, 9, 38, 9, 19, 6,
|
||||
1, 1, 0, 1, 0, 44, 48, 9, 9, 18, 6, 1, 1, 0, 1, 0, 21, 22, 18,
|
||||
15, 17, 6, 1, 1, 0, 1, 25, 35, 38, 22, 99,117, 98,105,116,115, 14, 16,
|
||||
6, 1, 1, 0, 1, 23, 37, 17, 18,100,119,101,108,116, 9, 15, 6, 1, 0,
|
||||
1, 1, 0, 49, 51, 38, 14, 14, 6, 1, 0, 1, 1, 23, 10, 89, 14,115,101,
|
||||
114,118,101, 12, 13, 6, 9, 0, 1, 1, 21, 68, 32,100,111,116,104, 9, 12,
|
||||
6, 1, 0, 1, 1, 0, 47, 16, 40, 9, 11, 6, 1, 0, 1, 1, 0, 25, 7,
|
||||
19, 8, 10, 6, 0, 1, 1, 8, 0, 16, 7, 9, 9, 6, 0, 1, 1, 1, 0,
|
||||
16, 81, 25, 9, 8, 6, 0, 1, 1, 1, 0, 7, 72, 31, 9, 7, 6, 0, 1,
|
||||
1, 1, 0, 6, 37, 31, 13, 6, 6, 0, 1, 1, 1, 21, 21, 91, 38,110,101,
|
||||
97,114, 16, 5, 6, 1, 1, 1, 1, 25, 15, 6, 3, 11,116,101,109,112,108,
|
||||
101, 10, 4, 6, 1, 1, 1, 1, 0, 21, 22, 92, 18, 14, 3, 6, 1, 1, 1,
|
||||
1, 21, 4, 41, 32, 35,110,101, 97,114, 10, 2, 6, 1, 1, 1, 1, 0, 46,
|
||||
28, 88, 22, 10, 1, 6, 1, 1, 1, 1, 0, 17, 29, 74, 36, 13, 0, 0, 0,
|
||||
15, 1, 71, 0, 1,243, 1,230, 1,217, 1,204, 1,191, 1,179, 1,167, 1,
|
||||
155, 1,143, 1,131, 1,119, 1,107, 1, 95, 1, 83, 1, 71, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
10, 15, 6, 1, 1, 1, 1, 0, 48, 37, 93, 7, 10, 14, 6, 1, 1, 1, 1,
|
||||
0, 22, 45, 71, 28, 10, 13, 6, 1, 1, 1, 1, 0, 12, 4, 38, 36, 10, 12,
|
||||
6, 1, 1, 1, 0, 1, 32, 16, 7, 79, 10, 11, 6, 1, 1, 1, 0, 1, 42,
|
||||
20, 18, 19, 10, 10, 6, 1, 1, 1, 0, 1, 34, 26, 15, 13, 10, 9, 6, 1,
|
||||
1, 0, 1, 1, 49, 9, 38, 97, 10, 8, 6, 1, 1, 0, 1, 1, 44, 48, 9,
|
||||
90, 10, 7, 6, 1, 1, 0, 1, 1, 35, 38, 22, 33, 10, 6, 6, 1, 1, 0,
|
||||
1, 1, 37, 17, 18, 18, 11, 5, 6, 1, 1, 1, 1, 1, 15, 6, 3, 11, 43,
|
||||
11, 4, 6, 1, 1, 1, 1, 1, 21, 22, 92, 18, 62, 11, 3, 6, 1, 1, 1,
|
||||
1, 1, 4, 41, 32, 35, 36, 11, 2, 6, 1, 1, 1, 1, 1, 46, 28, 88, 22,
|
||||
77, 11, 1, 6, 1, 1, 1, 1, 1, 17, 29, 74, 36, 61, 10, 0, 0, 0, 15,
|
||||
1,167, 0, 1,250, 1,244, 1,238, 1,233, 1,227, 1,221, 1,215, 1,209,
|
||||
1,203, 1,197, 1,191, 1,185, 1,179, 1,173, 1,167, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
5, 3, 1, 1, 49, 9, 5, 3, 1, 1, 48, 15, 5, 3, 1, 1, 46, 2, 5,
|
||||
3, 1, 1, 44, 8, 5, 3, 1, 1, 42, 11, 5, 3, 1, 1, 37, 6, 5, 3,
|
||||
1, 1, 35, 7, 5, 3, 1, 1, 34, 10, 5, 3, 1, 1, 32, 12, 5, 3, 1,
|
||||
1, 22, 14, 5, 3, 1, 1, 21, 4, 4, 3, 1, 9, 17, 5, 3, 1, 1, 15,
|
||||
5, 5, 3, 1, 1, 12, 13, 5, 3, 1, 1, 4, 3, 10, 0, 0, 0, 15, 1,
|
||||
167, 0, 1,250, 1,244, 1,238, 1,232, 1,226, 1,220, 1,214, 1,208, 1,
|
||||
202, 1,197, 1,191, 1,185, 1,179, 1,173, 1,167, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
|
||||
3, 1, 1, 48, 8, 5, 3, 1, 1, 45, 14, 5, 3, 1, 1, 41, 3, 5, 3,
|
||||
1, 1, 38, 7, 5, 3, 1, 1, 37, 15, 4, 3, 1, 9, 29, 5, 3, 1, 1,
|
||||
28, 2, 5, 3, 1, 1, 26, 10, 5, 3, 1, 1, 22, 4, 5, 3, 1, 1, 20,
|
||||
11, 5, 3, 1, 1, 17, 6, 5, 3, 1, 1, 16, 12, 5, 3, 1, 1, 9, 9,
|
||||
5, 3, 1, 1, 6, 5, 5, 3, 1, 1, 4, 13, 5, 0, 0, 0, 2, 1,246,
|
||||
0, 0, 0, 0, 27, 1,251, 1,246, 1,168, 1,148, 1,130, 1,107, 1, 86,
|
||||
1, 65, 1, 44, 1, 27, 1, 14, 0,250, 0,224, 0,205, 0,184, 0,165, 0,
|
||||
145, 0,123, 0,106, 0, 86, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 17, 23, 6, 0, 23, 1, 1, 21,107,110,111,119,110, 52, 19,112,
|
||||
111,111,114, 18, 22, 6, 0, 23, 1, 1, 23, 97, 98,111,118,101, 24, 26,115,
|
||||
101,114,118,101, 15, 21, 6, 0, 19, 1, 1, 21,119, 97,114, 52, 19,112,111,
|
||||
111,114, 20, 20, 6, 0, 27, 1, 8, 25,110,111,116,104,105,110,103, 7,112,
|
||||
108, 97, 99,101,115, 18, 19, 6, 0, 23, 1, 1, 23, 98,101,103, 97,116, 90,
|
||||
27,116,114,117,116,104, 17, 18, 6, 0, 23, 1, 1, 21,100,119,101,108,116,
|
||||
21, 39,100,111,116,104, 19, 17, 6, 0, 27, 1, 1, 21,109,111,114,110,105,
|
||||
110,103, 52, 19,112,111,111,114, 17, 16, 6, 0, 21, 1, 1, 23,115,104,101,
|
||||
119, 90, 27,116,114,117,116,104, 24, 15, 6, 0, 27, 1, 1, 31,116,104,101,
|
||||
114,101,105,110, 37, 31,115, 97, 99,114,105,102,105, 99,101, 18, 14, 6, 0,
|
||||
23, 1, 8, 25,115,109,111,116,101, 7,112,108, 97, 99,101,115, 11, 13, 6,
|
||||
0, 19, 1, 1, 0, 97,114,107, 72, 31, 15, 12, 6, 0, 21, 1, 8, 21,119,
|
||||
105,110,101, 58,119, 97,121,115, 19, 11, 6, 0, 21, 1, 1, 27,115,111,109,
|
||||
101, 98, 17,109,111,114,110,105,110,103, 19, 10, 6, 0, 27, 1, 1, 21, 98,
|
||||
101,116,119,101,101,110, 92, 18,115,111,109,101, 19, 9, 6, 0, 21, 1, 1,
|
||||
27,115, 97,118,101, 74, 36, 98,101,116,119,101,101,110, 21, 8, 6, 0, 25,
|
||||
1, 1, 27,116,104,111,117,103,104, 98, 17,109,111,114,110,105,110,103, 16,
|
||||
7, 6, 0, 21, 1, 1, 21,115,101,110,100, 49, 34,115,101,110,100, 18, 6,
|
||||
6, 0, 25, 1, 1, 21,119,105,115,100,111,109, 38, 36,115,101,110,100, 16,
|
||||
5, 6, 0, 23, 1, 9, 21, 97,110,103,101,114, 46,119, 97,121,115, 14, 4,
|
||||
6, 0, 19, 1, 1, 19, 99, 97,110, 19, 43,119, 97,114, 16, 3, 6, 0, 23,
|
||||
1, 1, 19,111,102,102,101,114, 48, 22,115,105,120, 16, 2, 6, 0, 23, 1,
|
||||
8, 21,119,111,114,107,115, 58,119, 97,121,115, 16, 1, 6, 0, 23, 1, 1,
|
||||
19, 0, 0, 0, 26, 45, 0, 0, 0, 25, 23, 13, 0, 0, 0, 7, 0, 48, 0,
|
||||
1,171, 1, 74, 1, 30, 0,126, 0,249, 0,212, 0, 48, 0, 81, 0, 0, 84,
|
||||
4, 7, 23, 17, 17, 1,129, 19,116, 97, 98,108,101,116, 52,116, 52, 5, 67,
|
||||
82, 69, 76, 7, 7, 23, 17, 17, 1,129, 3,116, 97, 98,108,101,116, 53,116,
|
||||
53, 8, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 53, 40, 97,
|
||||
32, 73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73, 77, 65, 82, 89, 32, 75, 69,
|
||||
89, 44, 32, 98, 32, 84, 69, 88, 84, 32, 85, 78, 73, 81, 85, 69, 44, 99, 44,
|
||||
100, 44,101, 41, 84, 4, 7, 23, 17, 17, 1,129, 19,116, 97, 98,108,101,116,
|
||||
52,116, 52, 5, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 52,
|
||||
40, 97, 32, 73, 78, 84, 32, 85, 78, 73, 81, 85, 69, 32, 78, 79, 84, 32, 78,
|
||||
85, 76, 76, 44, 32, 98, 32, 73, 78, 84, 32, 85, 78, 73, 81, 85, 69, 32, 78,
|
||||
79, 84, 32, 78, 85, 76, 76, 44, 99, 44,100, 44,101, 41, 35, 6, 6, 23, 55,
|
||||
17, 1, 0,105,110,100,101,120,115,113,108,105,116,101, 95, 97,117,116,111,
|
||||
105,110,100,101,120, 95,116, 52, 95, 50,116, 52, 7, 35, 5, 6, 23, 55, 17,
|
||||
1, 0,105,110,100,101,120,115,113,108,105,116,101, 95, 97,117,116,111,105,
|
||||
110,100,101,120, 95,116, 52, 95, 49,116, 52, 6, 42, 3, 6, 23, 17, 17, 1,
|
||||
65,116, 97, 98,108,101,116, 51,116, 51, 4, 67, 82, 69, 65, 84, 69, 32, 84,
|
||||
65, 66, 76, 69, 32,116, 51, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 95,
|
||||
2, 7, 23, 17, 17, 1,129, 41,116, 97, 98,108,101,116, 50,116, 50, 3, 67,
|
||||
82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 50, 40, 97, 32, 73, 78,
|
||||
84, 44, 32, 98, 32, 73, 78, 84, 44, 32, 99, 32, 73, 78, 84, 44,100, 32, 73,
|
||||
78, 84, 44,101, 32, 73, 78, 84, 44, 80, 82, 73, 77, 65, 82, 89, 32, 75, 69,
|
||||
89, 40, 98, 44, 97, 41, 41, 87, 73, 84, 72, 79, 85, 84, 32, 82, 79, 87, 73,
|
||||
68, 83, 1, 7, 23, 17, 17, 1,129, 17,116, 97, 98,108,101,116, 49,116, 49,
|
||||
2, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 49, 40, 97, 32,
|
||||
73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73, 77, 65, 82, 89, 32, 75, 69, 89,
|
||||
44, 32, 98, 32, 73, 78, 84, 44, 32, 99, 32, 73, 78, 84, 44, 32,100, 32, 73,
|
||||
78, 84, 44, 32,101, 32, 73, 78, 84, 41, 2, 0, 0, 0, 1, 1,243, 0, 0,
|
||||
0, 0, 29, 1,243, 1,218, 1,209, 1,199, 1,187, 1,179, 1,169, 1,158,
|
||||
1,145, 1,136, 1,127, 1,117, 1,107, 1, 98, 1, 82, 1, 72, 1, 63, 1,
|
||||
51, 1, 42, 1, 30, 1, 20, 1, 12, 1, 3, 0,248, 0,239, 0,225, 0,216,
|
||||
0,207, 0,197, 0,188, 0,180, 0,170, 0,161, 0,152, 0,141, 0,129, 0,
|
||||
118, 0,106, 0, 97, 0, 0, 0, 0, 0, 0, 0, 8, 3, 21, 1,116,114,101,
|
||||
101, 49, 11, 3, 27, 1,116,104,121,115,101,108,102, 27, 10, 3, 25, 1,116,
|
||||
104,111,117,103,104, 8, 11, 3, 27, 1,116,104,101,114,101,105,110, 15, 10,
|
||||
3, 25, 1,116,101,109,112,108,101, 43, 8, 3, 21, 1,116,101,108,108, 25,
|
||||
8, 3, 21, 1,115,111,109,101, 11, 9, 3, 23, 1,115,109,111,116,101, 14,
|
||||
7, 3, 19, 1,115,105,120, 48, 8, 3, 21, 1,115,104,101,119, 16, 9, 3,
|
||||
23, 1,115,101,114,118,101, 37, 8, 3, 21, 1,115,101,110,100, 7, 8, 3,
|
||||
21, 1,115, 97,118,101, 9, 13, 3, 31, 1,115, 97, 99,114,105,102,105, 99,
|
||||
101, 24, 8, 3, 21, 1,112,111,111,114, 40, 10, 3, 25, 1,112,108, 97, 99,
|
||||
101,115, 28, 8, 3, 21, 1,112, 97,114,116, 30, 7, 3, 19, 1,111,105,108,
|
||||
46, 9, 3, 23, 1,111,102,102,101,114, 3, 11, 3, 27, 1,110,111,116,104,
|
||||
105,110,103, 20, 8, 3, 21, 1,110,101, 97,114, 36, 11, 3, 27, 1,109,111,
|
||||
114,110,105,110,103, 17, 8, 3, 21, 1,108,111,110,103, 35, 9, 3, 23, 1,
|
||||
107,110,111,119,110, 23, 15, 3, 35, 1,105,110,104, 97, 98,105,116, 97,110,
|
||||
116,115, 45, 8, 3, 21, 1,103,111,110,101, 32, 9, 3, 23, 1,102,114,117,
|
||||
105,116, 38, 9, 3, 23, 1,100,119,101,108,116, 18, 8, 3, 21, 1,100,111,
|
||||
116,104, 39, 8, 3, 21, 1,100,105,101,100, 47, 12, 3, 29, 1,100,101,112,
|
||||
97,114,116,101,100, 26, 10, 3, 25, 1, 99,117, 98,105,116,115, 33, 9, 3,
|
||||
23, 1, 99,104,105,108,100, 42, 7, 3, 19, 1, 99, 97,110, 4, 11, 3, 27,
|
||||
1, 98,101,116,119,101,101,110, 10, 9, 3, 23, 1, 98,101,103, 97,116, 19,
|
||||
8, 3, 21, 1, 98,101, 97,114, 29, 7, 3, 19, 1, 97,114,107, 13, 9, 3,
|
||||
23, 1, 97,110,103,101,114, 5, 9, 3, 23, 1, 97,110,103, 0, 0, 0, 28,
|
||||
8, 3, 21, 1,116,114,101,101, 49, 13, 1,104, 0, 7, 0, 24, 0, 1, 67,
|
||||
1, 13, 0,225, 0,177, 0,109, 1,171, 0, 24, 0, 0, 83, 14, 7, 21, 19,
|
||||
19, 8,129, 17,118,105,101,119,118, 50, 48,118, 50, 48, 67, 82, 69, 65, 84,
|
||||
69, 32, 86, 73, 69, 87, 32,118, 50, 48, 40, 97, 44, 98, 44, 99, 44,100, 44,
|
||||
101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,
|
||||
100, 44,101, 32, 70, 82, 79, 77, 32,116, 50, 32, 87, 72, 69, 82, 69, 32, 97,
|
||||
60, 62, 50, 53, 66, 12, 6, 21, 19, 19, 8,113,118,105,101,119,118, 48, 48,
|
||||
118, 48, 48, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 48, 48, 40,
|
||||
97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67,
|
||||
84, 32, 49, 44, 49, 44, 49, 44, 49, 44, 39,111,110,101, 39, 46, 11, 6, 23,
|
||||
21, 17, 1, 69,105,110,100,101,120,116, 50,101,100,116, 50, 14, 67, 82, 69,
|
||||
65, 84, 69, 32, 73, 78, 68, 69, 88, 32,116, 50,101,100, 32, 79, 78, 32,116,
|
||||
50, 40,101, 44,100, 41, 42, 10, 6, 23, 19, 17, 1, 63,105,110,100,101,120,
|
||||
116, 49,101,116, 49, 13, 67, 82, 69, 65, 84, 69, 32, 73, 78, 68, 69, 88, 32,
|
||||
116, 49,101, 32, 79, 78, 32,116, 49, 40,101, 41, 52, 9, 6, 23, 21, 17, 1,
|
||||
81,105,110,100,101,120,116, 51,120, 49,116, 51, 12, 67, 82, 69, 65, 84, 69,
|
||||
32, 73, 78, 68, 69, 88, 32,116, 51,120, 49, 32, 79, 78, 32,116, 51, 40, 97,
|
||||
44, 98, 44, 99, 44,100, 44,101, 41, 35, 8, 6, 23, 55, 17, 1, 0,105,110,
|
||||
100,101,120,115,113,108,105,116,101, 95, 97,117,116,111,105,110,100,101,120,
|
||||
95,116, 53, 95, 49,116, 53, 10, 0, 0, 0, 67, 17, 17, 1,129, 3,116, 97,
|
||||
98,108,101,116, 53,116, 53, 8, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76,
|
||||
69, 32,116, 53, 40, 97, 32, 73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73, 77,
|
||||
65, 82, 89, 32, 75, 69, 89, 44, 32, 98, 32, 84, 69, 88, 84, 32, 85, 78, 83,
|
||||
13, 7, 21, 19, 19, 8,129, 17,118,105,101,119,118, 49, 48,118, 49, 48, 67,
|
||||
82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 49, 48, 40, 97, 44, 98, 44,
|
||||
99, 44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44,
|
||||
98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 32, 87, 72, 69,
|
||||
82, 69, 32, 97, 60, 62, 50, 53, 2, 0, 0, 0, 1, 1,240, 0, 0, 0, 0,
|
||||
24, 1,240, 1,220, 1,211, 1,199, 1,187, 1,176, 1,164, 1,148, 1,133,
|
||||
1,116, 1, 99, 1, 86, 1, 67, 1, 55, 1, 43, 1, 31, 1, 18, 1, 5, 0,
|
||||
249, 0,236, 0,224, 0,209, 0,191, 0,174, 0,157, 0,145, 0,132, 0,120,
|
||||
0,108, 0, 95, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 7, 1, 0,
|
||||
1, 1, 0, 1, 49, 51, 38, 15, 12, 7, 1, 1, 1, 1, 0, 1, 48, 37, 93,
|
||||
7, 30, 11, 7, 1, 1, 1, 0, 0, 1, 47, 22, 16, 24, 11, 7, 1, 0, 1,
|
||||
1, 0, 1, 47, 16, 40, 12, 12, 7, 1, 1, 1, 1, 0, 1, 46, 28, 88, 22,
|
||||
2, 11, 7, 1, 1, 0, 1, 0, 1, 44, 48, 9, 19, 16, 7, 1, 1, 1, 0,
|
||||
23, 1, 42, 20, 18, 98,101,103, 97,116, 22, 16, 7, 1, 1, 0, 1, 23, 1,
|
||||
37, 17, 18,100,119,101,108,116, 16, 17, 7, 1, 1, 0, 1, 25, 1, 35, 38,
|
||||
22, 99,117, 98,105,116,115, 17, 14, 7, 1, 1, 1, 0, 19, 1, 34, 26, 15,
|
||||
97,114,107, 21, 11, 7, 1, 1, 1, 0, 0, 1, 32, 16, 7, 23, 12, 7, 1,
|
||||
1, 1, 1, 0, 1, 28, 17, 67, 31, 29, 11, 7, 1, 0, 1, 1, 0, 1, 25,
|
||||
7, 19, 11, 12, 7, 1, 1, 1, 1, 0, 1, 22, 45, 71, 28, 28, 12, 7, 1,
|
||||
1, 1, 1, 0, 1, 21, 22, 92, 18, 4, 11, 7, 1, 1, 0, 1, 0, 1, 21,
|
||||
22, 18, 18, 11, 7, 1, 1, 1, 1, 0, 9, 17, 29, 74, 36, 11, 7, 1, 1,
|
||||
1, 0, 0, 1, 17, 29, 74, 25, 18, 7, 1, 1, 1, 1, 25, 1, 15, 6, 3,
|
||||
11,116,101,109,112,108,101, 5, 12, 7, 1, 1, 1, 1, 0, 1, 12, 4, 38,
|
||||
36, 27, 16, 7, 1, 0, 1, 1, 23, 1, 10, 89, 14,115,101,114,118,101, 14,
|
||||
16, 7, 1, 1, 1, 1, 21, 1, 4, 41, 32, 35,110,101, 97,114, 3, 14, 7,
|
||||
9, 0, 1, 1, 21, 1, 68, 32,100,111,116,104, 13, 15, 7, 0, 1, 1, 1,
|
||||
21, 1, 21, 91, 38,110,101, 97,114, 6, 11, 7, 0, 1, 1, 1, 0, 1, 16,
|
||||
81, 25, 9, 10, 7, 0, 1, 1, 8, 0, 1, 16, 7, 10, 11, 7, 0, 1, 1,
|
||||
1, 0, 1, 7, 72, 31, 8, 11, 7, 0, 1, 1, 1, 0, 1, 6, 37, 31, 7,
|
||||
8, 7, 0, 0, 0, 0, 0, 1, 35, 8, 7, 0, 0, 0, 0, 0, 1, 34, 8,
|
||||
7, 0, 0, 0, 0, 0, 1, 33, 8, 7, 0, 0, 0, 23, 11, 7, 1, 0, 1,
|
||||
1, 0, 1, 49, 51, 38, 15, 2, 0, 0, 0, 1, 1,241, 0, 0, 0, 0, 18,
|
||||
1,241, 1,221, 1,211, 1,203, 1,193, 1,183, 1,173, 1,163, 1,151, 1,
|
||||
143, 1,133, 1,122, 1,109, 1,100, 1, 92, 1, 83, 1, 74, 1, 64, 1, 55,
|
||||
1, 46, 1, 34, 1, 22, 1, 13, 1, 4, 0,252, 0,241, 0,232, 0,218, 0,
|
||||
209, 0,200, 0,191, 0,182, 0,173, 0,163, 0,153, 0,144, 0,136, 0,127,
|
||||
0,116, 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3,
|
||||
25, 1,116,101,109,112,108,101, 48, 10, 3, 25, 1,116,101,109,112,108,101,
|
||||
15, 8, 3, 21, 1,115,111,109,101, 21, 7, 3, 19, 1,115,105,120, 11, 8,
|
||||
3, 21, 1,115,104,101,119, 38, 9, 3, 23, 1,115,101,114,118,101, 10, 9,
|
||||
3, 23, 1,115,101,114,118,101, 3, 8, 3, 21, 1,115,101,110,100, 40, 8,
|
||||
3, 21, 1,115,101,110,100, 29, 8, 3, 21, 1,115,101,110,100, 12, 8, 3,
|
||||
21, 1,115,101,110,100, 8, 8, 3, 21, 1,115, 97,118,101, 2, 13, 3, 31,
|
||||
1,115, 97, 99,114,105,102,105, 99,101, 23, 8, 3, 21, 1,112,111,111,114,
|
||||
16, 10, 3, 25, 1,112,108, 97, 99,101,115, 32, 7, 3, 19, 1,111,105,108,
|
||||
49, 8, 3, 21, 1,110,101, 97,114, 7, 8, 3, 21, 1,110,101, 97,114, 4,
|
||||
11, 3, 27, 1,109,111,114,110,105,110,103, 41, 11, 3, 27, 1,109,111,114,
|
||||
110,105,110,103, 26, 8, 3, 21, 1,103,111,110,101, 25, 8, 3, 21, 1,103,
|
||||
111,110,101, 5, 9, 3, 23, 1,100,119,101,108,116, 37, 8, 3, 21, 1,100,
|
||||
111,116,104, 44, 8, 3, 21, 1,100,111,116,104, 13, 7, 3, 21, 9,100,111,
|
||||
116,104, 8, 3, 21, 1,100,105,101,100, 14, 12, 3, 29, 1,100,101,112, 97,
|
||||
114,116,101,100, 46, 10, 3, 25, 1, 99,117, 98,105,116,115, 35, 9, 3, 23,
|
||||
1, 99,104,105,108,100, 36, 7, 3, 19, 1, 99, 97,110, 6, 11, 3, 27, 1,
|
||||
98,101,116,119,101,101,110, 17, 9, 3, 23, 1, 98,101,103, 97,116, 43, 9,
|
||||
3, 23, 1, 98,101,103, 97,116, 42, 9, 3, 23, 1, 98,101,103, 97,116, 39,
|
||||
9, 3, 23, 1, 98,101,103, 97,116, 9, 7, 3, 19, 1, 97,114,107, 34, 9,
|
||||
3, 23, 1, 97,110,103,101,114, 47, 9, 3, 23, 1, 97,110,103,101,108, 27,
|
||||
9, 3, 23, 1, 97, 98,111,118,101, 45, 0, 0, 0, 17, 10, 3, 25, 1,116,
|
||||
101,109,112,108,101, 48, 2, 0, 0, 0, 1, 1,239, 0, 0, 0, 0, 20, 1,
|
||||
239, 1,206, 1,192, 1,180, 1,166, 1,152, 1,138, 1,125, 1,109, 1, 97,
|
||||
1, 84, 1, 69, 1, 52, 1, 39, 1, 26, 1, 14, 1, 1, 0,243, 0,230, 0,
|
||||
217, 0,201, 0,185, 0,172, 0,159, 0,147, 0,133, 0,120, 0,102, 0, 89,
|
||||
0, 76, 0, 0, 0, 0, 12, 5, 21, 1, 1, 1,115,101,110,100, 26, 14, 40,
|
||||
12, 5, 21, 1, 1, 1,115, 97,118,101, 39, 45, 2, 17, 5, 31, 1, 1, 1,
|
||||
115, 97, 99,114,105,102,105, 99,101, 31, 6, 23, 12, 5, 21, 1, 1, 1,112,
|
||||
111,111,114, 19, 44, 16, 13, 5, 25, 8, 1, 1,112,108, 97, 99,101,115, 16,
|
||||
32, 11, 5, 19, 1, 1, 1,111,105,108, 38, 9, 49, 12, 5, 21, 1, 1, 1,
|
||||
110,101, 97,114, 38, 21, 7, 12, 5, 21, 1, 1, 1,110,101, 97,114, 35, 41,
|
||||
4, 15, 5, 27, 1, 1, 1,109,111,114,110,105,110,103, 17, 40, 26, 15, 5,
|
||||
27, 1, 1, 1,109,111,114,110,105,110,103, 13, 46, 41, 12, 5, 21, 1, 1,
|
||||
1,103,111,110,101, 28, 25, 5, 12, 5, 21, 1, 1, 1,103,111,110,101, 19,
|
||||
10, 25, 13, 5, 23, 1, 1, 1,100,119,101,108,116, 18, 17, 37, 12, 5, 21,
|
||||
1, 1, 1,100,111,116,104, 39, 4, 13, 11, 5, 21, 1, 1, 9,100,111,116,
|
||||
104, 32, 40, 12, 5, 21, 1, 1, 1,100,111,116,104, 9, 48, 44, 12, 5, 21,
|
||||
1, 1, 1,100,105,101,100, 27, 35, 14, 16, 5, 29, 1, 1, 1,100,101,112,
|
||||
97,114,116,101,100, 22, 28, 46, 14, 5, 25, 1, 1, 1, 99,117, 98,105,116,
|
||||
115, 22, 38, 35, 12, 5, 23, 1, 8, 1, 99,104,105,108,100, 17, 36, 11, 5,
|
||||
19, 1, 1, 1, 99, 97,110, 11, 2, 6, 15, 5, 27, 1, 1, 1, 98,101,116,
|
||||
119,101,101,110, 36, 29, 17, 12, 5, 23, 1, 8, 1, 98,101,103, 97,116, 50,
|
||||
9, 13, 5, 23, 1, 1, 1, 98,101,103, 97,116, 45, 3, 39, 13, 5, 23, 1,
|
||||
1, 1, 98,101,103, 97,116, 41, 5, 43, 13, 5, 23, 1, 1, 1, 98,101,103,
|
||||
97,116, 5, 20, 42, 11, 5, 19, 1, 1, 1, 97,114,107, 20, 26, 34, 13, 5,
|
||||
23, 1, 1, 1, 97,110,103,101,114, 40, 22, 47, 13, 5, 23, 1, 1, 1, 97,
|
||||
110,103,101,108, 3, 22, 27, 12, 5, 23, 1, 9, 1, 97, 98,111,118,101, 45,
|
||||
20, 13, 5, 23, 1, 1, 1, 0, 0, 0, 19, 12, 5, 21, 1, 1, 1,115,101,
|
||||
110,100, 26, 14, 40, 13, 0, 0, 0, 28, 0, 78, 0, 1,241, 1,226, 1,210,
|
||||
1,195, 1,180, 1,166, 1,151, 1,136, 1,121, 1,105, 1, 91, 1, 76, 1,
|
||||
61, 1, 46, 1, 29, 1, 14, 0,252, 0,238, 0,224, 0,209, 0,194, 0,177,
|
||||
0,157, 0,143, 0,128, 0,110, 0, 94, 0, 78, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 14, 28, 6, 0, 1, 1, 1, 23, 17, 67, 31,119,
|
||||
111,114,107,115, 14, 27, 6, 0, 1, 1, 1, 23, 22, 71, 3, 97,110,103,101,
|
||||
108, 16, 26, 6, 0, 1, 1, 1, 27, 40, 98, 17,109,111,114,110,105,110,103,
|
||||
13, 25, 6, 0, 1, 1, 1, 21, 10, 7, 19,103,111,110,101, 12, 24, 6, 0,
|
||||
1, 1, 9, 21, 43, 46,119, 97,121,115, 18, 23, 6, 0, 1, 1, 1, 31, 6,
|
||||
37, 31,115, 97, 99,114,105,102,105, 99,101, 15, 22, 6, 0, 1, 1, 1, 25,
|
||||
45, 71, 28,116,104,111,117,103,104, 13, 21, 6, 0, 1, 1, 1, 21, 22, 92,
|
||||
18,115,111,109,101, 13, 20, 6, 0, 9, 1, 1, 23, 2, 45, 97, 98,111,118,
|
||||
101, 12, 19, 6, 0, 1, 1, 8, 21, 4, 58,119, 97,121,115, 12, 18, 6, 0,
|
||||
1, 1, 1, 19, 44, 19, 43,119, 97,114, 16, 17, 6, 0, 1, 1, 1, 27, 29,
|
||||
74, 36, 98,101,116,119,101,101,110, 13, 16, 6, 0, 1, 1, 1, 21, 44, 52,
|
||||
19,112,111,111,114, 15, 15, 6, 0, 1, 1, 1, 25, 6, 3, 11,116,101,109,
|
||||
112,108,101, 13, 14, 6, 0, 1, 1, 1, 21, 35, 48, 27,100,105,101,100, 13,
|
||||
13, 6, 0, 1, 1, 1, 21, 4, 21, 39,100,111,116,104, 13, 12, 6, 0, 1,
|
||||
1, 1, 21, 4, 38, 36,115,101,110,100, 12, 11, 6, 0, 1, 1, 1, 19, 13,
|
||||
48, 22,115,105,120, 14, 10, 6, 0, 1, 1, 1, 23, 41, 89, 14,115,101,114,
|
||||
118,101, 13, 9, 6, 0, 8, 1, 1, 23, 16, 50, 98,101,103, 97,116, 13, 8,
|
||||
6, 0, 1, 1, 1, 21, 42, 49, 34,115,101,110,100, 13, 7, 6, 0, 1, 1,
|
||||
1, 21, 21, 91, 38,110,101, 97,114, 12, 6, 6, 0, 1, 1, 1, 19, 2, 37,
|
||||
11, 99, 97,110, 13, 5, 6, 0, 1, 1, 1, 21, 25, 27, 28,103,111,110,101,
|
||||
13, 4, 6, 0, 1, 1, 1, 21, 41, 32, 35,110,101, 97,114, 14, 3, 6, 0,
|
||||
1, 1, 1, 23, 32, 24, 26,115,101,114,118,101, 13, 2, 6, 0, 1, 1, 1,
|
||||
21, 45, 14, 39,115, 97,118,101, 13, 1, 6, 0, 1, 1, 1, 21, 40, 68, 32,
|
||||
100,111,116,104, 13, 0, 0, 0, 22, 0,166, 0, 1,241, 1,226, 1,210, 1,
|
||||
194, 1,183, 1,169, 1,152, 1,137, 1,121, 1,106, 1, 90, 1, 75, 1, 57,
|
||||
1, 41, 1, 25, 1, 10, 0,250, 0,231, 0,215, 0,198, 0,184, 0,166, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
|
||||
50, 6, 0, 1, 1, 1, 27, 9, 92, 29,116,104,101,114,101,105,110, 12, 49,
|
||||
6, 0, 1, 1, 1, 19, 9, 51, 38,111,105,108, 15, 48, 6, 0, 1, 1, 1,
|
||||
25, 37, 93, 7,116,101,109,112,108,101, 14, 47, 6, 0, 1, 1, 1, 23, 22,
|
||||
16, 40, 97,110,103,101,114, 17, 46, 6, 0, 1, 1, 1, 29, 28, 88, 22,100,
|
||||
101,112, 97,114,116,101,100, 14, 45, 6, 0, 1, 1, 1, 23, 47, 54, 12, 97,
|
||||
98,111,118,101, 13, 44, 6, 0, 1, 1, 1, 21, 48, 15, 9,100,111,116,104,
|
||||
14, 43, 6, 0, 1, 1, 1, 23, 5, 23, 41, 98,101,103, 97,116, 14, 42, 6,
|
||||
0, 1, 1, 1, 23, 20, 18, 5, 98,101,103, 97,116, 16, 41, 6, 0, 1, 1,
|
||||
1, 27, 46, 92, 13,109,111,114,110,105,110,103, 13, 40, 6, 0, 1, 1, 1,
|
||||
21, 14, 30, 26,115,101,110,100, 14, 39, 6, 0, 1, 1, 1, 23, 3, 21, 45,
|
||||
98,101,103, 97,116, 13, 38, 6, 0, 1, 1, 1, 21, 10, 97, 34,115,104,101,
|
||||
119, 14, 37, 6, 0, 1, 1, 1, 23, 17, 66, 18,100,119,101,108,116, 13, 36,
|
||||
6, 0, 8, 1, 1, 23, 52, 17, 99,104,105,108,100, 15, 35, 6, 0, 1, 1,
|
||||
1, 25, 38, 34, 22, 99,117, 98,105,116,115, 12, 34, 6, 0, 1, 1, 1, 19,
|
||||
26, 15, 20, 97,114,107, 9, 33, 6, 0, 1, 1, 1, 0, 7, 72, 31, 14, 32,
|
||||
6, 0, 1, 1, 8, 25, 16, 7,112,108, 97, 99,101,115, 14, 31, 6, 0, 1,
|
||||
1, 1, 23, 39, 90, 27,116,114,117,116,104, 13, 30, 6, 0, 1, 1, 1, 21,
|
||||
16, 81, 25,119, 97,108,107, 13, 29, 6, 0, 1, 1, 1, 21, 34, 62, 27,115,
|
||||
101,110,100, 10, 0, 0, 0, 41, 0,116, 0, 1,251, 1,241, 1,231, 1,221,
|
||||
1,211, 1,203, 1,193, 1,183, 1,173, 1,163, 1,151, 1,143, 1,133, 1,
|
||||
122, 1,109, 1,100, 1, 92, 1, 83, 1, 74, 1, 64, 1, 55, 1, 46, 1, 34,
|
||||
1, 22, 1, 13, 1, 4, 0,252, 0,241, 0,232, 0,218, 0,209, 0,200, 0,
|
||||
191, 0,182, 0,173, 0,163, 0,153, 0,144, 0,136, 0,127, 0,116, 0,105,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11,116,101,
|
||||
109,112,108,101, 48, 10, 3, 25, 1,116,101,109,112,108,101, 15, 8, 3, 21,
|
||||
1,115,111,109,101, 21, 7, 3, 19, 1,115,105,120, 11, 8, 3, 21, 1,115,
|
||||
104,101,119, 38, 9, 3, 23, 1,115,101,114,118,101, 10, 9, 3, 23, 1,115,
|
||||
101,114,118,101, 3, 8, 3, 21, 1,115,101,110,100, 40, 8, 3, 21, 1,115,
|
||||
101,110,100, 29, 8, 3, 21, 1,115,101,110,100, 12, 8, 3, 21, 1,115,101,
|
||||
110,100, 8, 8, 3, 21, 1,115, 97,118,101, 2, 13, 3, 31, 1,115, 97, 99,
|
||||
114,105,102,105, 99,101, 23, 8, 3, 21, 1,112,111,111,114, 16, 10, 3, 25,
|
||||
1,112,108, 97, 99,101,115, 32, 7, 3, 19, 1,111,105,108, 49, 8, 3, 21,
|
||||
1,110,101, 97,114, 7, 8, 3, 21, 1,110,101, 97,114, 4, 11, 3, 27, 1,
|
||||
109,111,114,110,105,110,103, 41, 11, 3, 27, 1,109,111,114,110,105,110,103,
|
||||
26, 8, 3, 21, 1,103,111,110,101, 25, 8, 3, 21, 1,103,111,110,101, 5,
|
||||
9, 3, 23, 1,100,119,101,108,116, 37, 8, 3, 21, 1,100,111,116,104, 44,
|
||||
8, 3, 21, 1,100,111,116,104, 13, 7, 3, 21, 9,100,111,116,104, 8, 3,
|
||||
21, 1,100,105,101,100, 14, 12, 3, 29, 1,100,101,112, 97,114,116,101,100,
|
||||
46, 10, 3, 25, 1, 99,117, 98,105,116,115, 35, 9, 3, 23, 1, 99,104,105,
|
||||
108,100, 36, 7, 3, 19, 1, 99, 97,110, 6, 11, 3, 27, 1, 98,101,116,119,
|
||||
101,101,110, 17, 9, 3, 23, 1, 98,101,103, 97,116, 43, 9, 3, 23, 1, 98,
|
||||
101,103, 97,116, 42, 9, 3, 23, 1, 98,101,103, 97,116, 39, 9, 3, 23, 1,
|
||||
98,101,103, 97,116, 9, 7, 3, 19, 1, 97,114,107, 34, 9, 3, 23, 1, 97,
|
||||
110,103,101,114, 47, 9, 3, 23, 1, 97,110,103,101,108, 27, 9, 3, 23, 1,
|
||||
97, 98,111,118,101, 45, 9, 3, 23, 1, 97, 98,111,118,101, 20, 4, 3, 0,
|
||||
1, 33, 10, 0, 0, 0, 8, 1,178, 0, 1,244, 1,233, 1,223, 1,214, 1,
|
||||
206, 1,197, 1,188, 1,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
|
||||
3, 23, 1,119,111,114,107,115, 28, 8, 3, 21, 1,119, 97,121,115, 24, 8,
|
||||
3, 21, 1,119, 97,121,115, 19, 7, 3, 19, 1,119, 97,114, 18, 8, 3, 21,
|
||||
1,119, 97,108,107, 30, 9, 3, 23, 1,116,114,117,116,104, 31, 10, 3, 25,
|
||||
1,116,104,111,117,103,104, 22, 11, 3, 27, 1,116,104,101,114,101,105,110,
|
||||
50, 10, 0, 0, 0, 31, 0, 89, 0, 1,247, 1,233, 1,220, 1,206, 1,192,
|
||||
1,180, 1,166, 1,152, 1,138, 1,125, 1,109, 1, 97, 1, 84, 1, 69, 1,
|
||||
52, 1, 39, 1, 26, 1, 14, 1, 1, 0,243, 0,230, 0,217, 0,201, 0,185,
|
||||
0,172, 0,159, 0,147, 0,133, 0,120, 0,102, 0, 89, 0, 76, 0, 0, 0,
|
||||
0, 0, 0, 0, 13, 1, 1,115,101,110,100, 26, 14, 40, 12, 5, 21, 1, 1,
|
||||
1,115, 97,118,101, 39, 45, 2, 17, 5, 31, 1, 1, 1,115, 97, 99,114,105,
|
||||
102,105, 99,101, 31, 6, 23, 12, 5, 21, 1, 1, 1,112,111,111,114, 19, 44,
|
||||
16, 13, 5, 25, 8, 1, 1,112,108, 97, 99,101,115, 16, 32, 11, 5, 19, 1,
|
||||
1, 1,111,105,108, 38, 9, 49, 12, 5, 21, 1, 1, 1,110,101, 97,114, 38,
|
||||
21, 7, 12, 5, 21, 1, 1, 1,110,101, 97,114, 35, 41, 4, 15, 5, 27, 1,
|
||||
1, 1,109,111,114,110,105,110,103, 17, 40, 26, 15, 5, 27, 1, 1, 1,109,
|
||||
111,114,110,105,110,103, 13, 46, 41, 12, 5, 21, 1, 1, 1,103,111,110,101,
|
||||
28, 25, 5, 12, 5, 21, 1, 1, 1,103,111,110,101, 19, 10, 25, 13, 5, 23,
|
||||
1, 1, 1,100,119,101,108,116, 18, 17, 37, 12, 5, 21, 1, 1, 1,100,111,
|
||||
116,104, 39, 4, 13, 11, 5, 21, 1, 1, 9,100,111,116,104, 32, 40, 12, 5,
|
||||
21, 1, 1, 1,100,111,116,104, 9, 48, 44, 12, 5, 21, 1, 1, 1,100,105,
|
||||
101,100, 27, 35, 14, 16, 5, 29, 1, 1, 1,100,101,112, 97,114,116,101,100,
|
||||
22, 28, 46, 14, 5, 25, 1, 1, 1, 99,117, 98,105,116,115, 22, 38, 35, 12,
|
||||
5, 23, 1, 8, 1, 99,104,105,108,100, 17, 36, 11, 5, 19, 1, 1, 1, 99,
|
||||
97,110, 11, 2, 6, 15, 5, 27, 1, 1, 1, 98,101,116,119,101,101,110, 36,
|
||||
29, 17, 12, 5, 23, 1, 8, 1, 98,101,103, 97,116, 50, 9, 13, 5, 23, 1,
|
||||
1, 1, 98,101,103, 97,116, 45, 3, 39, 13, 5, 23, 1, 1, 1, 98,101,103,
|
||||
97,116, 41, 5, 43, 13, 5, 23, 1, 1, 1, 98,101,103, 97,116, 5, 20, 42,
|
||||
11, 5, 19, 1, 1, 1, 97,114,107, 20, 26, 34, 13, 5, 23, 1, 1, 1, 97,
|
||||
110,103,101,114, 40, 22, 47, 13, 5, 23, 1, 1, 1, 97,110,103,101,108, 3,
|
||||
22, 27, 12, 5, 23, 1, 9, 1, 97, 98,111,118,101, 45, 20, 13, 5, 23, 1,
|
||||
1, 1, 97, 98,111,118,101, 12, 47, 45, 8, 5, 0, 1, 1, 1, 31, 7, 33,
|
||||
10, 0, 0, 0, 18, 1, 13, 0, 1,243, 1,230, 1,217, 1,203, 1,189, 1,
|
||||
176, 1,164, 1,151, 1,136, 1,121, 1,105, 1, 90, 1, 76, 1, 63, 1, 51,
|
||||
1, 39, 1, 27, 1, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 13, 5, 23, 1, 1, 1,119,111,114,107,115, 31, 17, 28, 11, 5,
|
||||
21, 9, 1, 1,119, 97,121,115, 43, 24, 11, 5, 21, 8, 1, 1,119, 97,121,
|
||||
115, 4, 19, 11, 5, 19, 1, 1, 1,119, 97,114, 43, 44, 18, 12, 5, 21, 1,
|
||||
1, 1,119, 97,108,107, 25, 16, 30, 13, 5, 23, 1, 1, 1,116,114,117,116,
|
||||
104, 27, 39, 31, 14, 5, 25, 1, 1, 1,116,104,111,117,103,104, 28, 45, 22,
|
||||
15, 5, 27, 1, 1, 1,116,104,101,114,101,105,110, 29, 9, 50, 14, 5, 25,
|
||||
1, 1, 1,116,101,109,112,108,101, 11, 6, 15, 14, 5, 25, 1, 1, 1,116,
|
||||
101,109,112,108,101, 7, 37, 48, 12, 5, 21, 1, 1, 1,115,111,109,101, 18,
|
||||
22, 21, 11, 5, 19, 1, 1, 1,115,105,120, 22, 13, 11, 12, 5, 21, 1, 1,
|
||||
1,115,104,101,119, 34, 10, 38, 13, 5, 23, 1, 1, 1,115,101,114,118,101,
|
||||
26, 32, 3, 13, 5, 23, 1, 1, 1,115,101,114,118,101, 14, 41, 10, 12, 5,
|
||||
21, 1, 1, 1,115,101,110,100, 36, 4, 12, 12, 5, 21, 1, 1, 1,115,101,
|
||||
110,100, 34, 42, 8, 12, 5, 21, 1, 1, 1,115,101,110,100, 27, 34, 29, 10,
|
||||
0, 0, 0, 28, 0, 82, 0, 1,241, 1,226, 1,211, 1,197, 1,181, 1,166,
|
||||
1,151, 1,137, 1,121, 1,104, 1, 84, 1, 73, 1, 59, 1, 41, 1, 26, 1,
|
||||
11, 0,253, 0,238, 0,223, 0,207, 0,191, 0,175, 0,159, 0,144, 0,129,
|
||||
0,113, 0, 97, 0, 82, 0, 68, 0, 0, 0, 0, 0, 14, 1, 1, 19, 26, 34,
|
||||
15, 20, 97,114,107, 14, 6, 1, 1, 1, 1, 21, 25, 5, 27, 28,103,111,110,
|
||||
101, 15, 6, 1, 1, 1, 1, 23, 22, 47, 16, 40, 97,110,103,101,114, 15, 6,
|
||||
1, 1, 1, 1, 23, 22, 27, 71, 3, 97,110,103,101,108, 14, 6, 1, 1, 1,
|
||||
1, 21, 22, 21, 92, 18,115,111,109,101, 14, 6, 1, 1, 1, 1, 21, 21, 7,
|
||||
91, 38,110,101, 97,114, 15, 6, 1, 1, 1, 1, 23, 20, 42, 18, 5, 98,101,
|
||||
103, 97,116, 15, 6, 1, 1, 1, 1, 23, 17, 37, 66, 18,100,119,101,108,116,
|
||||
15, 6, 1, 1, 1, 1, 23, 17, 28, 67, 31,119,111,114,107,115, 15, 6, 1,
|
||||
1, 1, 8, 25, 16, 32, 7,112,108, 97, 99,101,115, 14, 6, 1, 1, 1, 1,
|
||||
21, 16, 30, 81, 25,119, 97,108,107, 14, 6, 1, 1, 1, 1, 21, 14, 40, 30,
|
||||
26,115,101,110,100, 13, 6, 1, 1, 1, 1, 19, 13, 11, 48, 22,115,105,120,
|
||||
14, 6, 1, 1, 1, 1, 21, 10, 38, 97, 34,115,104,101,119, 14, 6, 1, 1,
|
||||
1, 1, 21, 10, 25, 7, 19,103,111,110,101, 17, 6, 1, 1, 1, 1, 27, 9,
|
||||
50, 92, 29,116,104,101,114,101,105,110, 13, 6, 1, 1, 1, 1, 19, 9, 49,
|
||||
51, 38,111,105,108, 10, 6, 1, 1, 1, 1, 0, 7, 33, 72, 31, 19, 6, 1,
|
||||
1, 1, 1, 31, 6, 23, 37, 31,115, 97, 99,114,105,102,105, 99,101, 16, 6,
|
||||
1, 1, 1, 1, 25, 6, 15, 3, 11,116,101,109,112,108,101, 15, 6, 1, 1,
|
||||
1, 1, 23, 5, 43, 23, 41, 98,101,103, 97,116, 13, 6, 1, 1, 1, 8, 21,
|
||||
4, 19, 58,119, 97,121,115, 14, 6, 1, 1, 1, 1, 21, 4, 13, 21, 39,100,
|
||||
111,116,104, 14, 6, 1, 1, 1, 1, 21, 4, 12, 38, 36,115,101,110,100, 15,
|
||||
6, 1, 1, 1, 1, 23, 3, 39, 21, 45, 98,101,103, 97,116, 13, 6, 1, 1,
|
||||
1, 1, 19, 2, 6, 37, 11, 99, 97,110, 14, 6, 9, 1, 1, 1, 23, 20, 2,
|
||||
45, 97, 98,111,118,101, 14, 6, 8, 1, 1, 1, 23, 36, 52, 17, 99,104,105,
|
||||
108,100, 14, 6, 8, 1, 1, 1, 23, 9, 16, 50, 98,101,103, 97,116, 10, 0,
|
||||
0, 0, 21, 0,177, 0, 1,237, 1,219, 1,203, 1,188, 1,173, 1,156, 1,
|
||||
139, 1,123, 1,109, 1, 91, 1, 76, 1, 60, 1, 45, 1, 31, 1, 16, 1, 2,
|
||||
0,243, 0,226, 0,208, 0,192, 0,177, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 14, 6, 1, 1, 1, 1, 21, 48, 44, 15, 9,100,111,116,104,
|
||||
15, 6, 1, 1, 1, 1, 23, 47, 45, 54, 12, 97, 98,111,118,101, 17, 6, 1,
|
||||
1, 1, 1, 27, 46, 41, 92, 13,109,111,114,110,105,110,103, 16, 6, 1, 1,
|
||||
1, 1, 25, 45, 22, 71, 28,116,104,111,117,103,104, 14, 6, 1, 1, 1, 1,
|
||||
21, 45, 2, 14, 39,115, 97,118,101, 13, 6, 1, 1, 1, 1, 19, 44, 18, 19,
|
||||
43,119, 97,114, 14, 6, 1, 1, 1, 1, 21, 44, 16, 52, 19,112,111,111,114,
|
||||
13, 6, 1, 1, 1, 9, 21, 43, 24, 46,119, 97,121,115, 14, 6, 1, 1, 1,
|
||||
1, 21, 42, 8, 49, 34,115,101,110,100, 15, 6, 1, 1, 1, 1, 23, 41, 10,
|
||||
89, 14,115,101,114,118,101, 14, 6, 1, 1, 1, 1, 21, 41, 4, 32, 35,110,
|
||||
101, 97,114, 17, 6, 1, 1, 1, 1, 27, 40, 26, 98, 17,109,111,114,110,105,
|
||||
110,103, 13, 6, 1, 9, 1, 1, 21, 40, 68, 32,100,111,116,104, 15, 6, 1,
|
||||
1, 1, 1, 23, 39, 31, 90, 27,116,114,117,116,104, 16, 6, 1, 1, 1, 1,
|
||||
25, 38, 35, 34, 22, 99,117, 98,105,116,115, 16, 6, 1, 1, 1, 1, 25, 37,
|
||||
48, 93, 7,116,101,109,112,108,101, 14, 6, 1, 1, 1, 1, 21, 35, 14, 48,
|
||||
27,100,105,101,100, 14, 6, 1, 1, 1, 1, 21, 34, 29, 62, 27,115,101,110,
|
||||
100, 15, 6, 1, 1, 1, 1, 23, 32, 3, 24, 26,115,101,114,118,101, 17, 6,
|
||||
1, 1, 1, 1, 27, 29, 17, 74, 36, 98,101,116,119,101,101,110, 18, 6, 1,
|
||||
1, 1, 1, 29, 28, 46, 88, 22,100,101,112, 97,114,116,101,100, 10, 0, 0,
|
||||
0, 32, 0, 95, 0, 1,247, 1,238, 1,229, 1,220, 1,211, 1,199, 1,187,
|
||||
1,176, 1,164, 1,148, 1,133, 1,116, 1, 99, 1, 86, 1, 67, 1, 55, 1,
|
||||
43, 1, 31, 1, 18, 1, 5, 0,249, 0,236, 0,224, 0,209, 0,191, 0,174,
|
||||
0,157, 0,145, 0,132, 0,120, 0,108, 0, 95, 0, 83, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 12, 1, 1, 0, 1, 49, 51, 38, 15, 12, 7, 1,
|
||||
1, 1, 1, 0, 1, 48, 37, 93, 7, 30, 11, 7, 1, 1, 1, 0, 0, 1, 47,
|
||||
22, 16, 24, 11, 7, 1, 0, 1, 1, 0, 1, 47, 16, 40, 12, 12, 7, 1, 1,
|
||||
1, 1, 0, 1, 46, 28, 88, 22, 2, 11, 7, 1, 1, 0, 1, 0, 1, 44, 48,
|
||||
9, 19, 16, 7, 1, 1, 1, 0, 23, 1, 42, 20, 18, 98,101,103, 97,116, 22,
|
||||
16, 7, 1, 1, 0, 1, 23, 1, 37, 17, 18,100,119,101,108,116, 16, 17, 7,
|
||||
1, 1, 0, 1, 25, 1, 35, 38, 22, 99,117, 98,105,116,115, 17, 14, 7, 1,
|
||||
1, 1, 0, 19, 1, 34, 26, 15, 97,114,107, 21, 11, 7, 1, 1, 1, 0, 0,
|
||||
1, 32, 16, 7, 23, 12, 7, 1, 1, 1, 1, 0, 1, 28, 17, 67, 31, 29, 11,
|
||||
7, 1, 0, 1, 1, 0, 1, 25, 7, 19, 11, 12, 7, 1, 1, 1, 1, 0, 1,
|
||||
22, 45, 71, 28, 28, 12, 7, 1, 1, 1, 1, 0, 1, 21, 22, 92, 18, 4, 11,
|
||||
7, 1, 1, 0, 1, 0, 1, 21, 22, 18, 18, 11, 7, 1, 1, 1, 1, 0, 9,
|
||||
17, 29, 74, 36, 11, 7, 1, 1, 1, 0, 0, 1, 17, 29, 74, 25, 18, 7, 1,
|
||||
1, 1, 1, 25, 1, 15, 6, 3, 11,116,101,109,112,108,101, 5, 12, 7, 1,
|
||||
1, 1, 1, 0, 1, 12, 4, 38, 36, 27, 16, 7, 1, 0, 1, 1, 23, 1, 10,
|
||||
89, 14,115,101,114,118,101, 14, 16, 7, 1, 1, 1, 1, 21, 1, 4, 41, 32,
|
||||
35,110,101, 97,114, 3, 14, 7, 9, 0, 1, 1, 21, 1, 68, 32,100,111,116,
|
||||
104, 13, 15, 7, 0, 1, 1, 1, 21, 1, 21, 91, 38,110,101, 97,114, 6, 11,
|
||||
7, 0, 1, 1, 1, 0, 1, 16, 81, 25, 9, 10, 7, 0, 1, 1, 8, 0, 1,
|
||||
16, 7, 10, 11, 7, 0, 1, 1, 1, 0, 1, 7, 72, 31, 8, 11, 7, 0, 1,
|
||||
1, 1, 0, 1, 6, 37, 31, 7, 8, 7, 0, 0, 0, 0, 0, 1, 35, 8, 7,
|
||||
0, 0, 0, 0, 0, 1, 34, 8, 7, 0, 0, 0, 0, 0, 1, 33, 8, 7, 0,
|
||||
0, 0, 0, 0, 1, 32, 8, 7, 0, 0, 0, 0, 0, 1, 31, 10, 0, 0, 0,
|
||||
2, 1,231, 0, 1,244, 1,231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 1, 1, 1, 1, 0, 1, 49, 9, 51,
|
||||
38, 26, 11, 7, 1, 1, 0, 1, 0, 1, 49, 9, 38, 20, 13, 0, 0, 0, 23,
|
||||
0, 67, 0, 1,238, 1,220, 1,202, 1,186, 1,168, 1,148, 1,130, 1,107,
|
||||
1, 86, 1, 65, 1, 44, 1, 27, 1, 14, 0,250, 0,224, 0,205, 0,184, 0,
|
||||
165, 0,145, 0,123, 0,106, 0, 86, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 17, 23, 6, 0, 23, 1, 1, 21,107,110,111,119,110, 52,
|
||||
19,112,111,111,114, 18, 22, 6, 0, 23, 1, 1, 23, 97, 98,111,118,101, 24,
|
||||
26,115,101,114,118,101, 15, 21, 6, 0, 19, 1, 1, 21,119, 97,114, 52, 19,
|
||||
112,111,111,114, 20, 20, 6, 0, 27, 1, 8, 25,110,111,116,104,105,110,103,
|
||||
7,112,108, 97, 99,101,115, 18, 19, 6, 0, 23, 1, 1, 23, 98,101,103, 97,
|
||||
116, 90, 27,116,114,117,116,104, 17, 18, 6, 0, 23, 1, 1, 21,100,119,101,
|
||||
108,116, 21, 39,100,111,116,104, 19, 17, 6, 0, 27, 1, 1, 21,109,111,114,
|
||||
110,105,110,103, 52, 19,112,111,111,114, 17, 16, 6, 0, 21, 1, 1, 23,115,
|
||||
104,101,119, 90, 27,116,114,117,116,104, 24, 15, 6, 0, 27, 1, 1, 31,116,
|
||||
104,101,114,101,105,110, 37, 31,115, 97, 99,114,105,102,105, 99,101, 18, 14,
|
||||
6, 0, 23, 1, 8, 25,115,109,111,116,101, 7,112,108, 97, 99,101,115, 11,
|
||||
13, 6, 0, 19, 1, 1, 0, 97,114,107, 72, 31, 15, 12, 6, 0, 21, 1, 8,
|
||||
21,119,105,110,101, 58,119, 97,121,115, 19, 11, 6, 0, 21, 1, 1, 27,115,
|
||||
111,109,101, 98, 17,109,111,114,110,105,110,103, 19, 10, 6, 0, 27, 1, 1,
|
||||
21, 98,101,116,119,101,101,110, 92, 18,115,111,109,101, 19, 9, 6, 0, 21,
|
||||
1, 1, 27,115, 97,118,101, 74, 36, 98,101,116,119,101,101,110, 21, 8, 6,
|
||||
0, 25, 1, 1, 27,116,104,111,117,103,104, 98, 17,109,111,114,110,105,110,
|
||||
103, 16, 7, 6, 0, 21, 1, 1, 21,115,101,110,100, 49, 34,115,101,110,100,
|
||||
18, 6, 6, 0, 25, 1, 1, 21,119,105,115,100,111,109, 38, 36,115,101,110,
|
||||
100, 16, 5, 6, 0, 23, 1, 9, 21, 97,110,103,101,114, 46,119, 97,121,115,
|
||||
14, 4, 6, 0, 19, 1, 1, 19, 99, 97,110, 19, 43,119, 97,114, 16, 3, 6,
|
||||
0, 23, 1, 1, 19,111,102,102,101,114, 48, 22,115,105,120, 16, 2, 6, 0,
|
||||
23, 1, 8, 21,119,111,114,107,115, 58,119, 97,121,115, 16, 1, 6, 0, 23,
|
||||
1, 1, 19,116,114,117,116,104, 37, 11, 99, 97,110, 13, 0, 0, 0, 22, 0,
|
||||
64, 0, 1,230, 1,213, 1,191, 1,169, 1,148, 1,130, 1,108, 1, 89, 1,
|
||||
70, 1, 51, 1, 34, 1, 16, 0,253, 0,233, 0,214, 0,194, 0,174, 0,151,
|
||||
0,132, 0,109, 0, 90, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 24, 45, 6, 0, 35, 1, 1, 23,105,110,104, 97, 98,105,116, 97,110,116,
|
||||
115, 23, 41, 98,101,103, 97,116, 17, 44, 6, 0, 23, 1, 1, 21, 97,110,103,
|
||||
101,108, 48, 27,100,105,101,100, 21, 43, 6, 0, 25, 1, 1, 27,116,101,109,
|
||||
112,108,101, 74, 36, 98,101,116,119,101,101,110, 17, 42, 6, 0, 23, 1, 1,
|
||||
21, 99,104,105,108,100, 81, 25,119, 97,108,107, 21, 41, 6, 0, 21, 1, 1,
|
||||
31,119, 97,121,115, 37, 31,115, 97, 99,114,105,102,105, 99,101, 18, 40, 6,
|
||||
0, 21, 1, 1, 25,112,111,111,114, 93, 7,116,101,109,112,108,101, 18, 39,
|
||||
6, 0, 21, 1, 1, 25,100,111,116,104, 3, 11,116,101,109,112,108,101, 17,
|
||||
38, 6, 0, 23, 1, 1, 21,102,114,117,105,116, 62, 27,115,101,110,100, 18,
|
||||
37, 6, 0, 23, 1, 1, 23,115,101,114,118,101, 90, 27,116,114,117,116,104,
|
||||
17, 36, 6, 0, 21, 1, 1, 23,110,101, 97,114, 90, 27,116,114,117,116,104,
|
||||
16, 35, 6, 0, 21, 1, 1, 21,108,111,110,103, 14, 39,115, 97,118,101, 15,
|
||||
34, 6, 0, 21, 1, 1, 19,119, 97,108,107, 15, 20, 97,114,107, 17, 33, 6,
|
||||
0, 25, 1, 9, 21, 99,117, 98,105,116,115, 46,119, 97,121,115, 17, 32, 6,
|
||||
0, 21, 1, 1, 23,103,111,110,101, 23, 41, 98,101,103, 97,116, 17, 31, 6,
|
||||
0, 23, 1, 1, 21,119,104,105,108,101, 49, 34,115,101,110,100, 20, 30, 6,
|
||||
0, 21, 1, 1, 29,112, 97,114,116, 88, 22,100,101,112, 97,114,116,101,100,
|
||||
16, 29, 6, 0, 21, 1, 1, 21, 98,101, 97,114, 92, 18,115,111,109,101, 19,
|
||||
28, 6, 0, 25, 1, 1, 23,112,108, 97, 99,101,115, 23, 41, 98,101,103, 97,
|
||||
116, 20, 27, 6, 0, 27, 1, 1, 23,116,104,121,115,101,108,102, 54, 12, 97,
|
||||
98,111,118,101, 20, 26, 6, 0, 29, 1, 1, 21,100,101,112, 97,114,116,101,
|
||||
100, 92, 18,115,111,109,101, 15, 25, 6, 0, 21, 1, 1, 19,116,101,108,108,
|
||||
19, 43,119, 97,114, 24, 24, 6, 0, 31, 1, 1, 27,115, 97, 99,114,105,102,
|
||||
105, 99,101, 92, 13,109,111,114,110,105,110,103, 13, 0, 0, 0, 5, 1,162,
|
||||
0, 1,239, 1,221, 1,203, 1,182, 1,162, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 50, 6, 0, 23, 1, 1,
|
||||
23,119,114, 97,116,104, 21, 45, 98,101,103, 97,116, 19, 49, 6, 0, 21, 1,
|
||||
1, 27,116,114,101,101, 98, 17,109,111,114,110,105,110,103, 16, 48, 6, 0,
|
||||
19, 1, 1, 23,115,105,120, 71, 3, 97,110,103,101,108, 16, 47, 6, 0, 21,
|
||||
1, 1, 21,100,105,101,100, 7, 19,103,111,110,101, 15, 46, 6, 0, 19, 1,
|
||||
1, 21,111,105,108, 81, 25,119, 97,108,107, 10, 0, 0, 0, 40, 0,106, 0,
|
||||
1,246, 1,236, 1,226, 1,218, 1,209, 1,199, 1,187, 1,179, 1,169, 1,
|
||||
158, 1,145, 1,136, 1,127, 1,117, 1,107, 1, 98, 1, 82, 1, 72, 1, 63,
|
||||
1, 51, 1, 42, 1, 30, 1, 20, 1, 12, 1, 3, 0,248, 0,239, 0,225, 0,
|
||||
216, 0,207, 0,197, 0,188, 0,180, 0,170, 0,161, 0,152, 0,141, 0,129,
|
||||
0,118, 0,106, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,116,114,
|
||||
101,101, 49, 11, 3, 27, 1,116,104,121,115,101,108,102, 27, 10, 3, 25, 1,
|
||||
116,104,111,117,103,104, 8, 11, 3, 27, 1,116,104,101,114,101,105,110, 15,
|
||||
10, 3, 25, 1,116,101,109,112,108,101, 43, 8, 3, 21, 1,116,101,108,108,
|
||||
25, 8, 3, 21, 1,115,111,109,101, 11, 9, 3, 23, 1,115,109,111,116,101,
|
||||
14, 7, 3, 19, 1,115,105,120, 48, 8, 3, 21, 1,115,104,101,119, 16, 9,
|
||||
3, 23, 1,115,101,114,118,101, 37, 8, 3, 21, 1,115,101,110,100, 7, 8,
|
||||
3, 21, 1,115, 97,118,101, 9, 13, 3, 31, 1,115, 97, 99,114,105,102,105,
|
||||
99,101, 24, 8, 3, 21, 1,112,111,111,114, 40, 10, 3, 25, 1,112,108, 97,
|
||||
99,101,115, 28, 8, 3, 21, 1,112, 97,114,116, 30, 7, 3, 19, 1,111,105,
|
||||
108, 46, 9, 3, 23, 1,111,102,102,101,114, 3, 11, 3, 27, 1,110,111,116,
|
||||
104,105,110,103, 20, 8, 3, 21, 1,110,101, 97,114, 36, 11, 3, 27, 1,109,
|
||||
111,114,110,105,110,103, 17, 8, 3, 21, 1,108,111,110,103, 35, 9, 3, 23,
|
||||
1,107,110,111,119,110, 23, 15, 3, 35, 1,105,110,104, 97, 98,105,116, 97,
|
||||
110,116,115, 45, 8, 3, 21, 1,103,111,110,101, 32, 9, 3, 23, 1,102,114,
|
||||
117,105,116, 38, 9, 3, 23, 1,100,119,101,108,116, 18, 8, 3, 21, 1,100,
|
||||
111,116,104, 39, 8, 3, 21, 1,100,105,101,100, 47, 12, 3, 29, 1,100,101,
|
||||
112, 97,114,116,101,100, 26, 10, 3, 25, 1, 99,117, 98,105,116,115, 33, 9,
|
||||
3, 23, 1, 99,104,105,108,100, 42, 7, 3, 19, 1, 99, 97,110, 4, 11, 3,
|
||||
27, 1, 98,101,116,119,101,101,110, 10, 9, 3, 23, 1, 98,101,103, 97,116,
|
||||
19, 8, 3, 21, 1, 98,101, 97,114, 29, 7, 3, 19, 1, 97,114,107, 13, 9,
|
||||
3, 23, 1, 97,110,103,101,114, 5, 9, 3, 23, 1, 97,110,103,101,108, 44,
|
||||
9, 3, 23, 1, 97, 98,111,118,101, 22, 10, 0, 0, 0, 9, 1,171, 0, 1,
|
||||
247, 1,238, 1,230, 1,221, 1,211, 1,202, 1,191, 1,181, 1,171, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
9, 3, 23, 1,119,114, 97,116,104, 50, 9, 3, 23, 1,119,111,114,107,115,
|
||||
2, 10, 3, 25, 1,119,105,115,100,111,109, 6, 8, 3, 21, 1,119,105,110,
|
||||
101, 12, 9, 3, 23, 1,119,104,105,108,101, 31, 8, 3, 21, 1,119, 97,121,
|
||||
115, 41, 7, 3, 19, 1,119, 97,114, 21, 8, 3, 21, 1,119, 97,108,107, 34,
|
||||
8, 3, 23, 9,116,114,117,116,104, 13, 0, 0, 0, 5, 0, 84, 0, 1, 78,
|
||||
0,249, 0,177, 1,163, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 19,
|
||||
7, 21, 19, 19, 8,129, 33,118,105,101,119,118, 50, 49,118, 50, 49, 67, 82,
|
||||
69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 50, 49, 40, 97, 44, 98, 44, 99,
|
||||
44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98,
|
||||
44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 50, 32, 79, 82, 68, 69,
|
||||
82, 32, 66, 89, 32, 98, 32, 76, 73, 77, 73, 84, 32, 49, 48, 70, 17, 6, 21,
|
||||
19, 19, 8,121,118,105,101,119,118, 53, 48,118, 53, 48, 67, 82, 69, 65, 84,
|
||||
69, 32, 86, 73, 69, 87, 32,118, 53, 48, 40, 97, 44, 98, 41, 32, 65, 83, 32,
|
||||
83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 32, 70, 82, 79, 77, 32,116, 53, 32,
|
||||
87, 72, 69, 82, 69, 32, 97, 60, 62, 50, 53, 83, 16, 7, 21, 19, 19, 8,129,
|
||||
17,118,105,101,119,118, 52, 48,118, 52, 48, 67, 82, 69, 65, 84, 69, 32, 86,
|
||||
73, 69, 87, 32,118, 52, 48, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32,
|
||||
65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101,
|
||||
32, 70, 82, 79, 77, 32,116, 52, 32, 87, 72, 69, 82, 69, 32, 97, 60, 62, 50,
|
||||
53, 83, 15, 7, 21, 19, 19, 8,129, 17,118,105,101,119,118, 51, 48,118, 51,
|
||||
48, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 51, 48, 40, 97, 44,
|
||||
98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32,
|
||||
97, 44, 98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 51, 32, 87,
|
||||
72, 69, 82, 69, 32, 97, 60, 62, 50, 53, 91, 18, 7, 21, 19, 19, 8,129, 33,
|
||||
118,105,101,119,118, 49, 49,118, 49, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73,
|
||||
69, 87, 32,118, 49, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65,
|
||||
83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 32,
|
||||
70, 82, 79, 77, 32,116, 49, 32, 79, 82, 68, 69, 82, 32, 66, 89, 32, 98, 32,
|
||||
76, 73, 77, 73, 84, 32, 49, 48, 13, 1,163, 0, 4, 0, 40, 0, 1, 70, 0,
|
||||
233, 0,152, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 23, 7, 21, 19, 19, 8,129, 71,
|
||||
118,105,101,119,118, 49, 50,118, 49, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73,
|
||||
69, 87, 32,118, 49, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65,
|
||||
83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115,117,109, 40, 97, 41, 44, 32,
|
||||
97,118,103, 40, 98, 41, 44, 32, 99,111,117,110,116, 40, 42, 41, 44, 32,109,
|
||||
105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79, 77, 32,116, 49, 32, 71, 82,
|
||||
79, 85, 80, 32, 66, 89, 32, 53, 79, 22, 7, 21, 19, 19, 8,129, 9,118,105,
|
||||
101,119,118, 53, 49,118, 53, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87,
|
||||
32,118, 53, 49, 40, 97, 44, 98, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84,
|
||||
32, 97, 44, 98, 32, 70, 82, 79, 77, 32,116, 53, 32, 79, 82, 68, 69, 82, 32,
|
||||
66, 89, 32, 98, 32, 76, 73, 77, 73, 84, 32, 49, 48, 91, 21, 7, 21, 19, 19,
|
||||
8,129, 33,118,105,101,119,118, 52, 49,118, 52, 49, 67, 82, 69, 65, 84, 69,
|
||||
32, 86, 73, 69, 87, 32,118, 52, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101,
|
||||
41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100,
|
||||
44,101, 32, 70, 82, 79, 77, 32,116, 52, 32, 79, 82, 68, 69, 82, 32, 66, 89,
|
||||
32, 98, 32, 76, 73, 77, 73, 84, 32, 49, 48, 91, 20, 7, 21, 19, 19, 8,129,
|
||||
33,118,105,101,119,118, 51, 49,118, 51, 49, 67, 82, 69, 65, 84, 69, 32, 86,
|
||||
73, 69, 87, 32,118, 51, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32,
|
||||
65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101,
|
||||
32, 70, 82, 79, 77, 32,116, 51, 32, 79, 82, 68, 69, 82, 32, 66, 89, 32, 98,
|
||||
32, 76, 73, 77, 73, 84, 32, 49, 48, 0, 0, 0, 93, 19, 19, 8,129, 33,118,
|
||||
105,101,119,118, 50, 49,118, 50, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69,
|
||||
87, 32,118, 50, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83,
|
||||
32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 32, 70,
|
||||
82, 79, 77, 32,116, 50, 32, 79, 82, 68, 69, 82, 32, 66, 89, 32, 98, 32, 76,
|
||||
73, 77, 73, 84, 32, 49, 48, 13, 0, 0, 0, 3, 0, 66, 0, 1,107, 0,214,
|
||||
0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 17, 26,
|
||||
7, 21, 19, 19, 8,130, 13,118,105,101,119,118, 52, 50,118, 52, 50, 67, 82,
|
||||
69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 52, 50, 40, 97, 44, 98, 44, 99,
|
||||
44,100, 44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115,
|
||||
117,109, 40, 97, 41, 44, 32, 97,118,103, 40, 98, 41, 44, 32, 99,111,117,110,
|
||||
116, 40, 42, 41, 44, 32,109,105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79,
|
||||
77, 32,116, 52, 32, 71, 82, 79, 85, 80, 32, 66, 89, 32, 53, 10, 32, 32, 32,
|
||||
32, 72, 65, 86, 73, 78, 71, 32,109,105,110, 40,100, 41, 60, 51, 48, 32, 79,
|
||||
82, 68, 69, 82, 32, 66, 89, 32, 51, 44, 32, 49,129, 18, 25, 7, 21, 19, 19,
|
||||
8,130, 15,118,105,101,119,118, 51, 50,118, 51, 50, 67, 82, 69, 65, 84, 69,
|
||||
32, 86, 73, 69, 87, 32,118, 51, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101,
|
||||
41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115,117,109, 40, 97,
|
||||
41, 44, 32, 97,118,103, 40, 98, 41, 44, 32, 99,111,117,110,116, 40, 42, 41,
|
||||
44, 32,109,105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79, 77, 32,116, 51,
|
||||
32, 71, 82, 79, 85, 80, 32, 66, 89, 32, 53, 10, 32, 32, 32, 32, 72, 65, 86,
|
||||
73, 78, 71, 32, 99,111,117,110,116, 40, 42, 41, 62, 49, 32, 79, 82, 68, 69,
|
||||
82, 32, 66, 89, 32, 51, 44, 32, 49,129, 18, 24, 7, 21, 19, 19, 8,130, 15,
|
||||
118,105,101,119,118, 50, 50,118, 50, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73,
|
||||
69, 87, 32,118, 50, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65,
|
||||
83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115,117,109, 40, 97, 41, 44, 32,
|
||||
97,118,103, 40, 98, 41, 44, 32, 99,111,117,110,116, 40, 42, 41, 44, 32,109,
|
||||
105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79, 77, 32,116, 50, 32, 71, 82,
|
||||
79, 85, 80, 32, 66, 89, 32, 53, 10, 32, 32, 32, 32, 72, 65, 86, 73, 78, 71,
|
||||
32, 99,111,117,110,116, 40, 42, 41, 62, 49, 32, 79, 82, 68, 69, 82, 32, 66,
|
||||
89, 32, 51, 44, 32, 49, 13, 1,108, 0, 3, 0, 83, 0, 0,225, 0, 83, 1,
|
||||
136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 11, 28, 7, 21, 19,
|
||||
19, 8,130, 1,118,105,101,119,118, 49, 51,118, 49, 51, 67, 82, 69, 65, 84,
|
||||
69, 32, 86, 73, 69, 87, 32,118, 49, 51, 40, 97, 44, 98, 44, 99, 44,100, 44,
|
||||
101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44,
|
||||
99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 10, 32, 32, 85, 78, 73,
|
||||
79, 78, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101,
|
||||
32, 70, 82, 79, 77, 32,116, 50, 10, 32, 32, 85, 78, 73, 79, 78, 32, 83, 69,
|
||||
76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77,
|
||||
32,116, 51,129, 8, 27, 7, 21, 19, 19, 8,129,123,118,105,101,119,118, 53,
|
||||
50,118, 53, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 53, 50,
|
||||
40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69,
|
||||
76, 69, 67, 84, 32, 99,111,117,110,116, 40, 42, 41, 44, 32,109,105,110, 40,
|
||||
98, 41, 44, 32,115,117, 98,115,116,114, 40, 98, 44, 49, 44, 49, 41, 44, 32,
|
||||
109,105,110, 40, 97, 41, 44, 32,109, 97,120, 40, 97, 41, 32, 70, 82, 79, 77,
|
||||
32,116, 53, 10, 32, 32, 32, 71, 82, 79, 85, 80, 32, 66, 89, 32, 51, 32, 79,
|
||||
82, 68, 69, 82, 32, 66, 89, 32, 49, 0, 0, 0, 28, 21, 19, 19, 8,130, 13,
|
||||
118,105,101,119,118, 52, 50,118, 52, 50, 67, 82, 69, 65, 84, 69, 32, 86,118,
|
||||
29, 7, 21, 19, 19, 8,129, 87,118,105,101,119,118, 50, 51,118, 50, 51, 67,
|
||||
82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 50, 51, 40, 97, 44, 98, 44,
|
||||
99, 44,100, 44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,
|
||||
97, 44, 98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 10, 32,
|
||||
32, 69, 88, 67, 69, 80, 84, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44,
|
||||
99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 32, 87, 72, 69, 82, 69,
|
||||
32, 98, 60, 50, 53, 13, 0, 0, 0, 3, 0, 40, 0, 1,134, 1, 12, 0, 40,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0,129, 97, 32, 7, 21, 19, 19, 8,131, 45,118,105,
|
||||
101,119,118, 54, 50,118, 54, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87,
|
||||
32,118, 54, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 10,
|
||||
32, 32, 83, 69, 76, 69, 67, 84, 32,116, 49, 46, 97, 44,116, 50, 46, 98, 44,
|
||||
116, 51, 46, 99, 44,116, 52, 46,100, 44,116, 53, 46, 98, 10, 32, 32, 32, 32,
|
||||
70, 82, 79, 77, 32,116, 49, 32, 74, 79, 73, 78, 32,116, 50, 32, 79, 78, 32,
|
||||
40,116, 49, 46, 97, 61,116, 50, 46, 98, 41, 10, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 74, 79, 73, 78, 32,116, 51, 32, 79, 78, 32, 40,116, 49,
|
||||
46, 97, 61,116, 51, 46, 97, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 74, 79, 73, 78, 32,116, 52, 32, 79, 78, 32, 40,116, 52, 46, 98, 61,
|
||||
116, 51, 46, 98, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 76,
|
||||
69, 70, 84, 32, 74, 79, 73, 78, 32,116, 53, 32, 79, 78, 32, 40,116, 53, 46,
|
||||
97, 61,116, 49, 46, 99, 41,120, 31, 7, 21, 19, 19, 8,129, 91,118,105,101,
|
||||
119,118, 54, 49,118, 54, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,
|
||||
118, 54, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 10, 32,
|
||||
32, 83, 69, 76, 69, 67, 84, 32,116, 50, 46, 97, 44,116, 51, 46, 98, 44,116,
|
||||
50, 46, 99, 44,116, 51, 46,100, 44,116, 50, 46,101, 10, 32, 32, 32, 32, 70,
|
||||
82, 79, 77, 32,116, 50, 32, 76, 69, 70, 84, 32, 74, 79, 73, 78, 32,116, 51,
|
||||
32, 79, 78, 32, 40,116, 50, 46, 97, 61,116, 51, 46, 97, 41,120, 30, 7, 21,
|
||||
19, 19, 8,129, 91,118,105,101,119,118, 54, 48,118, 54, 48, 67, 82, 69, 65,
|
||||
84, 69, 32, 86, 73, 69, 87, 32,118, 54, 48, 40, 97, 44, 98, 44, 99, 44,100,
|
||||
44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,116, 49, 46,
|
||||
97, 44,116, 50, 46, 98, 44,116, 49, 46, 99, 44,116, 50, 46,100, 44,116, 49,
|
||||
46,101, 10, 32, 32, 32, 32, 70, 82, 79, 77, 32,116, 49, 32, 76, 69, 70, 84,
|
||||
32, 74, 79, 73, 78, 32,116, 50, 32, 79, 78, 32, 40,116, 49, 46, 97, 61,116,
|
||||
50, 46, 98, 41, 13, 0, 0, 0, 1, 1, 73, 0, 1, 73, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 52, 33, 7, 21, 19, 19, 8,130,
|
||||
83,118,105,101,119,118, 55, 48,118, 55, 48, 67, 82, 69, 65, 84, 69, 32, 86,
|
||||
73, 69, 87, 32,118, 55, 48, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32,
|
||||
65, 83, 10, 32, 32, 87, 73, 84, 72, 32, 82, 69, 67, 85, 82, 83, 73, 86, 69,
|
||||
32, 99, 48, 40,120, 41, 32, 65, 83, 32, 40, 86, 65, 76, 85, 69, 83, 40, 49,
|
||||
41, 32, 85, 78, 73, 79, 78, 32, 65, 76, 76, 32, 83, 69, 76, 69, 67, 84, 32,
|
||||
120, 43, 49, 32, 70, 82, 79, 77, 32, 99, 48, 32, 87, 72, 69, 82, 69, 32,120,
|
||||
60, 57, 41, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,120, 44, 32, 98, 44, 32,
|
||||
99, 44, 32,100, 44, 32,101, 32, 70, 82, 79, 77, 32, 99, 48, 32, 74, 79, 73,
|
||||
78, 32,116, 49, 32, 79, 78, 32, 40,116, 49, 46, 97, 61, 53, 48, 45, 99, 48,
|
||||
46,120, 41,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
-- Run this script through the sqlite3 command-line shell in order to generate
|
||||
-- a database file containing lots of data for testing purposes.
|
||||
--
|
||||
-- This script assumes that the "bin2c" program is available on ones $PATH.
|
||||
-- The "bin2c" program reads a binary file and outputs C-code that creates
|
||||
-- an array of bytes holding the content of that file.
|
||||
--
|
||||
-- This script is designed to create many tables and views all having
|
||||
-- 5 columns, "a" through "e", and with a variety of integers, short strings,
|
||||
-- and NULL values.
|
||||
--
|
||||
.open -new testdb01.db
|
||||
PRAGMA page_size=512;
|
||||
BEGIN;
|
||||
CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT, d INT, e INT);
|
||||
WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<50)
|
||||
INSERT INTO t1(a,b,c,d,e) SELECT x,abs(random()%51),
|
||||
abs(random()%100), abs(random()%51), abs(random()%100) FROM c;
|
||||
CREATE TABLE t2(a INT, b INT, c INT,d INT,e INT,PRIMARY KEY(b,a))WITHOUT ROWID;
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
CREATE TABLE t3(a,b,c,d,e);
|
||||
INSERT INTO t3 SELECT a,b,c,d,e FROM t1 ORDER BY random() LIMIT 5;
|
||||
INSERT INTO t3 SELECT null,b,c,d,e FROM t1 ORDER BY random() LIMIT 5;
|
||||
INSERT INTO t3 SELECT a,null,c,d,e FROM t1 ORDER BY random() LIMIT 5;
|
||||
INSERT INTO t3 SELECT a,b,null,d,e FROM t1 ORDER BY random() LIMIT 5;
|
||||
INSERT INTO t3 SELECT a,b,c,null,e FROM t1 ORDER BY random() LIMIT 5;
|
||||
INSERT INTO t3 SELECT a,b,c,d,null FROM t1 ORDER BY random() LIMIT 5;
|
||||
INSERT INTO t3 SELECT null,null,null,null,null FROM t1 LIMIT 5;
|
||||
CREATE INDEX t3x1 ON t3(a,b,c,d,e);
|
||||
CREATE TABLE t4(a INT UNIQUE NOT NULL, b INT UNIQUE NOT NULL,c,d,e);
|
||||
INSERT OR IGNORE INTO t4 SELECT a,b,c,d,e FROM t3;
|
||||
CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT UNIQUE,c,d,e);
|
||||
INSERT INTO t5(b) VALUES
|
||||
('truth'),
|
||||
('works'),
|
||||
('offer'),
|
||||
('can'),
|
||||
('anger'),
|
||||
('wisdom'),
|
||||
('send'),
|
||||
('though'),
|
||||
('save'),
|
||||
('between'),
|
||||
('some'),
|
||||
('wine'),
|
||||
('ark'),
|
||||
('smote'),
|
||||
('therein'),
|
||||
('shew'),
|
||||
('morning'),
|
||||
('dwelt'),
|
||||
('begat'),
|
||||
('nothing'),
|
||||
('war'),
|
||||
('above'),
|
||||
('known'),
|
||||
('sacrifice'),
|
||||
('tell'),
|
||||
('departed'),
|
||||
('thyself'),
|
||||
('places'),
|
||||
('bear'),
|
||||
('part'),
|
||||
('while'),
|
||||
('gone'),
|
||||
('cubits'),
|
||||
('walk'),
|
||||
('long'),
|
||||
('near'),
|
||||
('serve'),
|
||||
('fruit'),
|
||||
('doth'),
|
||||
('poor'),
|
||||
('ways'),
|
||||
('child'),
|
||||
('temple'),
|
||||
('angel'),
|
||||
('inhabitants'),
|
||||
('oil'),
|
||||
('died'),
|
||||
('six'),
|
||||
('tree'),
|
||||
('wrath');
|
||||
UPDATE t1 SET e=(SELECT b FROM t5 WHERE t5.a=(t1.e%51));
|
||||
UPDATE t5 SET (c,d,e) =
|
||||
(SELECT c,d,e FROM t1 WHERE t1.a=abs(t5.a+random()/100)%50+1);
|
||||
UPDATE t2 SET e=(SELECT b FROM t5 WHERE t5.a=(t2.e%51));
|
||||
UPDATE t3 SET e=(SELECT b FROM t5 WHERE t5.a=t3.e);
|
||||
CREATE INDEX t1e ON t1(e);
|
||||
CREATE INDEX t2ed ON t2(e,d);
|
||||
CREATE VIEW v00(a,b,c,d,e) AS SELECT 1,1,1,1,'one';
|
||||
CREATE VIEW v10(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t1 WHERE a<>25;
|
||||
CREATE VIEW v20(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t2 WHERE a<>25;
|
||||
CREATE VIEW v30(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t3 WHERE a<>25;
|
||||
CREATE VIEW v40(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t4 WHERE a<>25;
|
||||
CREATE VIEW v50(a,b) AS SELECT a,b FROM t5 WHERE a<>25;
|
||||
CREATE VIEW v11(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t1 ORDER BY b LIMIT 10;
|
||||
CREATE VIEW v21(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t2 ORDER BY b LIMIT 10;
|
||||
CREATE VIEW v31(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t3 ORDER BY b LIMIT 10;
|
||||
CREATE VIEW v41(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t4 ORDER BY b LIMIT 10;
|
||||
CREATE VIEW v51(a,b) AS SELECT a,b FROM t5 ORDER BY b LIMIT 10;
|
||||
CREATE VIEW v12(a,b,c,d,e) AS
|
||||
SELECT sum(a), avg(b), count(*), min(d), e FROM t1 GROUP BY 5;
|
||||
CREATE VIEW v22(a,b,c,d,e) AS
|
||||
SELECT sum(a), avg(b), count(*), min(d), e FROM t2 GROUP BY 5
|
||||
HAVING count(*)>1 ORDER BY 3, 1;
|
||||
CREATE VIEW v32(a,b,c,d,e) AS
|
||||
SELECT sum(a), avg(b), count(*), min(d), e FROM t3 GROUP BY 5
|
||||
HAVING count(*)>1 ORDER BY 3, 1;
|
||||
CREATE VIEW v42(a,b,c,d,e) AS
|
||||
SELECT sum(a), avg(b), count(*), min(d), e FROM t4 GROUP BY 5
|
||||
HAVING min(d)<30 ORDER BY 3, 1;
|
||||
CREATE VIEW v52(a,b,c,d,e) AS
|
||||
SELECT count(*), min(b), substr(b,1,1), min(a), max(a) FROM t5
|
||||
GROUP BY 3 ORDER BY 1;
|
||||
|
||||
CREATE VIEW v13(a,b,c,d,e) AS
|
||||
SELECT a,b,c,d,e FROM t1
|
||||
UNION SELECT a,b,c,d,e FROM t2
|
||||
UNION SELECT a,b,c,d,e FROM t3;
|
||||
CREATE VIEW v23(a,b,c,d,e) AS
|
||||
SELECT a,b,c,d,e FROM t1
|
||||
EXCEPT SELECT a,b,c,d,e FROM t1 WHERE b<25;
|
||||
|
||||
CREATE VIEW v60(a,b,c,d,e) AS
|
||||
SELECT t1.a,t2.b,t1.c,t2.d,t1.e
|
||||
FROM t1 LEFT JOIN t2 ON (t1.a=t2.b);
|
||||
CREATE VIEW v61(a,b,c,d,e) AS
|
||||
SELECT t2.a,t3.b,t2.c,t3.d,t2.e
|
||||
FROM t2 LEFT JOIN t3 ON (t2.a=t3.a);
|
||||
CREATE VIEW v62(a,b,c,d,e) AS
|
||||
SELECT t1.a,t2.b,t3.c,t4.d,t5.b
|
||||
FROM t1 JOIN t2 ON (t1.a=t2.b)
|
||||
JOIN t3 ON (t1.a=t3.a)
|
||||
JOIN t4 ON (t4.b=t3.b)
|
||||
LEFT JOIN t5 ON (t5.a=t1.c);
|
||||
CREATE VIEW v70(a,b,c,d,e) AS
|
||||
WITH RECURSIVE c0(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c0 WHERE x<9)
|
||||
SELECT x, b, c, d, e FROM c0 JOIN t1 ON (t1.a=50-c0.x);
|
||||
COMMIT;
|
||||
VACUUM;
|
||||
.shell bin2c testdb01.db
|
||||
+309
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
** 2018-03-21
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
*************************************************************************
|
||||
**
|
||||
** This program attempts to verify the correctness of the SQLite query
|
||||
** optimizer by fuzzing.
|
||||
**
|
||||
** The input is an SQL script, presumably generated by a fuzzer. The
|
||||
** argument is the name of the input. If no files are named, standard
|
||||
** input is read.
|
||||
**
|
||||
** The SQL script is run twice, once with optimization enabled, and again
|
||||
** with optimization disabled. If the output is not equivalent, an error
|
||||
** is printed and the program returns non-zero.
|
||||
*/
|
||||
|
||||
/* Include the SQLite amalgamation, after making appropriate #defines.
|
||||
*/
|
||||
#define SQLITE_THREADSAFE 0
|
||||
#define SQLITE_OMIT_LOAD_EXTENSION 1
|
||||
#define SQLITE_ENABLE_DESERIALIZE 1
|
||||
#include "sqlite3.c"
|
||||
|
||||
/* Content of the read-only test database */
|
||||
#include "optfuzz-db01.c"
|
||||
|
||||
/*
|
||||
** Prepare a single SQL statement. Panic if anything goes wrong
|
||||
*/
|
||||
static sqlite3_stmt *prepare_sql(sqlite3 *db, const char *zFormat, ...){
|
||||
char *zSql;
|
||||
int rc;
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, zFormat);
|
||||
zSql = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
|
||||
if( rc ){
|
||||
printf("Error: %s\nSQL: %s\n",
|
||||
sqlite3_errmsg(db), zSql);
|
||||
exit(1);
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
return pStmt;
|
||||
}
|
||||
|
||||
/*
|
||||
** Run SQL. Panic if anything goes wrong
|
||||
*/
|
||||
static void run_sql(sqlite3 *db, const char *zFormat, ...){
|
||||
char *zSql;
|
||||
int rc;
|
||||
char *zErr = 0;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, zFormat);
|
||||
zSql = sqlite3_vmprintf(zFormat, ap);
|
||||
va_end(ap);
|
||||
rc = sqlite3_exec(db, zSql, 0, 0, &zErr);
|
||||
if( rc || zErr ){
|
||||
printf("Error: %s\nsqlite3_errmsg: %s\nSQL: %s\n",
|
||||
zErr, sqlite3_errmsg(db), zSql);
|
||||
exit(1);
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
|
||||
/*
|
||||
** Run one or more SQL statements contained in zSql against database dbRun.
|
||||
** Store the input in database dbOut.
|
||||
*/
|
||||
static int optfuzz_exec(
|
||||
sqlite3 *dbRun, /* The database on which the SQL executes */
|
||||
const char *zSql, /* The SQL to be executed */
|
||||
sqlite3 *dbOut, /* Store results in this database */
|
||||
const char *zOutTab, /* Store results in this table of dbOut */
|
||||
int *pnStmt, /* Write the number of statements here */
|
||||
int *pnRow, /* Write the number of rows here */
|
||||
int bTrace /* Print query results if true */
|
||||
){
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
const char *zLeftover; /* Tail of unprocessed SQL */
|
||||
sqlite3_stmt *pStmt = 0; /* The current SQL statement */
|
||||
sqlite3_stmt *pIns = 0; /* Statement to insert into dbOut */
|
||||
const char *zCol; /* Single column value */
|
||||
int nCol; /* Number of output columns */
|
||||
char zLine[4000]; /* Complete row value */
|
||||
|
||||
run_sql(dbOut, "BEGIN");
|
||||
run_sql(dbOut, "CREATE TABLE IF NOT EXISTS staging(x TEXT)");
|
||||
run_sql(dbOut, "CREATE TABLE IF NOT EXISTS \"%w\"(x TEXT)", zOutTab);
|
||||
pIns = prepare_sql(dbOut, "INSERT INTO staging(x) VALUES(?1)");
|
||||
*pnRow = *pnStmt = 0;
|
||||
while( rc==SQLITE_OK && zSql && zSql[0] ){
|
||||
zLeftover = 0;
|
||||
rc = sqlite3_prepare_v2(dbRun, zSql, -1, &pStmt, &zLeftover);
|
||||
zSql = zLeftover;
|
||||
assert( rc==SQLITE_OK || pStmt==0 );
|
||||
if( rc!=SQLITE_OK ){
|
||||
printf("Error with [%s]\n%s\n", zSql, sqlite3_errmsg(dbRun));
|
||||
break;
|
||||
}
|
||||
if( !pStmt ) continue;
|
||||
(*pnStmt)++;
|
||||
nCol = sqlite3_column_count(pStmt);
|
||||
run_sql(dbOut, "DELETE FROM staging;");
|
||||
while( sqlite3_step(pStmt)==SQLITE_ROW ){
|
||||
int i, j;
|
||||
for(i=j=0; i<nCol && j<sizeof(zLine)-50; i++){
|
||||
int eType = sqlite3_column_type(pStmt, i);
|
||||
if( eType==SQLITE_NULL ){
|
||||
zCol = "NULL";
|
||||
}else{
|
||||
zCol = (const char*)sqlite3_column_text(pStmt, i);
|
||||
}
|
||||
if( i ) zLine[j++] = ',';
|
||||
if( eType==SQLITE_TEXT ){
|
||||
sqlite3_snprintf(sizeof(zLine)-j, zLine+j, "'%q'", zCol);
|
||||
}else{
|
||||
sqlite3_snprintf(sizeof(zLine)-j, zLine+j, "%s", zCol);
|
||||
}
|
||||
j += (int)strlen(zLine+j);
|
||||
}
|
||||
/* Detect if any row is too large and throw an error, because we will
|
||||
** want to go back and look more closely at that case */
|
||||
if( j>=sizeof(zLine)-100 ){
|
||||
printf("Excessively long output line: %d bytes\n" ,j);
|
||||
exit(1);
|
||||
}
|
||||
if( bTrace ){
|
||||
printf("%s\n", zLine);
|
||||
}
|
||||
(*pnRow)++;
|
||||
sqlite3_bind_text(pIns, 1, zLine, j, SQLITE_TRANSIENT);
|
||||
rc = sqlite3_step(pIns);
|
||||
assert( rc==SQLITE_DONE );
|
||||
rc = sqlite3_reset(pIns);
|
||||
}
|
||||
run_sql(dbOut,
|
||||
"INSERT INTO \"%w\"(x) VALUES('### %q ###')",
|
||||
zOutTab, sqlite3_sql(pStmt)
|
||||
);
|
||||
run_sql(dbOut,
|
||||
"INSERT INTO \"%w\"(x) SELECT group_concat(x,char(10))"
|
||||
" FROM (SELECT x FROM staging ORDER BY x)",
|
||||
zOutTab
|
||||
);
|
||||
run_sql(dbOut, "COMMIT");
|
||||
sqlite3_finalize(pStmt);
|
||||
pStmt = 0;
|
||||
}
|
||||
sqlite3_finalize(pStmt);
|
||||
sqlite3_finalize(pIns);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Read the content of file zName into memory obtained from sqlite3_malloc64()
|
||||
** and return a pointer to the buffer. The caller is responsible for freeing
|
||||
** the memory.
|
||||
**
|
||||
** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes
|
||||
** read.
|
||||
**
|
||||
** For convenience, a nul-terminator byte is always appended to the data read
|
||||
** from the file before the buffer is returned. This byte is not included in
|
||||
** the final value of (*pnByte), if applicable.
|
||||
**
|
||||
** NULL is returned if any error is encountered. The final value of *pnByte
|
||||
** is undefined in this case.
|
||||
*/
|
||||
static char *readFile(const char *zName, int *pnByte){
|
||||
FILE *in = fopen(zName, "rb");
|
||||
long nIn;
|
||||
size_t nRead;
|
||||
char *pBuf;
|
||||
if( in==0 ) return 0;
|
||||
fseek(in, 0, SEEK_END);
|
||||
nIn = ftell(in);
|
||||
rewind(in);
|
||||
pBuf = sqlite3_malloc64( nIn+1 );
|
||||
if( pBuf==0 ) return 0;
|
||||
nRead = fread(pBuf, nIn, 1, in);
|
||||
fclose(in);
|
||||
if( nRead!=1 ){
|
||||
sqlite3_free(pBuf);
|
||||
return 0;
|
||||
}
|
||||
pBuf[nIn] = 0;
|
||||
if( pnByte ) *pnByte = nIn;
|
||||
return pBuf;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv){
|
||||
int nIn = 0; /* Number of input files */
|
||||
char **azIn = 0; /* Names of input files */
|
||||
sqlite3 *dbOut = 0; /* Database to hold results */
|
||||
sqlite3 *dbRun = 0; /* Database used for tests */
|
||||
int bTrace = 0; /* Show query results */
|
||||
int bShowValid = 0; /* Just list inputs that are valid SQL */
|
||||
int nRow, nStmt; /* Number of rows and statements */
|
||||
int i, rc;
|
||||
|
||||
for(i=1; i<argc; i++){
|
||||
const char *z = argv[i];
|
||||
if( z[0]=='-' && z[1]=='-' ) z++;
|
||||
if( strcmp(z,"-help")==0 ){
|
||||
printf("Usage: %s [OPTIONS] FILENAME ...\n", argv[0]);
|
||||
printf("Options:\n");
|
||||
printf(" --help Show his message\n");
|
||||
printf(" --output-trace Show each line of SQL output\n");
|
||||
printf(" --valid-sql List FILEs that are valid SQL\n");
|
||||
return 0;
|
||||
}
|
||||
else if( strcmp(z,"-output-trace")==0 ){
|
||||
bTrace = 1;
|
||||
}
|
||||
else if( strcmp(z,"-valid-sql")==0 ){
|
||||
bShowValid = 1;
|
||||
}
|
||||
else if( z[0]=='-' ){
|
||||
printf("unknown option \"%s\". Use --help for details\n", argv[i]);
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
nIn++;
|
||||
azIn = realloc(azIn, sizeof(azIn[0])*nIn);
|
||||
if( azIn==0 ){
|
||||
printf("out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
azIn[nIn-1] = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_open(":memory:", &dbOut);
|
||||
sqlite3_open(":memory:", &dbRun);
|
||||
sqlite3_deserialize(dbRun, "main", data001, sizeof(data001),
|
||||
sizeof(data001), SQLITE_DESERIALIZE_READONLY);
|
||||
for(i=0; i<nIn; i++){
|
||||
char *zSql = readFile(azIn[i], 0);
|
||||
sqlite3_stmt *pCk;
|
||||
sqlite3_exec(dbRun, "ROLLBACK", 0, 0, 0);
|
||||
if( bShowValid ){
|
||||
rc = sqlite3_exec(dbRun, zSql, 0, 0, 0);
|
||||
if( rc==SQLITE_OK ) printf("%s\n", azIn[i]);
|
||||
sqlite3_free(zSql);
|
||||
continue;
|
||||
}
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, dbRun, 0);
|
||||
if( bTrace ) printf("%s: Optimized\n", azIn[i]);
|
||||
rc = optfuzz_exec(dbRun, zSql, dbOut, "opt", &nStmt, &nRow, bTrace);
|
||||
if( rc ){
|
||||
printf("%s: optimized run failed: %s\n",
|
||||
azIn[i], sqlite3_errmsg(dbRun));
|
||||
}else{
|
||||
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, dbRun, 0xffff);
|
||||
if( bTrace ) printf("%s: Non-optimized\n", azIn[i]);
|
||||
rc = optfuzz_exec(dbRun, zSql, dbOut, "noopt", &nStmt, &nRow, bTrace);
|
||||
if( rc ){
|
||||
printf("%s: non-optimized run failed: %s\n",
|
||||
azIn[i], sqlite3_errmsg(dbRun));
|
||||
exit(1);
|
||||
}
|
||||
pCk = prepare_sql(dbOut,
|
||||
"SELECT (SELECT group_concat(x,char(10)) FROM opt)=="
|
||||
" (SELECT group_concat(x,char(10)) FROM noopt)");
|
||||
rc = sqlite3_step(pCk);
|
||||
if( rc!=SQLITE_ROW ){
|
||||
printf("%s: comparison failed\n", sqlite3_errmsg(dbOut));
|
||||
exit(1);
|
||||
}
|
||||
if( !sqlite3_column_int(pCk, 0) ){
|
||||
printf("%s: opt/no-opt outputs differ\n", azIn[i]);
|
||||
pCk = prepare_sql(dbOut,
|
||||
"SELECT group_concat(x,char(10)) FROM opt "
|
||||
"UNION ALL "
|
||||
"SELECT group_concat(x,char(10)) FROM noopt");
|
||||
sqlite3_step(pCk);
|
||||
printf("opt:\n%s\n", sqlite3_column_text(pCk,0));
|
||||
sqlite3_step(pCk);
|
||||
printf("noopt:\n%s\n", sqlite3_column_text(pCk,0));
|
||||
exit(1);
|
||||
}else{
|
||||
printf("%s: %d stmts %d rows ok\n", azIn[i], nStmt, nRow);
|
||||
}
|
||||
sqlite3_finalize(pCk);
|
||||
}
|
||||
sqlite3_free(zSql);
|
||||
}
|
||||
sqlite3_close(dbRun);
|
||||
sqlite3_close(dbOut);
|
||||
free(azIn);
|
||||
if( sqlite3_memory_used() ){
|
||||
printf("Memory leak of %lld bytes\n", sqlite3_memory_used());
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1097,4 +1097,46 @@ do_test shell1-6.1 {
|
||||
} {}
|
||||
}
|
||||
|
||||
db close
|
||||
forcedelete test.db test.db-journal test.db-wal
|
||||
sqlite3 db test.db
|
||||
|
||||
# The shell tool ".schema" command uses virtual table "pragma_database_list"
|
||||
#
|
||||
ifcapable vtab {
|
||||
|
||||
do_test shell1-7.1.1 {
|
||||
db eval {
|
||||
CREATE TABLE Z (x TEXT PRIMARY KEY);
|
||||
CREATE TABLE _ (x TEXT PRIMARY KEY);
|
||||
CREATE TABLE YY (x TEXT PRIMARY KEY);
|
||||
CREATE TABLE __ (x TEXT PRIMARY KEY);
|
||||
CREATE TABLE WWW (x TEXT PRIMARY KEY);
|
||||
CREATE TABLE ___ (x TEXT PRIMARY KEY);
|
||||
}
|
||||
} {}
|
||||
do_test shell1-7.1.2 {
|
||||
catchcmd "test.db" ".schema _"
|
||||
} {0 {CREATE TABLE Z (x TEXT PRIMARY KEY);
|
||||
CREATE TABLE _ (x TEXT PRIMARY KEY);}}
|
||||
do_test shell1-7.1.3 {
|
||||
catchcmd "test.db" ".schema \\\\_"
|
||||
} {0 {CREATE TABLE _ (x TEXT PRIMARY KEY);}}
|
||||
do_test shell1-7.1.4 {
|
||||
catchcmd "test.db" ".schema __"
|
||||
} {0 {CREATE TABLE YY (x TEXT PRIMARY KEY);
|
||||
CREATE TABLE __ (x TEXT PRIMARY KEY);}}
|
||||
do_test shell1-7.1.5 {
|
||||
catchcmd "test.db" ".schema \\\\_\\\\_"
|
||||
} {0 {CREATE TABLE __ (x TEXT PRIMARY KEY);}}
|
||||
do_test shell1-7.1.6 {
|
||||
catchcmd "test.db" ".schema ___"
|
||||
} {0 {CREATE TABLE WWW (x TEXT PRIMARY KEY);
|
||||
CREATE TABLE ___ (x TEXT PRIMARY KEY);}}
|
||||
do_test shell1-7.1.7 {
|
||||
catchcmd "test.db" ".schema \\\\_\\\\_\\\\_"
|
||||
} {0 {CREATE TABLE ___ (x TEXT PRIMARY KEY);}}
|
||||
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
+2
-2
@@ -129,7 +129,7 @@ do_test trace3-4.3 {
|
||||
}
|
||||
set stmt [lindex [lindex $::stmtlist(record) 0] 0]
|
||||
set ns [lindex [lindex $::stmtlist(record) 0] 1]
|
||||
list $stmt [expr {$ns >= 0 && $ns <= 1000000}]; # less than 0.001 second
|
||||
list $stmt [expr {$ns >= 0 && $ns <= 9999999}]; # less than 0.010 seconds
|
||||
} {/^-?\d+ 1$/}
|
||||
do_test trace3-4.4 {
|
||||
set ::stmtlist(record) {}
|
||||
@@ -139,7 +139,7 @@ do_test trace3-4.4 {
|
||||
}
|
||||
set stmt [lindex [lindex $::stmtlist(record) 0] 0]
|
||||
set ns [lindex [lindex $::stmtlist(record) 0] 1]
|
||||
list $stmt [expr {$ns >= 0 && $ns <= 1000000}]; # less than 0.001 second
|
||||
list $stmt [expr {$ns >= 0 && $ns <= 9999999}]; # less than 0.010 seconds
|
||||
} {/^-?\d+ 1$/}
|
||||
|
||||
do_test trace3-5.1 {
|
||||
|
||||
+128
-46
@@ -10,6 +10,8 @@
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
package require Tcl 8.6
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix zipfile
|
||||
@@ -21,6 +23,10 @@ if {[catch {load_static_extension db zipfile} error]} {
|
||||
puts "Skipping zipfile tests, hit load error: $error"
|
||||
finish_test; return
|
||||
}
|
||||
if {[catch {load_static_extension db fileio} error]} {
|
||||
puts "Skipping zipfile tests, hit load error: $error"
|
||||
finish_test; return
|
||||
}
|
||||
|
||||
proc readfile {f} {
|
||||
set fd [open $f]
|
||||
@@ -30,16 +36,39 @@ proc readfile {f} {
|
||||
set data
|
||||
}
|
||||
|
||||
if {$::tcl_platform(platform)=="unix" && [catch {exec unzip}]==0} {
|
||||
set ::UNZIP 1
|
||||
load_static_extension db fileio
|
||||
unset -nocomplain ::UNZIP
|
||||
|
||||
if {[catch {exec unzip} msg]==0 && \
|
||||
[regexp -line {^UnZip \d+\.\d+ .*? Info-ZIP\.} $msg]} {
|
||||
set ::UNZIP unzip
|
||||
proc fix_stat_mode {name mode} {
|
||||
if {$::tcl_platform(platform)=="windows"} {
|
||||
#
|
||||
# NOTE: Set or unset the write bits of the file permissions
|
||||
# based on the read-only attribute because the Win32
|
||||
# version of UnZip does this.
|
||||
#
|
||||
set writebits 0x12; # 0o22
|
||||
set result $mode
|
||||
if {[file attributes $name -readonly]} {
|
||||
set result [expr {$result | $writebits}]
|
||||
} else {
|
||||
set result [expr {$result & ~$writebits}]
|
||||
}
|
||||
return $result
|
||||
} else {
|
||||
return $mode
|
||||
}
|
||||
}
|
||||
proc do_unzip {file} {
|
||||
forcedelete test_unzip
|
||||
file mkdir test_unzip
|
||||
exec unzip -d test_unzip $file
|
||||
|
||||
set res [db eval {
|
||||
SELECT replace(name,'test_unzip/',''),mode,mtime,data
|
||||
exec $::UNZIP -d test_unzip $file
|
||||
|
||||
db func modefix fix_stat_mode
|
||||
|
||||
set res [db eval {
|
||||
SELECT replace(name,'test_unzip/',''),modefix(name,mode),mtime,data
|
||||
FROM fsdir('test_unzip')
|
||||
WHERE name!='test_unzip'
|
||||
ORDER BY name
|
||||
@@ -108,7 +137,6 @@ proc do_zipfile_blob_test {tn file} {
|
||||
# the same results as in (1).
|
||||
#
|
||||
proc do_unzip_test {tn file} {
|
||||
if {[info vars ::UNZIP]==""} { return }
|
||||
db func sss strip_slash
|
||||
|
||||
db eval {
|
||||
@@ -247,65 +275,73 @@ do_execsql_test 1.6.2 {
|
||||
i.txt 33188 4 zxcvb 0
|
||||
}
|
||||
|
||||
do_execsql_test 1.6.3 {
|
||||
UPDATE zz SET mode='-rw-r--r-x' WHERE name='h.txt';
|
||||
SELECT name, mode, mtime, data, method FROM zipfile('test.zip');
|
||||
} {
|
||||
f.txt 33188 1000000000 abcde 0
|
||||
h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
i.txt 33188 4 zxcvb 0
|
||||
if {$::tcl_platform(platform)=="unix"} {
|
||||
set modes -rw-r--r-x
|
||||
set perms 33189
|
||||
} else {
|
||||
set modes -rw-r--r--; # no execute bits on Win32
|
||||
set perms 33188
|
||||
}
|
||||
|
||||
do_execsql_test 1.6.3 {
|
||||
UPDATE zz SET mode=$modes WHERE name='h.txt';
|
||||
SELECT name, mode, mtime, data, method FROM zipfile('test.zip');
|
||||
} [string map [list %perms% $perms] {
|
||||
f.txt 33188 1000000000 abcde 0
|
||||
h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
i.txt 33188 4 zxcvb 0
|
||||
}]
|
||||
do_zip_tests 1.6.3a test.zip
|
||||
|
||||
do_execsql_test 1.6.4 {
|
||||
UPDATE zz SET name = 'blue.txt' WHERE name='f.txt';
|
||||
SELECT name, mode, mtime, data, method FROM zipfile('test.zip');
|
||||
} {
|
||||
} [string map [list %perms% $perms] {
|
||||
blue.txt 33188 1000000000 abcde 0
|
||||
h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
i.txt 33188 4 zxcvb 0
|
||||
}
|
||||
}]
|
||||
do_zip_tests 1.6.4a test.zip
|
||||
|
||||
do_execsql_test 1.6.5 {
|
||||
UPDATE zz SET data = 'edcba' WHERE name='blue.txt';
|
||||
SELECT name, mode, mtime, data, method FROM zipfile('test.zip');
|
||||
} {
|
||||
} [string map [list %perms% $perms] {
|
||||
blue.txt 33188 1000000000 edcba 0
|
||||
h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
i.txt 33188 4 zxcvb 0
|
||||
}
|
||||
}]
|
||||
|
||||
do_execsql_test 1.6.6 {
|
||||
UPDATE zz SET mode=NULL, data = NULL WHERE name='blue.txt';
|
||||
SELECT name, mode, mtime, data, method FROM zipfile('test.zip');
|
||||
} {
|
||||
} [string map [list %perms% $perms] {
|
||||
blue.txt/ 16877 1000000000 {} 0
|
||||
h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
i.txt 33188 4 zxcvb 0
|
||||
}
|
||||
}]
|
||||
|
||||
do_catchsql_test 1.6.7 {
|
||||
UPDATE zz SET data=NULL WHERE name='i.txt'
|
||||
} {1 {zipfile: mode does not match data}}
|
||||
do_execsql_test 1.6.8 {
|
||||
SELECT name, mode, mtime, data, method FROM zipfile('test.zip');
|
||||
} {
|
||||
} [string map [list %perms% $perms] {
|
||||
blue.txt/ 16877 1000000000 {} 0
|
||||
h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
i.txt 33188 4 zxcvb 0
|
||||
}
|
||||
|
||||
do_execsql_test 1.6.8 {
|
||||
UPDATE zz SET data = '' WHERE name='i.txt';
|
||||
SELECT name,mode,mtime,data,method from zipfile('test.zip');
|
||||
} {
|
||||
blue.txt/ 16877 1000000000 {} 0
|
||||
h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
i.txt 33188 4 {} 0
|
||||
}
|
||||
}]
|
||||
|
||||
do_execsql_test 1.6.9 {
|
||||
UPDATE zz SET data = '' WHERE name='i.txt';
|
||||
SELECT name,mode,mtime,data,method from zipfile('test.zip');
|
||||
} [string map [list %perms% $perms] {
|
||||
blue.txt/ 16877 1000000000 {} 0
|
||||
h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8
|
||||
i.txt 33188 4 {} 0
|
||||
}]
|
||||
|
||||
do_execsql_test 1.6.10 {
|
||||
SELECT a.name, a.data
|
||||
FROM zz AS a, zz AS b
|
||||
WHERE a.name=+b.name AND +a.mode=b.mode
|
||||
@@ -315,7 +351,7 @@ do_execsql_test 1.6.9 {
|
||||
i.txt {}
|
||||
}
|
||||
|
||||
do_execsql_test 1.6.10 {
|
||||
do_execsql_test 1.6.11 {
|
||||
SELECT name, data FROM zz WHERE name LIKE '%txt'
|
||||
} {
|
||||
h.txt aaaaaaaaaabbbbbbbbbb
|
||||
@@ -360,13 +396,18 @@ do_execsql_test 2.4 {
|
||||
}
|
||||
do_zip_tests 2.4a test.zip
|
||||
|
||||
# If on unix, check that the [unzip] utility can unpack our archive.
|
||||
# Check that the [unzip] utility can unpack our archive.
|
||||
#
|
||||
if {$::tcl_platform(platform)=="unix"} {
|
||||
if {[info exists ::UNZIP]} {
|
||||
do_test 2.5.1 {
|
||||
forcedelete dirname
|
||||
forcedelete dirname2
|
||||
set rc [catch { exec unzip test.zip > /dev/null } msg]
|
||||
if {$::tcl_platform(platform)=="unix"} {
|
||||
set null /dev/null
|
||||
} else {
|
||||
set null NUL
|
||||
}
|
||||
set rc [catch { exec $::UNZIP test.zip > $null } msg]
|
||||
list $rc $msg
|
||||
} {0 {}}
|
||||
do_test 2.5.2 { file isdir dirname3 } 1
|
||||
@@ -384,6 +425,7 @@ if {$::tcl_platform(platform)=="unix"} {
|
||||
reset_db
|
||||
forcedelete test.zip
|
||||
load_static_extension db zipfile
|
||||
load_static_extension db fileio
|
||||
|
||||
do_execsql_test 3.0 {
|
||||
CREATE VIRTUAL TABLE temp.x1 USING zipfile('test.zip');
|
||||
@@ -453,7 +495,7 @@ do_catchsql_test 4.7 {
|
||||
SELECT zipfile(name,data) FROM c
|
||||
} {1 {first argument to zipfile() must be non-NULL}}
|
||||
|
||||
do_catchsql_test 4.7 {
|
||||
do_catchsql_test 4.8 {
|
||||
WITH c(name,data,method) AS (
|
||||
SELECT 'a.txt', 'abc', 0
|
||||
UNION SELECT 'b.txt', 'def', 8
|
||||
@@ -462,7 +504,7 @@ do_catchsql_test 4.7 {
|
||||
SELECT zipfile(name,NULL,NULL,data,method) FROM c
|
||||
} {1 {illegal method value: 16}}
|
||||
|
||||
do_catchsql_test 4.8 {
|
||||
do_catchsql_test 4.9 {
|
||||
WITH c(name,data) AS (
|
||||
SELECT 'a.txt', 'abc'
|
||||
UNION SELECT 'b.txt', 'def'
|
||||
@@ -485,9 +527,8 @@ do_execsql_test 5.0 {
|
||||
a.txt 946684800 abc
|
||||
}
|
||||
|
||||
if {[info vars ::UNZIP]!=""} {
|
||||
if {[info exists ::UNZIP]} {
|
||||
ifcapable datetime {
|
||||
load_static_extension db fileio
|
||||
forcedelete test1.zip test2.zip
|
||||
do_test 6.0 {
|
||||
execsql {
|
||||
@@ -502,7 +543,7 @@ ifcapable datetime {
|
||||
}
|
||||
forcedelete test_unzip
|
||||
file mkdir test_unzip
|
||||
exec unzip -d test_unzip test1.zip
|
||||
exec $::UNZIP -d test_unzip test1.zip
|
||||
|
||||
db eval {
|
||||
SELECT name, strftime('%s', mtime, 'unixepoch', 'localtime')
|
||||
@@ -534,7 +575,7 @@ ifcapable datetime {
|
||||
do_test 6.2 {
|
||||
forcedelete test_unzip
|
||||
file mkdir test_unzip
|
||||
exec unzip -d test_unzip test2.zip
|
||||
exec $::UNZIP -d test_unzip test2.zip
|
||||
|
||||
db eval {
|
||||
SELECT name, mtime
|
||||
@@ -652,6 +693,8 @@ catch {db close}
|
||||
forcedelete test.zip test.db
|
||||
sqlite3 db :memory:
|
||||
load_static_extension db zipfile
|
||||
load_static_extension db fileio
|
||||
|
||||
do_execsql_test 10.0 {
|
||||
CREATE VIRTUAL TABLE z USING zipfile('test.zip');
|
||||
} {}
|
||||
@@ -674,5 +717,44 @@ do_execsql_test 10.6 {
|
||||
SELECT name, data FROM z;
|
||||
} {a0 four}
|
||||
|
||||
do_execsql_test 11.1 {
|
||||
DELETE FROM z;
|
||||
} {}
|
||||
do_execsql_test 11.2 {
|
||||
SELECT name, data FROM z;
|
||||
} {}
|
||||
do_execsql_test 11.3 {
|
||||
INSERT INTO z (name,data) VALUES ('b0','one');
|
||||
SELECT name, data FROM z;
|
||||
} {b0 one}
|
||||
do_execsql_test 11.4 {
|
||||
UPDATE z SET name = 'b1' WHERE name = 'b0';
|
||||
SELECT name, data FROM z;
|
||||
} {b1 one}
|
||||
do_execsql_test 11.5 {
|
||||
INSERT INTO z (name,data) VALUES ('b0','one');
|
||||
SELECT name, data FROM z ORDER BY name;
|
||||
} {b0 one b1 one}
|
||||
do_catchsql_test 11.6 {
|
||||
UPDATE z SET name = 'b1' WHERE name = 'b0';
|
||||
} {1 {duplicate name: "b1"}}
|
||||
do_execsql_test 11.7 {
|
||||
UPDATE z SET data = 'two' WHERE name = 'b0';
|
||||
SELECT name, data FROM z ORDER BY name;
|
||||
} {b0 two b1 one}
|
||||
do_catchsql_test 11.8 {
|
||||
UPDATE z SET name = 'b1';
|
||||
} {1 {duplicate name: "b1"}}
|
||||
do_catchsql_test 11.9 {
|
||||
UPDATE z SET name = 'b2';
|
||||
} {1 {duplicate name: "b2"}}
|
||||
do_execsql_test 11.10 {
|
||||
UPDATE z SET name = name;
|
||||
SELECT name, data FROM z ORDER BY name;
|
||||
} {b0 two b2 one}
|
||||
do_execsql_test 11.11 {
|
||||
UPDATE z SET name = name || 'suffix';
|
||||
SELECT name, data FROM z ORDER BY name;
|
||||
} {b0suffix two b2suffix one}
|
||||
|
||||
finish_test
|
||||
|
||||
+39
-1
@@ -10,6 +10,8 @@
|
||||
#***********************************************************************
|
||||
#
|
||||
|
||||
package require Tcl 8.6
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
set testprefix zipfile2
|
||||
@@ -50,12 +52,17 @@ do_execsql_test 1.0 {
|
||||
CREATE VIRTUAL TABLE fff USING zipfile('test''zip');
|
||||
}
|
||||
|
||||
if {$::tcl_platform(platform)=="windows"} {
|
||||
set res {1 {cannot open file: testdir}}
|
||||
} else {
|
||||
set res {1 {error in fread()}}
|
||||
}
|
||||
do_test 2.0 {
|
||||
forcedelete testdir
|
||||
file mkdir testdir
|
||||
execsql { CREATE VIRTUAL TABLE hhh USING zipfile('testdir') }
|
||||
catchsql { SELECT * FROM hhh }
|
||||
} {1 {error in fread()}}
|
||||
} $res
|
||||
|
||||
|
||||
set archive {
|
||||
@@ -203,6 +210,37 @@ do_test 5.0 {
|
||||
execsql { SELECT name, data IS NULL FROM zipfile($blob2) }
|
||||
} {notadi/ 1}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Test that duplicate entries may not be created using UPDATE
|
||||
# statements.
|
||||
#
|
||||
forcedelete test.zip
|
||||
do_execsql_test 6.0 {
|
||||
CREATE VIRTUAL TABLE temp.zip USING zipfile('test.zip');
|
||||
INSERT INTO temp.zip (name,data) VALUES ('test1','test');
|
||||
INSERT INTO temp.zip (name,data) VALUES ('test2','test');
|
||||
}
|
||||
do_catchsql_test 6.1 {
|
||||
UPDATE temp.zip SET name='test1' WHERE name='test2'
|
||||
} {1 {duplicate name: "test1"}}
|
||||
|
||||
forcedelete test.zip
|
||||
do_catchsql_test 6.2 {
|
||||
DROP TABLE zip;
|
||||
CREATE VIRTUAL TABLE temp.zip USING zipfile('test.zip');
|
||||
INSERT INTO temp.zip (name,data) VALUES ('test','test');
|
||||
UPDATE temp.zip set name=name||'new' where name='test';
|
||||
INSERT INTO temp.zip (name,data) VALUES ('test','test');
|
||||
UPDATE temp.zip set name=name||'new' where name='test';
|
||||
} {1 {duplicate name: "testnew"}}
|
||||
|
||||
forcedelete test.zip
|
||||
do_execsql_test 6.3 {
|
||||
INSERT INTO temp.zip (name,data) VALUES ('test1','test');
|
||||
INSERT INTO temp.zip (name,data) VALUES ('test2','test');
|
||||
UPDATE OR REPLACE zip SET name='test2' WHERE name='test1';
|
||||
SELECT name FROM zip;
|
||||
} {test2}
|
||||
|
||||
finish_test
|
||||
|
||||
|
||||
+5
-1
@@ -72,6 +72,9 @@ set declpattern3 \
|
||||
set declpattern4 \
|
||||
{^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3changegroup_[_a-zA-Z0-9]+)(\(.*)$}
|
||||
|
||||
set declpattern5 \
|
||||
{^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3rebaser_[_a-zA-Z0-9]+)(\(.*)$}
|
||||
|
||||
# Force the output to use unix line endings, even on Windows.
|
||||
fconfigure stdout -translation lf
|
||||
|
||||
@@ -121,7 +124,8 @@ foreach file $filelist {
|
||||
if {[regexp $declpattern1 $line all rettype funcname rest] || \
|
||||
[regexp $declpattern2 $line all rettype funcname rest] || \
|
||||
[regexp $declpattern3 $line all rettype funcname rest] || \
|
||||
[regexp $declpattern4 $line all rettype funcname rest]} {
|
||||
[regexp $declpattern4 $line all rettype funcname rest] || \
|
||||
[regexp $declpattern5 $line all rettype funcname rest]} {
|
||||
set line SQLITE_API
|
||||
append line " " [string trim $rettype]
|
||||
if {[string index $rettype end] ne "*"} {
|
||||
|
||||
Reference in New Issue
Block a user