Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | Merge all version 3.23.1 changes and enhancements from trunk. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | apple-osx |
Files: | files | file ages | folders |
SHA3-256: |
e20fcb5159f2a74ea60ac6a0287165d1 |
User & Date: | drh 2018-04-10 18:05:07 |
2018-05-04
| ||
19:33 | Merge recent enhancements from trunk. check-in: e17bca2c user: drh tags: apple-osx | |
2018-04-10
| ||
18:05 | Merge all version 3.23.1 changes and enhancements from trunk. check-in: e20fcb51 user: drh tags: apple-osx | |
17:39 | Version 3.23.1 check-in: 4bb22940 user: drh tags: trunk, release, version-3.23.1 | |
2018-03-14
| ||
17:17 | Merge the latest enhancements from trunk. check-in: a658f80c user: drh tags: apple-osx | |
Changes to Makefile.msc.
2088 2088 2089 2089 keywordhash.h: $(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe 2090 2090 .\mkkeywordhash.exe > keywordhash.h 2091 2091 2092 2092 # Source files that go into making shell.c 2093 2093 SHELL_SRC = \ 2094 2094 $(TOP)\src\shell.c.in \ 2095 - $(TOP)\ext\misc\appendvfs.c \ 2095 + $(TOP)\ext\misc\appendvfs.c \ 2096 2096 $(TOP)\ext\misc\shathree.c \ 2097 2097 $(TOP)\ext\misc\fileio.c \ 2098 2098 $(TOP)\ext\misc\completion.c \ 2099 2099 $(TOP)\ext\expert\sqlite3expert.c \ 2100 2100 $(TOP)\ext\expert\sqlite3expert.h \ 2101 2101 $(TOP)\src\test_windirent.c 2102 2102
Changes to README.md.
1 1 <h1 align="center">SQLite Source Repository</h1> 2 2 3 3 This repository contains the complete source code for the SQLite database 4 4 engine. Some test scripts are also included. However, many other test scripts 5 5 and most of the documentation are managed separately. 6 6 7 -If you are reading this on a Git mirror someplace, you are doing it wrong. 8 -The [official repository](https://www.sqlite.org/src/) is better. Go there 9 -now. 7 +SQLite [does not use Git](https://sqlite.org/whynotgit.html). 8 +If you are reading this on GitHub, then you are looking at an 9 +unofficial mirror. See <https://sqlite.org/src> for the official 10 +repository. 10 11 11 12 ## Obtaining The Code 12 13 13 14 SQLite sources are managed using the 14 15 [Fossil](https://www.fossil-scm.org/), a distributed version control system 15 16 that was specifically designed to support SQLite development. 16 17 If you do not want to use Fossil, you can download tarballs or ZIP
Changes to VERSION.
1 -3.23.0 1 +3.23.1
Changes to configure.
1 1 #! /bin/sh 2 2 # Guess values for system-dependent variables and create Makefiles. 3 -# Generated by GNU Autoconf 2.69 for sqlite 3.23.0. 3 +# Generated by GNU Autoconf 2.69 for sqlite 3.23.1. 4 4 # 5 5 # 6 6 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. 7 7 # 8 8 # 9 9 # This configure script is free software; the Free Software Foundation 10 10 # gives unlimited permission to copy, distribute and modify it. ................................................................................ 722 722 subdirs= 723 723 MFLAGS= 724 724 MAKEFLAGS= 725 725 726 726 # Identity of this package. 727 727 PACKAGE_NAME='sqlite' 728 728 PACKAGE_TARNAME='sqlite' 729 -PACKAGE_VERSION='3.23.0' 730 -PACKAGE_STRING='sqlite 3.23.0' 729 +PACKAGE_VERSION='3.23.1' 730 +PACKAGE_STRING='sqlite 3.23.1' 731 731 PACKAGE_BUGREPORT='' 732 732 PACKAGE_URL='' 733 733 734 734 # Factoring default headers for most tests. 735 735 ac_includes_default="\ 736 736 #include <stdio.h> 737 737 #ifdef HAVE_SYS_TYPES_H ................................................................................ 1461 1461 # 1462 1462 # Report the --help message. 1463 1463 # 1464 1464 if test "$ac_init_help" = "long"; then 1465 1465 # Omit some internal or obsolete options to make the list less imposing. 1466 1466 # This message is too long to be a string in the A/UX 3.1 sh. 1467 1467 cat <<_ACEOF 1468 -\`configure' configures sqlite 3.23.0 to adapt to many kinds of systems. 1468 +\`configure' configures sqlite 3.23.1 to adapt to many kinds of systems. 1469 1469 1470 1470 Usage: $0 [OPTION]... [VAR=VALUE]... 1471 1471 1472 1472 To assign environment variables (e.g., CC, CFLAGS...), specify them as 1473 1473 VAR=VALUE. See below for descriptions of some of the useful variables. 1474 1474 1475 1475 Defaults for the options are specified in brackets. ................................................................................ 1526 1526 --build=BUILD configure for building on BUILD [guessed] 1527 1527 --host=HOST cross-compile to build programs to run on HOST [BUILD] 1528 1528 _ACEOF 1529 1529 fi 1530 1530 1531 1531 if test -n "$ac_init_help"; then 1532 1532 case $ac_init_help in 1533 - short | recursive ) echo "Configuration of sqlite 3.23.0:";; 1533 + short | recursive ) echo "Configuration of sqlite 3.23.1:";; 1534 1534 esac 1535 1535 cat <<\_ACEOF 1536 1536 1537 1537 Optional Features: 1538 1538 --disable-option-checking ignore unrecognized --enable/--with options 1539 1539 --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) 1540 1540 --enable-FEATURE[=ARG] include FEATURE [ARG=yes] ................................................................................ 1651 1651 cd "$ac_pwd" || { ac_status=$?; break; } 1652 1652 done 1653 1653 fi 1654 1654 1655 1655 test -n "$ac_init_help" && exit $ac_status 1656 1656 if $ac_init_version; then 1657 1657 cat <<\_ACEOF 1658 -sqlite configure 3.23.0 1658 +sqlite configure 3.23.1 1659 1659 generated by GNU Autoconf 2.69 1660 1660 1661 1661 Copyright (C) 2012 Free Software Foundation, Inc. 1662 1662 This configure script is free software; the Free Software Foundation 1663 1663 gives unlimited permission to copy, distribute and modify it. 1664 1664 _ACEOF 1665 1665 exit ................................................................................ 2070 2070 eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno 2071 2071 2072 2072 } # ac_fn_c_check_header_mongrel 2073 2073 cat >config.log <<_ACEOF 2074 2074 This file contains any messages produced by compilers while 2075 2075 running configure, to aid debugging if configure makes a mistake. 2076 2076 2077 -It was created by sqlite $as_me 3.23.0, which was 2077 +It was created by sqlite $as_me 3.23.1, which was 2078 2078 generated by GNU Autoconf 2.69. Invocation command line was 2079 2079 2080 2080 $ $0 $@ 2081 2081 2082 2082 _ACEOF 2083 2083 exec 5>>config.log 2084 2084 { ................................................................................ 12238 12238 test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 12239 12239 12240 12240 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 12241 12241 # Save the log message, to keep $0 and so on meaningful, and to 12242 12242 # report actual input values of CONFIG_FILES etc. instead of their 12243 12243 # values after options handling. 12244 12244 ac_log=" 12245 -This file was extended by sqlite $as_me 3.23.0, which was 12245 +This file was extended by sqlite $as_me 3.23.1, which was 12246 12246 generated by GNU Autoconf 2.69. Invocation command line was 12247 12247 12248 12248 CONFIG_FILES = $CONFIG_FILES 12249 12249 CONFIG_HEADERS = $CONFIG_HEADERS 12250 12250 CONFIG_LINKS = $CONFIG_LINKS 12251 12251 CONFIG_COMMANDS = $CONFIG_COMMANDS 12252 12252 $ $0 $@ ................................................................................ 12304 12304 12305 12305 Report bugs to the package provider." 12306 12306 12307 12307 _ACEOF 12308 12308 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 12309 12309 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" 12310 12310 ac_cs_version="\\ 12311 -sqlite config.status 3.23.0 12311 +sqlite config.status 3.23.1 12312 12312 configured by $0, generated by GNU Autoconf 2.69, 12313 12313 with options \\"\$ac_cs_config\\" 12314 12314 12315 12315 Copyright (C) 2012 Free Software Foundation, Inc. 12316 12316 This config.status script is free software; the Free Software Foundation 12317 12317 gives unlimited permission to copy, distribute and modify it." 12318 12318
Changes to ext/fts5/fts5_main.c.
530 530 FTS5_BI_ROWID_GE, 0, 0, -1}, 531 531 }; 532 532 533 533 int aColMap[3]; 534 534 aColMap[0] = -1; 535 535 aColMap[1] = nCol; 536 536 aColMap[2] = nCol+1; 537 + 538 + assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH ); 539 + assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH ); 540 + assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH ); 541 + assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH ); 542 + assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH ); 537 543 538 544 /* Set idxFlags flags for all WHERE clause terms that will be used. */ 539 545 for(i=0; i<pInfo->nConstraint; i++){ 540 546 struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; 541 547 int iCol = p->iColumn; 542 548 543 549 if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol) ................................................................................ 549 555 aConstraint[0].iConsIndex = i; 550 556 }else{ 551 557 /* As there exists an unusable MATCH constraint this is an 552 558 ** unusable plan. Set a prohibitively high cost. */ 553 559 pInfo->estimatedCost = 1e50; 554 560 return SQLITE_OK; 555 561 } 556 - }else{ 562 + }else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){ 557 563 int j; 558 564 for(j=1; j<ArraySize(aConstraint); j++){ 559 565 struct Constraint *pC = &aConstraint[j]; 560 - if( iCol==aColMap[pC->iCol] && p->op & pC->op && p->usable ){ 566 + if( iCol==aColMap[pC->iCol] && (p->op & pC->op) && p->usable ){ 561 567 pC->iConsIndex = i; 562 568 idxFlags |= pC->fts5op; 563 569 } 564 570 } 565 571 } 566 572 } 567 573
Changes to ext/fts5/test/fts5aa.test.
586 586 INSERT INTO t9(rowid, x) VALUES(3, 'bbb'); 587 587 COMMIT; 588 588 } 589 589 590 590 do_execsql_test 22.1 { 591 591 SELECT rowid FROM t9('a*') 592 592 } {1} 593 + 594 +#------------------------------------------------------------------------- 595 +do_execsql_test 23.0 { 596 + CREATE VIRTUAL TABLE t10 USING fts5(x, detail=%DETAIL%); 597 + CREATE TABLE t11(x); 598 +} 599 +do_execsql_test 23.1 { 600 + SELECT * FROM t11, t10 WHERE t11.x = t10.x AND t10.rowid IS NULL; 601 +} 602 +do_execsql_test 23.2 { 603 + SELECT * FROM t11, t10 WHERE t10.rowid IS NULL; 604 +} 593 605 594 606 } 595 607 596 608 expand_all_sql db 597 609 finish_test
Changes to ext/icu/README.txt.
35 35 36 36 http://www.icu-project.org/userguide/caseMappings.html 37 37 http://www.icu-project.org/userguide/posix.html#case_mappings 38 38 39 39 To utilise "general" case mapping, the upper() or lower() scalar 40 40 functions are invoked with one argument: 41 41 42 - upper('ABC') -> 'abc' 43 - lower('abc') -> 'ABC' 42 + upper('abc') -> 'ABC' 43 + lower('ABC') -> 'abc' 44 44 45 45 To access ICU "language specific" case mapping, upper() or lower() 46 46 should be invoked with two arguments. The second argument is the name 47 47 of the locale to use. Passing an empty string ("") or SQL NULL value 48 48 as the second argument is the same as invoking the 1 argument version 49 49 of upper() or lower(): 50 50
Changes to ext/misc/completion.c.
74 74 #define COMPLETION_KEYWORDS 1 75 75 #define COMPLETION_PRAGMAS 2 76 76 #define COMPLETION_FUNCTIONS 3 77 77 #define COMPLETION_COLLATIONS 4 78 78 #define COMPLETION_INDEXES 5 79 79 #define COMPLETION_TRIGGERS 6 80 80 #define COMPLETION_DATABASES 7 81 -#define COMPLETION_TABLES 8 81 +#define COMPLETION_TABLES 8 /* Also VIEWs and TRIGGERs */ 82 82 #define COMPLETION_COLUMNS 9 83 83 #define COMPLETION_MODULES 10 84 84 #define COMPLETION_EOF 11 85 85 86 86 /* 87 87 ** The completionConnect() method is invoked to create a new 88 88 ** completion_vtab that describes the completion virtual table. ................................................................................ 246 246 char *zSql = 0; 247 247 const char *zSep = ""; 248 248 sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pS2, 0); 249 249 while( sqlite3_step(pS2)==SQLITE_ROW ){ 250 250 const char *zDb = (const char*)sqlite3_column_text(pS2, 1); 251 251 zSql = sqlite3_mprintf( 252 252 "%z%s" 253 - "SELECT name FROM \"%w\".sqlite_master" 254 - " WHERE type='table'", 253 + "SELECT name FROM \"%w\".sqlite_master", 255 254 zSql, zSep, zDb 256 255 ); 257 256 if( zSql==0 ) return SQLITE_NOMEM; 258 257 zSep = " UNION "; 259 258 } 260 259 sqlite3_finalize(pS2); 261 260 sqlite3_prepare_v2(pCur->db, zSql, -1, &pCur->pStmt, 0);
Changes to ext/misc/eval.c.
30 30 31 31 /* 32 32 ** Callback from sqlite_exec() for the eval() function. 33 33 */ 34 34 static int callback(void *pCtx, int argc, char **argv, char **colnames){ 35 35 struct EvalResult *p = (struct EvalResult*)pCtx; 36 36 int i; 37 + if( argv==0 ) return 0; 37 38 for(i=0; i<argc; i++){ 38 39 const char *z = argv[i] ? argv[i] : ""; 39 40 size_t sz = strlen(z); 40 41 if( (sqlite3_int64)sz+p->nUsed+p->szSep+1 > p->nAlloc ){ 41 42 char *zNew; 42 43 p->nAlloc = p->nAlloc*2 + sz + p->szSep + 1; 43 44 /* Using sqlite3_realloc64() would be better, but it is a recent
Changes to ext/misc/fileio.c.
89 89 # include <sys/time.h> 90 90 #else 91 91 # include "windows.h" 92 92 # include <io.h> 93 93 # include <direct.h> 94 94 # include "test_windirent.h" 95 95 # define dirent DIRENT 96 +# ifndef chmod 97 +# define chmod _chmod 98 +# endif 96 99 # ifndef stat 97 100 # define stat _stat 98 101 # endif 99 102 # define mkdir(path,mode) _mkdir(path) 100 103 # define lstat(path,buf) stat(path,buf) 101 104 #endif 102 105 #include <time.h> ................................................................................ 154 157 va_list ap; 155 158 va_start(ap, zFmt); 156 159 zMsg = sqlite3_vmprintf(zFmt, ap); 157 160 sqlite3_result_error(ctx, zMsg, -1); 158 161 sqlite3_free(zMsg); 159 162 va_end(ap); 160 163 } 164 + 165 +#if defined(_WIN32) 166 +/* 167 +** This function is designed to convert a Win32 FILETIME structure into the 168 +** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC). 169 +*/ 170 +static sqlite3_uint64 fileTimeToUnixTime( 171 + LPFILETIME pFileTime 172 +){ 173 + SYSTEMTIME epochSystemTime; 174 + ULARGE_INTEGER epochIntervals; 175 + FILETIME epochFileTime; 176 + ULARGE_INTEGER fileIntervals; 177 + 178 + memset(&epochSystemTime, 0, sizeof(SYSTEMTIME)); 179 + epochSystemTime.wYear = 1970; 180 + epochSystemTime.wMonth = 1; 181 + epochSystemTime.wDay = 1; 182 + SystemTimeToFileTime(&epochSystemTime, &epochFileTime); 183 + epochIntervals.LowPart = epochFileTime.dwLowDateTime; 184 + epochIntervals.HighPart = epochFileTime.dwHighDateTime; 185 + 186 + fileIntervals.LowPart = pFileTime->dwLowDateTime; 187 + fileIntervals.HighPart = pFileTime->dwHighDateTime; 188 + 189 + return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000; 190 +} 191 + 192 +/* 193 +** This function attempts to normalize the time values found in the stat() 194 +** buffer to UTC. This is necessary on Win32, where the runtime library 195 +** appears to return these values as local times. 196 +*/ 197 +static void statTimesToUtc( 198 + const char *zPath, 199 + struct stat *pStatBuf 200 +){ 201 + HANDLE hFindFile; 202 + WIN32_FIND_DATAW fd; 203 + LPWSTR zUnicodeName; 204 + extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); 205 + zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath); 206 + if( zUnicodeName ){ 207 + memset(&fd, 0, sizeof(WIN32_FIND_DATA)); 208 + hFindFile = FindFirstFileW(zUnicodeName, &fd); 209 + if( hFindFile!=NULL ){ 210 + pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime); 211 + pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime); 212 + pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime); 213 + FindClose(hFindFile); 214 + } 215 + sqlite3_free(zUnicodeName); 216 + } 217 +} 218 +#endif 219 + 220 +/* 221 +** This function is used in place of stat(). On Windows, special handling 222 +** is required in order for the included time to be returned as UTC. On all 223 +** other systems, this function simply calls stat(). 224 +*/ 225 +static int fileStat( 226 + const char *zPath, 227 + struct stat *pStatBuf 228 +){ 229 +#if defined(_WIN32) 230 + int rc = stat(zPath, pStatBuf); 231 + if( rc==0 ) statTimesToUtc(zPath, pStatBuf); 232 + return rc; 233 +#else 234 + return stat(zPath, pStatBuf); 235 +#endif 236 +} 237 + 238 +/* 239 +** This function is used in place of lstat(). On Windows, special handling 240 +** is required in order for the included time to be returned as UTC. On all 241 +** other systems, this function simply calls lstat(). 242 +*/ 243 +static int fileLinkStat( 244 + const char *zPath, 245 + struct stat *pStatBuf 246 +){ 247 +#if defined(_WIN32) 248 + int rc = lstat(zPath, pStatBuf); 249 + if( rc==0 ) statTimesToUtc(zPath, pStatBuf); 250 + return rc; 251 +#else 252 + return lstat(zPath, pStatBuf); 253 +#endif 254 +} 161 255 162 256 /* 163 257 ** Argument zFile is the name of a file that will be created and/or written 164 258 ** by SQL function writefile(). This function ensures that the directory 165 259 ** zFile will be written to exists, creating it if required. The permissions 166 260 ** for any path components created by this function are set to (mode&0777). 167 261 ** ................................................................................ 186 280 struct stat sStat; 187 281 int rc2; 188 282 189 283 for(; zCopy[i]!='/' && i<nCopy; i++); 190 284 if( i==nCopy ) break; 191 285 zCopy[i] = '\0'; 192 286 193 - rc2 = stat(zCopy, &sStat); 287 + rc2 = fileStat(zCopy, &sStat); 194 288 if( rc2!=0 ){ 195 289 if( mkdir(zCopy, mode & 0777) ) rc = SQLITE_ERROR; 196 290 }else{ 197 291 if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR; 198 292 } 199 293 zCopy[i] = '/'; 200 294 i++; ................................................................................ 228 322 if( mkdir(zFile, mode) ){ 229 323 /* The mkdir() call to create the directory failed. This might not 230 324 ** be an error though - if there is already a directory at the same 231 325 ** path and either the permissions already match or can be changed 232 326 ** to do so using chmod(), it is not an error. */ 233 327 struct stat sStat; 234 328 if( errno!=EEXIST 235 - || 0!=stat(zFile, &sStat) 329 + || 0!=fileStat(zFile, &sStat) 236 330 || !S_ISDIR(sStat.st_mode) 237 331 || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777)) 238 332 ){ 239 333 return 1; 240 334 } 241 335 } 242 336 }else{ ................................................................................ 275 369 276 370 GetSystemTime(¤tTime); 277 371 SystemTimeToFileTime(¤tTime, &lastAccess); 278 372 intervals = Int32x32To64(mtime, 10000000) + 116444736000000000; 279 373 lastWrite.dwLowDateTime = (DWORD)intervals; 280 374 lastWrite.dwHighDateTime = intervals >> 32; 281 375 zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile); 376 + if( zUnicodeName==0 ){ 377 + return 1; 378 + } 282 379 hFile = CreateFileW( 283 380 zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING, 284 381 FILE_FLAG_BACKUP_SEMANTICS, NULL 285 382 ); 286 383 sqlite3_free(zUnicodeName); 287 384 if( hFile!=INVALID_HANDLE_VALUE ){ 288 385 BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite); 289 386 CloseHandle(hFile); 290 387 return !bResult; 291 388 }else{ 292 389 return 1; 293 390 } 294 -#elif defined(AT_FDCWD) && 0 /* utimensat() is not univerally available */ 391 +#elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */ 295 392 /* Recent unix */ 296 393 struct timespec times[2]; 297 394 times[0].tv_nsec = times[1].tv_nsec = 0; 298 395 times[0].tv_sec = time(0); 299 396 times[1].tv_sec = mtime; 300 397 if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){ 301 398 return 1; ................................................................................ 492 589 } 493 590 sqlite3_free(pCur->zPath); 494 591 sqlite3_free(pCur->aLvl); 495 592 pCur->aLvl = 0; 496 593 pCur->zPath = 0; 497 594 pCur->zBase = 0; 498 595 pCur->nBase = 0; 596 + pCur->nLvl = 0; 499 597 pCur->iLvl = -1; 500 598 pCur->iRowid = 1; 501 599 } 502 600 503 601 /* 504 602 ** Destructor for an fsdir_cursor. 505 603 */ ................................................................................ 563 661 if( pEntry->d_name[0]=='.' ){ 564 662 if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue; 565 663 if( pEntry->d_name[1]=='\0' ) continue; 566 664 } 567 665 sqlite3_free(pCur->zPath); 568 666 pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name); 569 667 if( pCur->zPath==0 ) return SQLITE_NOMEM; 570 - if( lstat(pCur->zPath, &pCur->sStat) ){ 668 + if( fileLinkStat(pCur->zPath, &pCur->sStat) ){ 571 669 fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath); 572 670 return SQLITE_ERROR; 573 671 } 574 672 return SQLITE_OK; 575 673 } 576 674 closedir(pLvl->pDir); 577 675 sqlite3_free(pLvl->zDir); ................................................................................ 697 795 }else{ 698 796 pCur->zPath = sqlite3_mprintf("%s", zDir); 699 797 } 700 798 701 799 if( pCur->zPath==0 ){ 702 800 return SQLITE_NOMEM; 703 801 } 704 - if( lstat(pCur->zPath, &pCur->sStat) ){ 802 + if( fileLinkStat(pCur->zPath, &pCur->sStat) ){ 705 803 fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath); 706 804 return SQLITE_ERROR; 707 805 } 708 806 709 807 return SQLITE_OK; 710 808 } 711 809
Changes to ext/misc/series.c.
265 265 pCur->mxValue = 0xffffffff; 266 266 } 267 267 if( idxNum & 4 ){ 268 268 pCur->iStep = sqlite3_value_int64(argv[i++]); 269 269 if( pCur->iStep<1 ) pCur->iStep = 1; 270 270 }else{ 271 271 pCur->iStep = 1; 272 + } 273 + for(i=0; i<argc; i++){ 274 + if( sqlite3_value_type(argv[i])==SQLITE_NULL ){ 275 + /* If any of the constraints have a NULL value, then return no rows. 276 + ** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */ 277 + pCur->mnValue = 1; 278 + pCur->mxValue = 0; 279 + break; 280 + } 272 281 } 273 282 if( idxNum & 8 ){ 274 283 pCur->isDesc = 1; 275 284 pCur->iValue = pCur->mxValue; 276 285 if( pCur->iStep>0 ){ 277 286 pCur->iValue -= (pCur->mxValue - pCur->mnValue)%pCur->iStep; 278 287 }
Changes to ext/misc/spellfix.c.
760 760 int nTo = zTo ? sqlite3_column_bytes(pStmt, 2) : 0; 761 761 int iCost = sqlite3_column_int(pStmt, 3); 762 762 763 763 assert( zFrom!=0 || nFrom==0 ); 764 764 assert( zTo!=0 || nTo==0 ); 765 765 if( nFrom>100 || nTo>100 ) continue; 766 766 if( iCost<0 ) continue; 767 - if( iCost>10000 ) continue; /* Costs above 10K are considered infinite */ 767 + if( iCost>=10000 ) continue; /* Costs above 10K are considered infinite */ 768 768 if( pLang==0 || iLang!=iLangPrev ){ 769 769 EditDist3Lang *pNew; 770 770 pNew = sqlite3_realloc64(p->a, (p->nLang+1)*sizeof(p->a[0])); 771 771 if( pNew==0 ){ rc = SQLITE_NOMEM; break; } 772 772 p->a = pNew; 773 773 pLang = &p->a[p->nLang]; 774 774 p->nLang++; ................................................................................ 831 831 } 832 832 833 833 /* 834 834 ** Return TRUE (non-zero) if the To side of the given cost matches 835 835 ** the given string. 836 836 */ 837 837 static int matchTo(EditDist3Cost *p, const char *z, int n){ 838 + assert( n>0 ); 838 839 if( p->a[p->nFrom]!=z[0] ) return 0; 839 840 if( p->nTo>n ) return 0; 840 841 if( strncmp(p->a+p->nFrom, z, p->nTo)!=0 ) return 0; 841 842 return 1; 842 843 } 843 844 844 845 /* 845 846 ** Return TRUE (non-zero) if the From side of the given cost matches 846 847 ** the given string. 847 848 */ 848 849 static int matchFrom(EditDist3Cost *p, const char *z, int n){ 849 850 assert( p->nFrom<=n ); 850 - if( p->a[0]!=z[0] ) return 0; 851 - if( strncmp(p->a, z, p->nFrom)!=0 ) return 0; 851 + if( p->nFrom ){ 852 + if( p->a[0]!=z[0] ) return 0; 853 + if( strncmp(p->a, z, p->nFrom)!=0 ) return 0; 854 + } 852 855 return 1; 853 856 } 854 857 855 858 /* 856 859 ** Return TRUE (non-zero) of the next FROM character and the next TO 857 860 ** character are the same. 858 861 */ ................................................................................ 860 863 EditDist3FromString *pStr, /* Left hand string */ 861 864 int n1, /* Index of comparison character on the left */ 862 865 const char *z2, /* Right-handl comparison character */ 863 866 int n2 /* Bytes remaining in z2[] */ 864 867 ){ 865 868 int b1 = pStr->a[n1].nByte; 866 869 if( b1>n2 ) return 0; 870 + assert( b1>0 ); 867 871 if( pStr->z[n1]!=z2[0] ) return 0; 868 872 if( strncmp(pStr->z+n1, z2, b1)!=0 ) return 0; 869 873 return 1; 870 874 } 871 875 872 876 /* 873 877 ** Delete an EditDist3FromString objecct
Changes to ext/misc/zipfile.c.
1495 1495 */ 1496 1496 static u32 zipfileGetTime(sqlite3_value *pVal){ 1497 1497 if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){ 1498 1498 return zipfileTime(); 1499 1499 } 1500 1500 return (u32)sqlite3_value_int64(pVal); 1501 1501 } 1502 + 1503 +/* 1504 +** Unless it is NULL, entry pOld is currently part of the pTab->pFirstEntry 1505 +** linked list. Remove it from the list and free the object. 1506 +*/ 1507 +static void zipfileRemoveEntryFromList(ZipfileTab *pTab, ZipfileEntry *pOld){ 1508 + if( pOld ){ 1509 + ZipfileEntry **pp; 1510 + for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext)); 1511 + *pp = (*pp)->pNext; 1512 + zipfileEntryFree(pOld); 1513 + } 1514 +} 1502 1515 1503 1516 /* 1504 1517 ** xUpdate method. 1505 1518 */ 1506 1519 static int zipfileUpdate( 1507 1520 sqlite3_vtab *pVtab, 1508 1521 int nVal, ................................................................................ 1520 1533 int nPath = 0; /* strlen(zPath) */ 1521 1534 const u8 *pData = 0; /* Pointer to buffer containing content */ 1522 1535 int nData = 0; /* Size of pData buffer in bytes */ 1523 1536 int iMethod = 0; /* Compression method for new entry */ 1524 1537 u8 *pFree = 0; /* Free this */ 1525 1538 char *zFree = 0; /* Also free this */ 1526 1539 ZipfileEntry *pOld = 0; 1540 + ZipfileEntry *pOld2 = 0; 1541 + int bUpdate = 0; /* True for an update that modifies "name" */ 1527 1542 int bIsDir = 0; 1528 1543 u32 iCrc32 = 0; 1529 1544 1530 1545 if( pTab->pWriteFd==0 ){ 1531 1546 rc = zipfileBegin(pVtab); 1532 1547 if( rc!=SQLITE_OK ) return rc; 1533 1548 } 1534 1549 1535 1550 /* If this is a DELETE or UPDATE, find the archive entry to delete. */ 1536 1551 if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ 1537 1552 const char *zDelete = (const char*)sqlite3_value_text(apVal[0]); 1538 1553 int nDelete = (int)strlen(zDelete); 1554 + if( nVal>1 ){ 1555 + const char *zUpdate = (const char*)sqlite3_value_text(apVal[1]); 1556 + if( zUpdate && zipfileComparePath(zUpdate, zDelete, nDelete)!=0 ){ 1557 + bUpdate = 1; 1558 + } 1559 + } 1539 1560 for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){ 1540 1561 if( zipfileComparePath(pOld->cds.zFile, zDelete, nDelete)==0 ){ 1541 1562 break; 1542 1563 } 1543 1564 assert( pOld->pNext ); 1544 1565 } 1545 1566 } ................................................................................ 1609 1630 zFree = sqlite3_mprintf("%s/", zPath); 1610 1631 if( zFree==0 ){ rc = SQLITE_NOMEM; } 1611 1632 zPath = (const char*)zFree; 1612 1633 nPath++; 1613 1634 } 1614 1635 } 1615 1636 1616 - /* Check that we're not inserting a duplicate entry */ 1617 - if( pOld==0 && rc==SQLITE_OK ){ 1637 + /* Check that we're not inserting a duplicate entry -OR- updating an 1638 + ** entry with a path, thereby making it into a duplicate. */ 1639 + if( (pOld==0 || bUpdate) && rc==SQLITE_OK ){ 1618 1640 ZipfileEntry *p; 1619 1641 for(p=pTab->pFirstEntry; p; p=p->pNext){ 1620 1642 if( zipfileComparePath(p->cds.zFile, zPath, nPath)==0 ){ 1621 1643 switch( sqlite3_vtab_on_conflict(pTab->db) ){ 1622 1644 case SQLITE_IGNORE: { 1623 1645 goto zipfile_update_done; 1624 1646 } 1625 1647 case SQLITE_REPLACE: { 1626 - pOld = p; 1648 + pOld2 = p; 1627 1649 break; 1628 1650 } 1629 1651 default: { 1630 1652 zipfileTableErr(pTab, "duplicate name: \"%s\"", zPath); 1631 1653 rc = SQLITE_CONSTRAINT; 1632 1654 break; 1633 1655 } ................................................................................ 1657 1679 pNew->mUnixTime = (u32)mTime; 1658 1680 rc = zipfileAppendEntry(pTab, pNew, pData, nData); 1659 1681 zipfileAddEntry(pTab, pOld, pNew); 1660 1682 } 1661 1683 } 1662 1684 } 1663 1685 1664 - if( rc==SQLITE_OK && pOld ){ 1665 - ZipfileEntry **pp; 1686 + if( rc==SQLITE_OK && (pOld || pOld2) ){ 1666 1687 ZipfileCsr *pCsr; 1667 1688 for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){ 1668 - if( pCsr->pCurrent==pOld ){ 1669 - pCsr->pCurrent = pOld->pNext; 1689 + if( pCsr->pCurrent && (pCsr->pCurrent==pOld || pCsr->pCurrent==pOld2) ){ 1690 + pCsr->pCurrent = pCsr->pCurrent->pNext; 1670 1691 pCsr->bNoop = 1; 1671 1692 } 1672 1693 } 1673 - for(pp=&pTab->pFirstEntry; (*pp)!=pOld; pp=&((*pp)->pNext)); 1674 - *pp = (*pp)->pNext; 1675 - zipfileEntryFree(pOld); 1694 + 1695 + zipfileRemoveEntryFromList(pTab, pOld); 1696 + zipfileRemoveEntryFromList(pTab, pOld2); 1676 1697 } 1677 1698 1678 1699 zipfile_update_done: 1679 1700 sqlite3_free(pFree); 1680 1701 sqlite3_free(zFree); 1681 1702 return rc; 1682 1703 } ................................................................................ 2036 2057 2037 2058 /* Append the LFH to the body of the new archive */ 2038 2059 nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9; 2039 2060 if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out; 2040 2061 p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]); 2041 2062 2042 2063 /* Append the data to the body of the new archive */ 2043 - if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out; 2044 - memcpy(&p->body.a[p->body.n], aData, nData); 2045 - p->body.n += nData; 2064 + if( nData>0 ){ 2065 + if( (rc = zipfileBufferGrow(&p->body, nData)) ) goto zipfile_step_out; 2066 + memcpy(&p->body.a[p->body.n], aData, nData); 2067 + p->body.n += nData; 2068 + } 2046 2069 2047 2070 /* Append the CDS record to the directory of the new archive */ 2048 2071 nByte = ZIPFILE_CDS_FIXED_SZ + e.cds.nFile + 9; 2049 2072 if( (rc = zipfileBufferGrow(&p->cds, nByte)) ) goto zipfile_step_out; 2050 2073 p->cds.n += zipfileSerializeCDS(&e, &p->cds.a[p->cds.n]); 2051 2074 2052 2075 /* Increment the count of entries in the archive */
Changes to ext/rbu/rbu_common.tcl.
67 67 rbu close 68 68 if {$rc != "SQLITE_OK"} break 69 69 } 70 70 set rc 71 71 } 72 72 73 73 proc do_rbu_vacuum_test {tn step} { 74 + forcedelete state.db 74 75 uplevel [list do_test $tn.1 { 75 76 if {$step==0} { sqlite3rbu_vacuum rbu test.db state.db } 76 77 while 1 { 77 78 if {$step==1} { sqlite3rbu_vacuum rbu test.db state.db } 78 79 set state [rbu state] 79 80 check_prestep_state test.db $state 80 81 set rc [rbu step]
Added ext/rbu/rbucollate.test.
1 +# 2018 March 22 2 +# 3 +# The author disclaims copyright to this source code. In place of 4 +# a legal notice, here is a blessing: 5 +# 6 +# May you do good and not evil. 7 +# May you find forgiveness for yourself and forgive others. 8 +# May you share freely, never taking more than you give. 9 +# 10 +#*********************************************************************** 11 +# 12 + 13 +source [file join [file dirname [info script]] rbu_common.tcl] 14 +set ::testprefix rbucollate 15 + 16 +ifcapable !icu_collations { 17 + finish_test 18 + return 19 +} 20 + 21 +db close 22 +sqlite3_shutdown 23 +sqlite3_config_uri 1 24 +reset_db 25 + 26 +# Create a simple RBU database. That expects to write to a table: 27 +# 28 +# CREATE TABLE t1(a PRIMARY KEY, b, c); 29 +# 30 +proc create_rbu1 {filename} { 31 + forcedelete $filename 32 + sqlite3 rbu1 $filename 33 + rbu1 eval { 34 + CREATE TABLE data_t1(a, b, c, rbu_control); 35 + INSERT INTO data_t1 VALUES('a', 'one', 1, 0); 36 + INSERT INTO data_t1 VALUES('b', 'two', 2, 0); 37 + INSERT INTO data_t1 VALUES('c', 'three', 3, 0); 38 + } 39 + rbu1 close 40 + return $filename 41 +} 42 + 43 +do_execsql_test 1.0 { 44 + SELECT icu_load_collation('en_US', 'my-collate'); 45 + CREATE TABLE t1(a COLLATE "my-collate" PRIMARY KEY, b, c); 46 +} {{}} 47 + 48 +do_test 1.2 { 49 + create_rbu1 testrbu.db 50 + sqlite3rbu rbu test.db testrbu.db 51 + rbu dbMain_eval { SELECT icu_load_collation('en_US', 'my-collate') } 52 + rbu dbRbu_eval { SELECT icu_load_collation('en_US', 'my-collate') } 53 + while 1 { 54 + set rc [rbu step] 55 + if {$rc!="SQLITE_OK"} break 56 + } 57 + rbu close 58 + db eval { SELECT * FROM t1 } 59 +} {a one 1 b two 2 c three 3} 60 + 61 +#forcedelete testrbu.db 62 +finish_test 63 +
Changes to ext/rbu/sqlite3rbu.c.
1802 1802 1803 1803 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ 1804 1804 int bKey = sqlite3_column_int(pXInfo, 5); 1805 1805 if( bKey ){ 1806 1806 int iCid = sqlite3_column_int(pXInfo, 1); 1807 1807 int bDesc = sqlite3_column_int(pXInfo, 3); 1808 1808 const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); 1809 - zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma, 1809 + zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %Q", zCols, zComma, 1810 1810 iCid, pIter->azTblType[iCid], zCollate 1811 1811 ); 1812 1812 zPk = rbuMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":""); 1813 1813 zComma = ", "; 1814 1814 } 1815 1815 } 1816 1816 zCols = rbuMPrintf(p, "%z, id INTEGER", zCols); ................................................................................ 1863 1863 ); 1864 1864 1865 1865 if( pIter->eType==RBU_PK_IPK && pIter->abTblPk[iCol] ){ 1866 1866 /* If the target table column is an "INTEGER PRIMARY KEY", add 1867 1867 ** "PRIMARY KEY" to the imposter table column declaration. */ 1868 1868 zPk = "PRIMARY KEY "; 1869 1869 } 1870 - zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s", 1870 + zSql = rbuMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %Q%s", 1871 1871 zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl, 1872 1872 (pIter->abNotNull[iCol] ? " NOT NULL" : "") 1873 1873 ); 1874 1874 zComma = ", "; 1875 1875 } 1876 1876 1877 1877 if( pIter->eType==RBU_PK_WITHOUT_ROWID ){
Changes to ext/rbu/test_rbu.c.
77 77 {"bp_progress", 2, ""}, /* 5 */ 78 78 {"db", 3, "RBU"}, /* 6 */ 79 79 {"state", 2, ""}, /* 7 */ 80 80 {"progress", 2, ""}, /* 8 */ 81 81 {"close_no_error", 2, ""}, /* 9 */ 82 82 {"temp_size_limit", 3, "LIMIT"}, /* 10 */ 83 83 {"temp_size", 2, ""}, /* 11 */ 84 + {"dbRbu_eval", 3, "SQL"}, /* 12 */ 84 85 {0,0,0} 85 86 }; 86 87 int iCmd; 87 88 88 89 if( objc<2 ){ 89 90 Tcl_WrongNumArgs(interp, 1, objv, "METHOD"); 90 91 return TCL_ERROR; ................................................................................ 142 143 case 3: /* savestate */ { 143 144 int rc = sqlite3rbu_savestate(pRbu); 144 145 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); 145 146 ret = (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); 146 147 break; 147 148 } 148 149 149 - case 4: /* dbMain_eval */ { 150 - sqlite3 *db = sqlite3rbu_db(pRbu, 0); 150 + case 12: /* dbRbu_eval */ 151 + case 4: /* dbMain_eval */ { 152 + sqlite3 *db = sqlite3rbu_db(pRbu, (iCmd==12)); 151 153 int rc = sqlite3_exec(db, Tcl_GetString(objv[2]), 0, 0, 0); 152 154 if( rc!=SQLITE_OK ){ 153 155 Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(db), -1)); 154 156 ret = TCL_ERROR; 155 157 } 156 158 break; 157 159 }
Changes to ext/session/session1.test.
607 607 do_iterator_test $tn.12.2 * { 608 608 UPDATE t1 SET b='one' WHERE a=1; 609 609 } { 610 610 {UPDATE t1 0 X.. {i 1 {} {} i 1} {{} {} {} {} t one}} 611 611 {UPDATE t1 0 X.. {i 2 {} {} i 2} {{} {} {} {} t one}} 612 612 {UPDATE t1 0 X.. {i 3 {} {} i 3} {{} {} {} {} t one}} 613 613 } 614 + 615 +#------------------------------------------------------------------------- 616 +# Test that no savepoint is used if -nosavepoint is specified. 617 +# 618 +do_execsql_test $tn.13.1 { 619 + CREATE TABLE x1(a INTEGER PRIMARY KEY, b)%WR%; 620 +} 621 +do_test $tn.13.2 { 622 + execsql BEGIN 623 + set C [changeset_from_sql { 624 + INSERT INTO x1 VALUES(1, 'one'); 625 + INSERT INTO x1 VALUES(2, 'two'); 626 + INSERT INTO x1 VALUES(3, 'three'); 627 + }] 628 + execsql ROLLBACK 629 + execsql { 630 + INSERT INTO x1 VALUES(1, 'i'); 631 + INSERT INTO x1 VALUES(2, 'ii'); 632 + INSERT INTO x1 VALUES(3, 'iii'); 633 + } 634 +} {} 635 + 636 +proc xConflict {args} { 637 + set ret [lindex $::CONFLICT_HANDLERS 0] 638 + set ::CONFLICT_HANDLERS [lrange $::CONFLICT_HANDLERS 1 end] 639 + set ret 640 +} 641 +do_test $tn.13.3 { 642 + set CONFLICT_HANDLERS [list REPLACE REPLACE ABORT] 643 + execsql BEGIN 644 + catch { sqlite3changeset_apply_v2 db $C xConflict } msg 645 + execsql { 646 + SELECT * FROM x1 647 + } 648 +} {1 i 2 ii 3 iii} 649 +do_test $tn.13.3 { 650 + set CONFLICT_HANDLERS [list REPLACE REPLACE ABORT] 651 + execsql ROLLBACK 652 + execsql BEGIN 653 + catch { sqlite3changeset_apply_v2 -nosavepoint db $C xConflict } msg 654 + execsql { SELECT * FROM x1 } 655 +} {1 one 2 two 3 iii} 656 +execsql ROLLBACK 614 657 615 658 }] 616 659 } 617 660 618 661 619 662 finish_test
Changes to ext/session/session4.test.
6 6 # May you do good and not evil. 7 7 # May you find forgiveness for yourself and forgive others. 8 8 # May you share freely, never taking more than you give. 9 9 # 10 10 #*********************************************************************** 11 11 # This file implements regression tests for the session module. 12 12 # 13 + 14 +package require Tcl 8.6 13 15 14 16 if {![info exists testdir]} { 15 17 set testdir [file join [file dirname [info script]] .. .. test] 16 18 } 17 19 source [file join [file dirname [info script]] session_common.tcl] 18 20 source $testdir/tester.tcl 19 21 ifcapable !session {finish_test; return}
Changes to ext/session/sessionG.test.
200 200 db2 eval { 201 201 SELECT * FROM t1; 202 202 SELECT * FROM t2; 203 203 SELECT * FROM t3; 204 204 } 205 205 } {1 2 3 7 8 9} 206 206 207 +#------------------------------------------------------------------------- 208 + 209 +reset_db 210 +db func number_name number_name 211 +do_execsql_test 6.0 { 212 + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); 213 + CREATE UNIQUE INDEX t1b ON t1(b); 214 + WITH s(i) AS ( 215 + SELECT 1 216 + UNION ALL 217 + SELECT i+1 FROM s WHERE i<1000 218 + ) 219 + INSERT INTO t1 SELECT i, number_name(i) FROM s; 220 +} 221 + 222 +do_test 6.1 { 223 + db eval BEGIN 224 + set ::C [changeset_from_sql { 225 + DELETE FROM t1; 226 + WITH s(i) AS ( 227 + SELECT 1 228 + UNION ALL 229 + SELECT i+1 FROM s WHERE i<1000 230 + ) 231 + INSERT INTO t1 SELECT i, number_name(i+1) FROM s; 232 + }] 233 + db eval ROLLBACK 234 + execsql { SELECT count(*) FROM t1 WHERE number_name(a) IS NOT b } 235 +} {0} 236 + 237 +proc xConflict {args} { exit ; return "OMIT" } 238 +do_test 6.2 { 239 + sqlite3changeset_apply db $C xConflict 240 +} {} 241 + 242 +do_execsql_test 6.3 { SELECT count(*) FROM t1; } {1000} 243 +do_execsql_test 6.4 { 244 + SELECT count(*) FROM t1 WHERE number_name(a+1) IS NOT b; 245 +} {0} 207 246 247 +# db eval { SELECT * FROM t1 } { puts "$a || $b" } 208 248 209 249 210 250 finish_test 211 251
Changes to ext/session/session_common.tcl.
165 165 } 166 166 167 167 proc changeset_to_list {c} { 168 168 set list [list] 169 169 sqlite3session_foreach elem $c { lappend list $elem } 170 170 lsort $list 171 171 } 172 + 173 +set ones {zero one two three four five six seven eight nine 174 + ten eleven twelve thirteen fourteen fifteen sixteen seventeen 175 + eighteen nineteen} 176 +set tens {{} ten twenty thirty forty fifty sixty seventy eighty ninety} 177 +proc number_name {n} { 178 + if {$n>=1000} { 179 + set txt "[number_name [expr {$n/1000}]] thousand" 180 + set n [expr {$n%1000}] 181 + } else { 182 + set txt {} 183 + } 184 + if {$n>=100} { 185 + append txt " [lindex $::ones [expr {$n/100}]] hundred" 186 + set n [expr {$n%100}] 187 + } 188 + if {$n>=20} { 189 + append txt " [lindex $::tens [expr {$n/10}]]" 190 + set n [expr {$n%10}] 191 + } 192 + if {$n>0} { 193 + append txt " [lindex $::ones $n]" 194 + } 195 + set txt [string trim $txt] 196 + if {$txt==""} {set txt zero} 197 + return $txt 198 +}
Changes to ext/session/sessionfault2.test.
15 15 if {![info exists testdir]} { 16 16 set testdir [file join [file dirname [info script]] .. .. test] 17 17 } 18 18 source [file join [file dirname [info script]] session_common.tcl] 19 19 source $testdir/tester.tcl 20 20 ifcapable !session {finish_test; return} 21 21 set testprefix sessionfault2 22 + 23 +if 1 { 22 24 23 25 do_execsql_test 1.0.0 { 24 26 CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); 25 27 INSERT INTO t1 VALUES(1, 1); 26 28 INSERT INTO t1 VALUES(2, 2); 27 29 INSERT INTO t1 VALUES(3, 3); 28 30 ................................................................................ 98 100 faultsim_restore_and_reopen 99 101 } -body { 100 102 sqlite3changeset_apply db $::C xConflict 101 103 } -test { 102 104 faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 103 105 faultsim_integrity_check 104 106 } 107 + 108 +#------------------------------------------------------------------------- 109 +# OOM when collecting and apply a changeset that uses sqlite_stat1. 110 +# 111 +reset_db 112 +forcedelete test.db2 113 +sqlite3 db2 test.db2 114 +do_common_sql { 115 + CREATE TABLE t1(a PRIMARY KEY, b UNIQUE, c); 116 + CREATE INDEX i1 ON t1(c); 117 + INSERT INTO t1 VALUES(1, 2, 3); 118 + INSERT INTO t1 VALUES(4, 5, 6); 119 + INSERT INTO t1 VALUES(7, 8, 9); 120 + CREATE TABLE t2(a, b, c); 121 + INSERT INTO t2 VALUES(1, 2, 3); 122 + INSERT INTO t2 VALUES(4, 5, 6); 123 + INSERT INTO t2 VALUES(7, 8, 9); 124 + ANALYZE; 125 +} 126 +faultsim_save_and_close 127 +db2 close 128 + 129 +do_faultsim_test 1.1 -faults oom-* -prep { 130 + catch {db2 close} 131 + catch {db close} 132 + faultsim_restore_and_reopen 133 + sqlite3 db2 test.db2 134 +} -body { 135 + do_then_apply_sql { 136 + INSERT INTO sqlite_stat1 VALUES('x', 'y', 45); 137 + UPDATE sqlite_stat1 SET stat = 123 WHERE tbl='t1' AND idx='i1'; 138 + UPDATE sqlite_stat1 SET stat = 456 WHERE tbl='t2'; 139 + } 140 +} -test { 141 + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 142 + faultsim_integrity_check 143 + if {$testrc==0} { compare_db db db2 } 144 +} 145 + 146 +#------------------------------------------------------------------------- 147 +# OOM when collecting and using a rebase changeset. 148 +# 149 +reset_db 150 +do_execsql_test 2.0 { 151 + CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c)); 152 + CREATE TABLE t4(x PRIMARY KEY, y, z); 153 + 154 + INSERT INTO t3 VALUES(1, 2, 3); 155 + INSERT INTO t3 VALUES(4, 2, 5); 156 + INSERT INTO t3 VALUES(7, 2, 9); 157 + 158 + INSERT INTO t4 VALUES('a', 'b', 'c'); 159 + INSERT INTO t4 VALUES('d', 'e', 'f'); 160 + INSERT INTO t4 VALUES('g', 'h', 'i'); 161 +} 162 +faultsim_save_and_close 163 +db2 close 164 + 165 +proc xConflict {ret args} { return $ret } 166 + 167 +do_test 2.1 { 168 + faultsim_restore_and_reopen 169 + set C1 [changeset_from_sql { 170 + INSERT INTO t3 VALUES(10, 11, 12); 171 + UPDATE t4 SET y='j' WHERE x='g'; 172 + DELETE FROM t4 WHERE x='a'; 173 + }] 174 + 175 + faultsim_restore_and_reopen 176 + set C2 [changeset_from_sql { 177 + INSERT INTO t3 VALUES(1000, 11, 12); 178 + DELETE FROM t4 WHERE x='g'; 179 + }] 180 + 181 + faultsim_restore_and_reopen 182 + sqlite3changeset_apply db $C1 [list xConflict OMIT] 183 + faultsim_save_and_close 184 +} {} 185 + 186 +do_faultsim_test 2.2 -faults oom* -prep { 187 + catch {db2 close} 188 + catch {db close} 189 + faultsim_restore_and_reopen 190 + sqlite3 db2 test.db2 191 +} -body { 192 + set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]] 193 + set {} {} 194 +} -test { 195 + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 196 +} 197 +do_faultsim_test 2.3 -faults oom* -prep { 198 + catch {db2 close} 199 + catch {db close} 200 + faultsim_restore_and_reopen 201 + sqlite3 db2 test.db2 202 +} -body { 203 + set rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]] 204 + set {} {} 205 +} -test { 206 + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 207 +} 208 +do_faultsim_test 2.4 -faults oom* -prep { 209 + catch {db2 close} 210 + catch {db close} 211 + faultsim_restore_and_reopen 212 + set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict REPLACE]] 213 +} -body { 214 + sqlite3rebaser_create R 215 + R configure $::rebase 216 + R rebase $::C1 217 + set {} {} 218 +} -test { 219 + catch { R delete } 220 + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 221 +} 222 +do_faultsim_test 2.5 -faults oom* -prep { 223 + catch {db2 close} 224 + catch {db close} 225 + faultsim_restore_and_reopen 226 + set ::rebase [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]] 227 +} -body { 228 + sqlite3rebaser_create R 229 + R configure $::rebase 230 + R rebase $::C1 231 + set {} {} 232 +} -test { 233 + catch { R delete } 234 + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 235 +} 236 + 237 +} 238 + 239 +reset_db 240 +do_execsql_test 3.0 { 241 + CREATE TABLE t1(x PRIMARY KEY, y, z); 242 + INSERT INTO t1 VALUES(3, 1, 4); 243 + INSERT INTO t1 VALUES(1, 5, 9); 244 +} 245 +faultsim_save_and_close 246 + 247 +proc xConflict {ret args} { return $ret } 248 + 249 +do_test 3.1 { 250 + faultsim_restore_and_reopen 251 + 252 + execsql { BEGIN; UPDATE t1 SET z=11; } 253 + set C1 [changeset_from_sql { 254 + UPDATE t1 SET z=10 WHERE x=1; 255 + }] 256 + execsql { ROLLBACK } 257 + 258 + execsql { BEGIN; UPDATE t1 SET z=11; } 259 + set C2 [changeset_from_sql { 260 + UPDATE t1 SET z=55 WHERE x=1; 261 + }] 262 + execsql { ROLLBACK } 263 + 264 + set ::rebase1 [sqlite3changeset_apply_v2 db $::C1 [list xConflict OMIT]] 265 + set ::rebase2 [sqlite3changeset_apply_v2 db $::C2 [list xConflict OMIT]] 266 + set {} {} 267 + execsql { SELECT * FROM t1 } 268 +} {3 1 4 1 5 9} 269 + 270 + 271 +do_faultsim_test 3.2 -faults oom* -prep { 272 + faultsim_restore_and_reopen 273 +} -body { 274 + sqlite3rebaser_create R 275 + R configure $::rebase1 276 + R configure $::rebase2 277 + set {} {} 278 +} -test { 279 + catch { R delete } 280 + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} 281 +} 282 + 105 283 106 284 finish_test 107 285
Added ext/session/sessionrebase.test.
1 +# 2018 March 14 2 +# 3 +# The author disclaims copyright to this source code. In place of 4 +# a legal notice, here is a blessing: 5 +# 6 +# May you do good and not evil. 7 +# May you find forgiveness for yourself and forgive others. 8 +# May you share freely, never taking more than you give. 9 +# 10 +#*********************************************************************** 11 +# This file implements regression tests for SQLite library. 12 +# 13 + 14 +if {![info exists testdir]} { 15 + set testdir [file join [file dirname [info script]] .. .. test] 16 +} 17 +source [file join [file dirname [info script]] session_common.tcl] 18 +source $testdir/tester.tcl 19 +ifcapable !session {finish_test; return} 20 + 21 +set testprefix sessionrebase 22 + 23 +set ::lConflict [list] 24 +proc xConflict {args} { 25 + set res [lindex $::lConflict 0] 26 + set ::lConflict [lrange $::lConflict 1 end] 27 + return $res 28 +} 29 + 30 +#------------------------------------------------------------------------- 31 +# The following test cases - 1.* - test that the rebase blobs output by 32 +# sqlite3_changeset_apply_v2 look correct in some simple cases. The blob 33 +# is itself a changeset, containing records determined as follows: 34 +# 35 +# * For each conflict resolved with REPLACE, the rebase blob contains 36 +# a DELETE record. All fields other than the PK fields are undefined. 37 +# 38 +# * For each conflict resolved with OMIT, the rebase blob contains an 39 +# INSERT record. For an INSERT or UPDATE operation, the indirect flag 40 +# is clear and all updated fields are defined. For a DELETE operation, 41 +# the indirect flag is set and all non-PK fields left undefined. 42 +# 43 +proc do_apply_v2_test {tn sql modsql conflict_handler res} { 44 + 45 + execsql BEGIN 46 + sqlite3session S db main 47 + S attach * 48 + execsql $sql 49 + set changeset [S changeset] 50 + S delete 51 + execsql ROLLBACK 52 + 53 + execsql BEGIN 54 + execsql $modsql 55 + set ::lConflict $conflict_handler 56 + set blob [sqlite3changeset_apply_v2 db $changeset xConflict] 57 + execsql ROLLBACK 58 + 59 + uplevel [list do_test $tn [list changeset_to_list $blob] [list {*}$res]] 60 +} 61 + 62 + 63 +set ::lConflict [list] 64 +proc xConflict {args} { 65 + set res [lindex $::lConflict 0] 66 + set ::lConflict [lrange $::lConflict 1 end] 67 + return $res 68 +} 69 + 70 +# Take a copy of database test.db in file test.db2. Execute $sql1 71 +# against test.db and $sql2 against test.db2. Capture a changeset 72 +# for each. Then send the test.db2 changeset to test.db and apply 73 +# it with the conflict handlers in $conflict_handler. Patch the 74 +# test.db changeset and then execute it against test.db2. Test that 75 +# the two databases come out the same. 76 +# 77 +proc do_rebase_test {tn sql1 sql2 conflict_handler {testsql ""} {testres ""}} { 78 + 79 + for {set i 1} {$i <= 2} {incr i} { 80 + forcedelete test.db2 test.db2-journal test.db2-wal 81 + forcecopy test.db test.db2 82 + sqlite3 db2 test.db2 83 + 84 + db eval BEGIN 85 + 86 + sqlite3session S1 db main 87 + S1 attach * 88 + execsql $sql1 db 89 + set c1 [S1 changeset] 90 + S1 delete 91 + 92 + if {$i==1} { 93 + sqlite3session S2 db2 main 94 + S2 attach * 95 + execsql $sql2 db2 96 + set c2 [S2 changeset] 97 + S2 delete 98 + } else { 99 + set c2 [list] 100 + foreach sql [split $sql2 ";"] { 101 + if {[string is space $sql]} continue 102 + sqlite3session S2 db2 main 103 + S2 attach * 104 + execsql $sql db2 105 + lappend c2 [S2 changeset] 106 + S2 delete 107 + } 108 + } 109 + 110 + set ::lConflict $conflict_handler 111 + set rebase [list] 112 + if {$i==1} { 113 + lappend rebase [sqlite3changeset_apply_v2 db $c2 xConflict] 114 + } else { 115 + foreach c $c2 { 116 +#puts "apply_v2: [changeset_to_list $c]" 117 + lappend rebase [sqlite3changeset_apply_v2 db $c xConflict] 118 + } 119 + #puts "llength: [llength $rebase]" 120 + } 121 + #if {$tn=="2.1.4"} { puts [changeset_to_list $rebase] ; breakpoint } 122 + #puts [changeset_to_list [lindex $rebase 0]] ; breakpoint 123 + #puts [llength $rebase] 124 + 125 + sqlite3rebaser_create R 126 + foreach r $rebase { 127 +#puts [changeset_to_list $r] 128 + R configure $r 129 + } 130 + set c1r [R rebase $c1] 131 + R delete 132 + #if {$tn=="2.1.4"} { puts [changeset_to_list $c1r] } 133 + 134 + sqlite3changeset_apply_v2 db2 $c1r xConflictAbort 135 + 136 + if {[string range $tn end end]!="*"} { 137 + uplevel [list do_test $tn.$i.1 [list compare_db db db2] {}] 138 + } 139 + db2 close 140 + 141 + if {$testsql!=""} { 142 + uplevel [list do_execsql_test $tn.$i.2 $testsql $testres] 143 + } 144 + 145 + db eval ROLLBACK 146 + } 147 +} 148 + 149 +do_execsql_test 1.0 { 150 + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); 151 + INSERT INTO t1 VALUES(1, 'value A'); 152 +} 153 + 154 +do_apply_v2_test 1.1.1 { 155 + UPDATE t1 SET b = 'value B' WHERE a=1; 156 +} { 157 + UPDATE t1 SET b = 'value C' WHERE a=1; 158 +} { 159 + OMIT 160 +} { 161 + {INSERT t1 0 X. {} {i 1 t {value B}}} 162 +} 163 + 164 +do_apply_v2_test 1.1.2 { 165 + UPDATE t1 SET b = 'value B' WHERE a=1; 166 +} { 167 + UPDATE t1 SET b = 'value C' WHERE a=1; 168 +} { 169 + REPLACE 170 +} { 171 + {INSERT t1 1 X. {} {i 1 t {value B}}} 172 +} 173 + 174 +do_apply_v2_test 1.2.1 { 175 + INSERT INTO t1 VALUES(2, 'first'); 176 +} { 177 + INSERT INTO t1 VALUES(2, 'second'); 178 +} { 179 + OMIT 180 +} { 181 + {INSERT t1 0 X. {} {i 2 t first}} 182 +} 183 +do_apply_v2_test 1.2.2 { 184 + INSERT INTO t1 VALUES(2, 'first'); 185 +} { 186 + INSERT INTO t1 VALUES(2, 'second'); 187 +} { 188 + REPLACE 189 +} { 190 + {INSERT t1 1 X. {} {i 2 t first}} 191 +} 192 + 193 +do_apply_v2_test 1.3.1 { 194 + DELETE FROM t1 WHERE a=1; 195 +} { 196 + UPDATE t1 SET b='value D' WHERE a=1; 197 +} { 198 + OMIT 199 +} { 200 + {DELETE t1 0 X. {i 1 t {value A}} {}} 201 +} 202 +do_apply_v2_test 1.3.2 { 203 + DELETE FROM t1 WHERE a=1; 204 +} { 205 + UPDATE t1 SET b='value D' WHERE a=1; 206 +} { 207 + REPLACE 208 +} { 209 + {DELETE t1 1 X. {i 1 t {value A}} {}} 210 +} 211 + 212 +#------------------------------------------------------------------------- 213 +# Test cases 2.* - simple tests of rebasing actual changesets. 214 +# 215 +# 2.1.1 - 1u2u1r 216 +# 2.1.2 - 1u2u2r 217 +# 2.1.3 - 1d2d 218 +# 2.1.4 - 1d2u1r 219 +# 2.1.5 - 1d2u2r !! 220 +# 2.1.6 - 1u2d1r 221 +# 2.1.7 - 1u2d2r 222 +# 223 +# 2.1.8 - 1i2i2r 224 +# 2.1.9 - 1i2i1r 225 +# 226 + 227 +proc xConflictAbort {args} { 228 + return "ABORT" 229 +} 230 + 231 +reset_db 232 +do_execsql_test 2.1.0 { 233 + CREATE TABLE t1 (a INTEGER PRIMARY KEY, b TEXT); 234 + INSERT INTO t1 VALUES(1, 'one'); 235 + INSERT INTO t1 VALUES(2, 'two'); 236 + INSERT INTO t1 VALUES(3, 'three'); 237 +} 238 +do_rebase_test 2.1.1 { 239 + UPDATE t1 SET b = 'two.1' WHERE a=2 240 +} { 241 + UPDATE t1 SET b = 'two.2' WHERE a=2; 242 +} { 243 + OMIT 244 +} { SELECT * FROM t1 } {1 one 2 two.1 3 three} 245 + 246 +do_rebase_test 2.1.2 { 247 + UPDATE t1 SET b = 'two.1' WHERE a=2 248 +} { 249 + UPDATE t1 SET b = 'two.2' WHERE a=2; 250 +} { 251 + REPLACE 252 +} { SELECT * FROM t1 } {1 one 2 two.2 3 three} 253 + 254 +do_rebase_test 2.1.3 { 255 + DELETE FROM t1 WHERE a=3 256 +} { 257 + DELETE FROM t1 WHERE a=3; 258 +} { 259 + OMIT 260 +} { SELECT * FROM t1 } {1 one 2 two} 261 + 262 +do_rebase_test 2.1.4 { 263 + DELETE FROM t1 WHERE a=1 264 +} { 265 + UPDATE t1 SET b='one.2' WHERE a=1 266 +} { 267 + OMIT 268 +} { SELECT * FROM t1 } {2 two 3 three} 269 + 270 +#do_rebase_test 2.1.5 { 271 +# DELETE FROM t1 WHERE a=1; 272 +#} { 273 +# UPDATE t1 SET b='one.2' WHERE a=1 274 +#} { 275 +# REPLACE 276 +#} { SELECT * FROM t1 } {2 two 3 three} 277 + 278 +do_rebase_test 2.1.6 { 279 + UPDATE t1 SET b='three.1' WHERE a=3 280 +} { 281 + DELETE FROM t1 WHERE a=3; 282 +} { 283 + OMIT 284 +} { SELECT * FROM t1 } {1 one 2 two 3 three.1} 285 + 286 +do_rebase_test 2.1.7 { 287 + UPDATE t1 SET b='three.1' WHERE a=3 288 +} { 289 + DELETE FROM t1 WHERE a=3; 290 +} { 291 + REPLACE 292 +} { SELECT * FROM t1 } {1 one 2 two} 293 + 294 +do_rebase_test 2.1.8 { 295 + INSERT INTO t1 VALUES(4, 'four.1') 296 +} { 297 + INSERT INTO t1 VALUES(4, 'four.2'); 298 +} { 299 + REPLACE 300 +} { SELECT * FROM t1 } {1 one 2 two 3 three 4 four.2} 301 + 302 +do_rebase_test 2.1.9 { 303 + INSERT INTO t1 VALUES(4, 'four.1') 304 +} { 305 + INSERT INTO t1 VALUES(4, 'four.2'); 306 +} { 307 + OMIT 308 +} { SELECT * FROM t1 } {1 one 2 two 3 three 4 four.1} 309 + 310 +do_execsql_test 2.2.0 { 311 + CREATE TABLE t2(x, y, z PRIMARY KEY); 312 + INSERT INTO t2 VALUES('i', 'a', 'A'); 313 + INSERT INTO t2 VALUES('ii', 'b', 'B'); 314 + INSERT INTO t2 VALUES('iii', 'c', 'C'); 315 + 316 + CREATE TABLE t3(a INTEGER PRIMARY KEY, b, c); 317 + INSERT INTO t3 VALUES(-1, 'z', 'Z'); 318 + INSERT INTO t3 VALUES(-2, 'y', 'Y'); 319 +} 320 + 321 +do_rebase_test 2.2.1 { 322 + UPDATE t2 SET x=1 WHERE z='A' 323 +} { 324 + UPDATE t2 SET y='one' WHERE z='A'; 325 +} { 326 +} { SELECT * FROM t2 WHERE z='A' } { 1 one A } 327 + 328 +do_rebase_test 2.2.2 { 329 + UPDATE t2 SET x=1, y='one' WHERE z='B' 330 +} { 331 + UPDATE t2 SET y='two' WHERE z='B'; 332 +} { 333 + REPLACE 334 +} { SELECT * FROM t2 WHERE z='B' } { 1 two B } 335 + 336 +do_rebase_test 2.2.3 { 337 + UPDATE t2 SET x=1, y='one' WHERE z='B' 338 +} { 339 + UPDATE t2 SET y='two' WHERE z='B'; 340 +} { 341 + OMIT 342 +} { SELECT * FROM t2 WHERE z='B' } { 1 one B } 343 + 344 +#------------------------------------------------------------------------- 345 +reset_db 346 +do_execsql_test 3.0 { 347 + CREATE TABLE t3(a, b, c, PRIMARY KEY(b, c)); 348 + CREATE TABLE abcdefghijkl(x PRIMARY KEY, y, z); 349 + 350 + INSERT INTO t3 VALUES(1, 2, 3); 351 + INSERT INTO t3 VALUES(4, 2, 5); 352 + INSERT INTO t3 VALUES(7, 2, 9); 353 + 354 + INSERT INTO abcdefghijkl VALUES('a', 'b', 'c'); 355 + INSERT INTO abcdefghijkl VALUES('d', 'e', 'f'); 356 + INSERT INTO abcdefghijkl VALUES('g', 'h', 'i'); 357 +} 358 + 359 +breakpoint 360 +# do_rebase_test 3.6.tn { 361 +# UPDATE abcdefghijkl SET z='X', y='X' WHERE x='d'; 362 +# } { 363 +# UPDATE abcdefghijkl SET y=1 WHERE x='d'; 364 +# UPDATE abcdefghijkl SET z=1 WHERE x='d'; 365 +# } [list REPLACE REPLACE REPLACE] 366 + 367 +foreach {tn p} { 368 + 1 OMIT 2 REPLACE 369 +} { 370 + do_rebase_test 3.1.$tn { 371 + INSERT INTO t3 VALUES(1, 1, 1); 372 + UPDATE abcdefghijkl SET y=2; 373 + } { 374 + INSERT INTO t3 VALUES(4, 1, 1); 375 + DELETE FROM abcdefghijkl; 376 + } [list $p $p $p $p $p $p $p $p] 377 + 378 + do_rebase_test 3.2.$tn { 379 + INSERT INTO abcdefghijkl SELECT * FROM t3; 380 + UPDATE t3 SET b=b+1; 381 + } { 382 + INSERT INTO t3 VALUES(3, 3, 3); 383 + INSERT INTO abcdefghijkl SELECT * FROM t3; 384 + } [list $p $p $p $p $p $p $p $p] 385 + 386 + do_rebase_test 3.3.$tn { 387 + INSERT INTO abcdefghijkl VALUES(22, 23, 24); 388 + } { 389 + INSERT INTO abcdefghijkl VALUES(22, 25, 26); 390 + UPDATE abcdefghijkl SET y=400 WHERE x=22; 391 + } [list $p $p $p $p $p $p $p $p] 392 + 393 + do_rebase_test 3.4.$tn { 394 + INSERT INTO abcdefghijkl VALUES(22, 23, 24); 395 + } { 396 + INSERT INTO abcdefghijkl VALUES(22, 25, 26); 397 + UPDATE abcdefghijkl SET y=400 WHERE x=22; 398 + } [list REPLACE $p] 399 + 400 + do_rebase_test 3.5.$tn* { 401 + UPDATE abcdefghijkl SET y='X' WHERE x='d'; 402 + } { 403 + DELETE FROM abcdefghijkl WHERE x='d'; 404 + INSERT INTO abcdefghijkl VALUES('d', NULL, NULL); 405 + } [list $p $p $p] 406 + do_rebase_test 3.5.$tn { 407 + UPDATE abcdefghijkl SET y='X' WHERE x='d'; 408 + } { 409 + DELETE FROM abcdefghijkl WHERE x='d'; 410 + INSERT INTO abcdefghijkl VALUES('d', NULL, NULL); 411 + } [list REPLACE $p $p] 412 + 413 + do_rebase_test 3.6.$tn { 414 + UPDATE abcdefghijkl SET z='X', y='X' WHERE x='d'; 415 + } { 416 + UPDATE abcdefghijkl SET y=1 WHERE x='d'; 417 + UPDATE abcdefghijkl SET z=1 WHERE x='d'; 418 + } [list REPLACE $p $p] 419 +} 420 + 421 +#------------------------------------------------------------------------- 422 +# Check that apply_v2() does not create a rebase buffer for a patchset. 423 +# And that it is not possible to rebase a patchset. 424 +# 425 +do_execsql_test 4.0 { 426 + CREATE TABLE t5(o PRIMARY KEY, p, q); 427 + INSERT INTO t5 VALUES(1, 2, 3); 428 + INSERT INTO t5 VALUES(4, 5, 6); 429 +} 430 +foreach {tn cmd rebasable} { 431 + 1 patchset 0 432 + 2 changeset 1 433 +} { 434 + proc xConflict {args} { return "OMIT" } 435 + do_test 4.1.$tn { 436 + execsql { 437 + BEGIN; 438 + DELETE FROM t5 WHERE o=4; 439 + } 440 + 441 + sqlite3session S db main 442 + S attach * 443 + execsql { 444 + INSERT INTO t5 VALUES(4, 'five', 'six'); 445 + } 446 + set P [S $cmd] 447 + S delete 448 + 449 + execsql ROLLBACK; 450 + 451 + set ::rebase [sqlite3changeset_apply_v2 db $P xConflict] 452 + expr [llength $::rebase]>0 453 + } $rebasable 454 +} 455 + 456 +foreach {tn cmd rebasable} { 457 + 1 patchset 0 458 + 2 changeset 1 459 +} { 460 + do_test 4.2.$tn { 461 + sqlite3session S db main 462 + S attach * 463 + execsql { 464 + INSERT INTO t5 VALUES(5+$tn, 'five', 'six'); 465 + } 466 + set P [S $cmd] 467 + S delete 468 + 469 + sqlite3rebaser_create R 470 + R configure $::rebase 471 + expr [catch {R rebase $P}]==0 472 + } $rebasable 473 + 474 + catch { R delete } 475 +} 476 +finish_test 477 +
Changes to ext/session/sqlite3session.c.
64 64 /* 65 65 ** An object of this type is used internally as an abstraction for 66 66 ** input data. Input data may be supplied either as a single large buffer 67 67 ** (e.g. sqlite3changeset_start()) or using a stream function (e.g. 68 68 ** sqlite3changeset_start_strm()). 69 69 */ 70 70 struct SessionInput { 71 - int bNoDiscard; /* If true, discard no data */ 71 + int bNoDiscard; /* If true, do not discard in InputBuffer() */ 72 72 int iCurrent; /* Offset in aData[] of current change */ 73 73 int iNext; /* Offset in aData[] of next change */ 74 74 u8 *aData; /* Pointer to buffer containing changeset */ 75 75 int nData; /* Number of bytes in aData */ 76 76 77 77 SessionBuffer buf; /* Current read buffer */ 78 78 int (*xInput)(void*, void*, int*); /* Input stream call (or NULL) */ ................................................................................ 228 228 ** 229 229 ** As in the changeset format, each field of the single record that is part 230 230 ** of a patchset change is associated with the correspondingly positioned 231 231 ** table column, counting from left to right within the CREATE TABLE 232 232 ** statement. 233 233 ** 234 234 ** For a DELETE change, all fields within the record except those associated 235 -** with PRIMARY KEY columns are set to "undefined". The PRIMARY KEY fields 236 -** contain the values identifying the row to delete. 235 +** with PRIMARY KEY columns are omitted. The PRIMARY KEY fields contain the 236 +** values identifying the row to delete. 237 237 ** 238 238 ** For an UPDATE change, all fields except those associated with PRIMARY KEY 239 239 ** columns and columns that are modified by the UPDATE are set to "undefined". 240 240 ** PRIMARY KEY fields contain the values identifying the table row to update, 241 241 ** and fields associated with modified columns contain the new column values. 242 242 ** 243 243 ** The records associated with INSERT changes are in the same format as for ................................................................................ 512 512 ** The buffer that the argument points to contains a serialized SQL value. 513 513 ** Return the number of bytes of space occupied by the value (including 514 514 ** the type byte). 515 515 */ 516 516 static int sessionSerialLen(u8 *a){ 517 517 int e = *a; 518 518 int n; 519 - if( e==0 ) return 1; 519 + if( e==0 || e==0xFF ) return 1; 520 520 if( e==SQLITE_NULL ) return 1; 521 521 if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; 522 522 return sessionVarintGet(&a[1], &n) + 1 + n; 523 523 } 524 524 525 525 /* 526 526 ** Based on the primary key values stored in change aRecord, calculate a ................................................................................ 592 592 int iCol; /* Used to iterate through table columns */ 593 593 594 594 for(iCol=0; iCol<pTab->nCol; iCol++){ 595 595 if( pTab->abPK[iCol] ){ 596 596 int n1 = sessionSerialLen(a1); 597 597 int n2 = sessionSerialLen(a2); 598 598 599 - if( pTab->abPK[iCol] && (n1!=n2 || memcmp(a1, a2, n1)) ){ 599 + if( n1!=n2 || memcmp(a1, a2, n1) ){ 600 600 return 0; 601 601 } 602 602 a1 += n1; 603 603 a2 += n2; 604 604 }else{ 605 605 if( bLeftPkOnly==0 ) a1 += sessionSerialLen(a1); 606 606 if( bRightPkOnly==0 ) a2 += sessionSerialLen(a2); ................................................................................ 835 835 a += sessionVarintGet(a, &n); 836 836 if( sqlite3_value_bytes(pVal)!=n ) return 0; 837 837 if( eType==SQLITE_TEXT ){ 838 838 z = sqlite3_value_text(pVal); 839 839 }else{ 840 840 z = sqlite3_value_blob(pVal); 841 841 } 842 - if( memcmp(a, z, n) ) return 0; 842 + if( n>0 && memcmp(a, z, n) ) return 0; 843 843 a += n; 844 844 } 845 845 } 846 846 } 847 847 848 848 return 1; 849 849 } ................................................................................ 2179 2179 int nSql = -1; 2180 2180 2181 2181 if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){ 2182 2182 zSql = sqlite3_mprintf( 2183 2183 "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND " 2184 2184 "idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb 2185 2185 ); 2186 + if( zSql==0 ) rc = SQLITE_NOMEM; 2186 2187 }else{ 2187 2188 int i; 2188 2189 const char *zSep = ""; 2189 2190 SessionBuffer buf = {0, 0, 0}; 2190 2191 2191 2192 sessionAppendStr(&buf, "SELECT * FROM ", &rc); 2192 2193 sessionAppendIdent(&buf, zDb, &rc); ................................................................................ 2588 2589 } 2589 2590 2590 2591 /* 2591 2592 ** If the SessionInput object passed as the only argument is a streaming 2592 2593 ** object and the buffer is full, discard some data to free up space. 2593 2594 */ 2594 2595 static void sessionDiscardData(SessionInput *pIn){ 2595 - if( pIn->bEof && pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){ 2596 + if( pIn->xInput && pIn->iNext>=SESSIONS_STRM_CHUNK_SIZE ){ 2596 2597 int nMove = pIn->buf.nBuf - pIn->iNext; 2597 2598 assert( nMove>=0 ); 2598 2599 if( nMove>0 ){ 2599 2600 memmove(pIn->buf.aBuf, &pIn->buf.aBuf[pIn->iNext], nMove); 2600 2601 } 2601 2602 pIn->buf.nBuf -= pIn->iNext; 2602 2603 pIn->iNext = 0; ................................................................................ 2914 2915 ** successfully advanced to the next change in the changeset, an SQLite 2915 2916 ** error code if an error occurs, or SQLITE_DONE if there are no further 2916 2917 ** changes in the changeset. 2917 2918 */ 2918 2919 static int sessionChangesetNext( 2919 2920 sqlite3_changeset_iter *p, /* Changeset iterator */ 2920 2921 u8 **paRec, /* If non-NULL, store record pointer here */ 2921 - int *pnRec /* If non-NULL, store size of record here */ 2922 + int *pnRec, /* If non-NULL, store size of record here */ 2923 + int *pbNew /* If non-NULL, true if new table */ 2922 2924 ){ 2923 2925 int i; 2924 2926 u8 op; 2925 2927 2926 2928 assert( (paRec==0 && pnRec==0) || (paRec && pnRec) ); 2927 2929 2928 2930 /* If the iterator is in the error-state, return immediately. */ ................................................................................ 2949 2951 } 2950 2952 2951 2953 sessionDiscardData(&p->in); 2952 2954 p->in.iCurrent = p->in.iNext; 2953 2955 2954 2956 op = p->in.aData[p->in.iNext++]; 2955 2957 while( op=='T' || op=='P' ){ 2958 + if( pbNew ) *pbNew = 1; 2956 2959 p->bPatchset = (op=='P'); 2957 2960 if( sessionChangesetReadTblhdr(p) ) return p->rc; 2958 2961 if( (p->rc = sessionInputBuffer(&p->in, 2)) ) return p->rc; 2959 2962 p->in.iCurrent = p->in.iNext; 2960 2963 if( p->in.iNext>=p->in.nData ) return SQLITE_DONE; 2961 2964 op = p->in.aData[p->in.iNext++]; 2962 2965 } ................................................................................ 3027 3030 ** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE 3028 3031 ** or SQLITE_CORRUPT. 3029 3032 ** 3030 3033 ** This function may not be called on iterators passed to a conflict handler 3031 3034 ** callback by changeset_apply(). 3032 3035 */ 3033 3036 int sqlite3changeset_next(sqlite3_changeset_iter *p){ 3034 - return sessionChangesetNext(p, 0, 0); 3037 + return sessionChangesetNext(p, 0, 0, 0); 3035 3038 } 3036 3039 3037 3040 /* 3038 3041 ** The following function extracts information on the current change 3039 3042 ** from a changeset iterator. It may only be called after changeset_next() 3040 3043 ** has returned SQLITE_ROW. 3041 3044 */ ................................................................................ 3406 3409 sqlite3_stmt *pSelect; /* SELECT statement */ 3407 3410 int nCol; /* Size of azCol[] and abPK[] arrays */ 3408 3411 const char **azCol; /* Array of column names */ 3409 3412 u8 *abPK; /* Boolean array - true if column is in PK */ 3410 3413 int bStat1; /* True if table is sqlite_stat1 */ 3411 3414 int bDeferConstraints; /* True to defer constraints */ 3412 3415 SessionBuffer constraints; /* Deferred constraints are stored here */ 3416 + SessionBuffer rebase; /* Rebase information (if any) here */ 3417 + int bRebaseStarted; /* If table header is already in rebase */ 3413 3418 }; 3414 3419 3415 3420 /* 3416 3421 ** Formulate a statement to DELETE a row from database db. Assuming a table 3417 3422 ** structure like this: 3418 3423 ** 3419 3424 ** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c)); ................................................................................ 3672 3677 if( rc==SQLITE_OK ){ 3673 3678 rc = sessionPrepare(db, &p->pDelete, 3674 3679 "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS " 3675 3680 "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END " 3676 3681 "AND (?4 OR stat IS ?3)" 3677 3682 ); 3678 3683 } 3679 - assert( rc==SQLITE_OK ); 3680 3684 return rc; 3681 3685 } 3682 3686 3683 3687 /* 3684 3688 ** A wrapper around sqlite3_bind_value() that detects an extra problem. 3685 3689 ** See comments in the body of this function for details. 3686 3690 */ ................................................................................ 3786 3790 if( rc==SQLITE_OK ){ 3787 3791 rc = sqlite3_step(pSelect); 3788 3792 if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect); 3789 3793 } 3790 3794 3791 3795 return rc; 3792 3796 } 3797 + 3798 +/* 3799 +** This function is called from within sqlite3changset_apply_v2() when 3800 +** a conflict is encountered and resolved using conflict resolution 3801 +** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE).. 3802 +** It adds a conflict resolution record to the buffer in 3803 +** SessionApplyCtx.rebase, which will eventually be returned to the caller 3804 +** of apply_v2() as the "rebase" buffer. 3805 +** 3806 +** Return SQLITE_OK if successful, or an SQLite error code otherwise. 3807 +*/ 3808 +static int sessionRebaseAdd( 3809 + SessionApplyCtx *p, /* Apply context */ 3810 + int eType, /* Conflict resolution (OMIT or REPLACE) */ 3811 + sqlite3_changeset_iter *pIter /* Iterator pointing at current change */ 3812 +){ 3813 + int rc = SQLITE_OK; 3814 + int i; 3815 + int eOp = pIter->op; 3816 + if( p->bRebaseStarted==0 ){ 3817 + /* Append a table-header to the rebase buffer */ 3818 + const char *zTab = pIter->zTab; 3819 + sessionAppendByte(&p->rebase, 'T', &rc); 3820 + sessionAppendVarint(&p->rebase, p->nCol, &rc); 3821 + sessionAppendBlob(&p->rebase, p->abPK, p->nCol, &rc); 3822 + sessionAppendBlob(&p->rebase, (u8*)zTab, (int)strlen(zTab)+1, &rc); 3823 + p->bRebaseStarted = 1; 3824 + } 3825 + 3826 + assert( eType==SQLITE_CHANGESET_REPLACE||eType==SQLITE_CHANGESET_OMIT ); 3827 + assert( eOp==SQLITE_DELETE || eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE ); 3828 + 3829 + sessionAppendByte(&p->rebase, 3830 + (eOp==SQLITE_DELETE ? SQLITE_DELETE : SQLITE_INSERT), &rc 3831 + ); 3832 + sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc); 3833 + for(i=0; i<p->nCol; i++){ 3834 + sqlite3_value *pVal = 0; 3835 + if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){ 3836 + sqlite3changeset_old(pIter, i, &pVal); 3837 + }else{ 3838 + sqlite3changeset_new(pIter, i, &pVal); 3839 + } 3840 + sessionAppendValue(&p->rebase, pVal, &rc); 3841 + } 3842 + 3843 + return rc; 3844 +} 3793 3845 3794 3846 /* 3795 3847 ** Invoke the conflict handler for the change that the changeset iterator 3796 3848 ** currently points to. 3797 3849 ** 3798 3850 ** Argument eType must be either CHANGESET_DATA or CHANGESET_CONFLICT. 3799 3851 ** If argument pbReplace is NULL, then the type of conflict handler invoked ................................................................................ 3862 3914 }else if( rc==SQLITE_OK ){ 3863 3915 if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){ 3864 3916 /* Instead of invoking the conflict handler, append the change blob 3865 3917 ** to the SessionApplyCtx.constraints buffer. */ 3866 3918 u8 *aBlob = &pIter->in.aData[pIter->in.iCurrent]; 3867 3919 int nBlob = pIter->in.iNext - pIter->in.iCurrent; 3868 3920 sessionAppendBlob(&p->constraints, aBlob, nBlob, &rc); 3869 - res = SQLITE_CHANGESET_OMIT; 3921 + return SQLITE_OK; 3870 3922 }else{ 3871 3923 /* No other row with the new.* primary key. */ 3872 3924 res = xConflict(pCtx, eType+1, pIter); 3873 3925 if( res==SQLITE_CHANGESET_REPLACE ) rc = SQLITE_MISUSE; 3874 3926 } 3875 3927 } 3876 3928 ................................................................................ 3888 3940 rc = SQLITE_ABORT; 3889 3941 break; 3890 3942 3891 3943 default: 3892 3944 rc = SQLITE_MISUSE; 3893 3945 break; 3894 3946 } 3947 + if( rc==SQLITE_OK ){ 3948 + rc = sessionRebaseAdd(p, res, pIter); 3949 + } 3895 3950 } 3896 3951 3897 3952 return rc; 3898 3953 } 3899 3954 3900 3955 /* 3901 3956 ** Attempt to apply the change that the iterator passed as the first argument ................................................................................ 4063 4118 void *pCtx /* First argument passed to xConflict */ 4064 4119 ){ 4065 4120 int bReplace = 0; 4066 4121 int bRetry = 0; 4067 4122 int rc; 4068 4123 4069 4124 rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, &bReplace, &bRetry); 4070 - assert( rc==SQLITE_OK || (bRetry==0 && bReplace==0) ); 4071 - 4072 - /* If the bRetry flag is set, the change has not been applied due to an 4073 - ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and 4074 - ** a row with the correct PK is present in the db, but one or more other 4075 - ** fields do not contain the expected values) and the conflict handler 4076 - ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation, 4077 - ** but pass NULL as the final argument so that sessionApplyOneOp() ignores 4078 - ** the SQLITE_CHANGESET_DATA problem. */ 4079 - if( bRetry ){ 4080 - assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE ); 4081 - rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); 4082 - } 4083 - 4084 - /* If the bReplace flag is set, the change is an INSERT that has not 4085 - ** been performed because the database already contains a row with the 4086 - ** specified primary key and the conflict handler returned 4087 - ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row 4088 - ** before reattempting the INSERT. */ 4089 - else if( bReplace ){ 4090 - assert( pIter->op==SQLITE_INSERT ); 4091 - rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); 4092 - if( rc==SQLITE_OK ){ 4093 - rc = sessionBindRow(pIter, 4094 - sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete); 4095 - sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1); 4096 - } 4097 - if( rc==SQLITE_OK ){ 4098 - sqlite3_step(pApply->pDelete); 4099 - rc = sqlite3_reset(pApply->pDelete); 4100 - } 4101 - if( rc==SQLITE_OK ){ 4125 + if( rc==SQLITE_OK ){ 4126 + /* If the bRetry flag is set, the change has not been applied due to an 4127 + ** SQLITE_CHANGESET_DATA problem (i.e. this is an UPDATE or DELETE and 4128 + ** a row with the correct PK is present in the db, but one or more other 4129 + ** fields do not contain the expected values) and the conflict handler 4130 + ** returned SQLITE_CHANGESET_REPLACE. In this case retry the operation, 4131 + ** but pass NULL as the final argument so that sessionApplyOneOp() ignores 4132 + ** the SQLITE_CHANGESET_DATA problem. */ 4133 + if( bRetry ){ 4134 + assert( pIter->op==SQLITE_UPDATE || pIter->op==SQLITE_DELETE ); 4102 4135 rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); 4103 4136 } 4104 - if( rc==SQLITE_OK ){ 4105 - rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0); 4137 + 4138 + /* If the bReplace flag is set, the change is an INSERT that has not 4139 + ** been performed because the database already contains a row with the 4140 + ** specified primary key and the conflict handler returned 4141 + ** SQLITE_CHANGESET_REPLACE. In this case remove the conflicting row 4142 + ** before reattempting the INSERT. */ 4143 + else if( bReplace ){ 4144 + assert( pIter->op==SQLITE_INSERT ); 4145 + rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); 4146 + if( rc==SQLITE_OK ){ 4147 + rc = sessionBindRow(pIter, 4148 + sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete); 4149 + sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1); 4150 + } 4151 + if( rc==SQLITE_OK ){ 4152 + sqlite3_step(pApply->pDelete); 4153 + rc = sqlite3_reset(pApply->pDelete); 4154 + } 4155 + if( rc==SQLITE_OK ){ 4156 + rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); 4157 + } 4158 + if( rc==SQLITE_OK ){ 4159 + rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0); 4160 + } 4106 4161 } 4107 4162 } 4108 4163 4109 4164 return rc; 4110 4165 } 4111 4166 4112 4167 /* ................................................................................ 4174 4229 const char *zTab /* Table name */ 4175 4230 ), 4176 4231 int(*xConflict)( 4177 4232 void *pCtx, /* Copy of fifth arg to _apply() */ 4178 4233 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ 4179 4234 sqlite3_changeset_iter *p /* Handle describing change and conflict */ 4180 4235 ), 4181 - void *pCtx /* First argument passed to xConflict */ 4236 + void *pCtx, /* First argument passed to xConflict */ 4237 + void **ppRebase, int *pnRebase, /* OUT: Rebase information */ 4238 + int flags /* SESSION_APPLY_XXX flags */ 4182 4239 ){ 4183 4240 int schemaMismatch = 0; 4184 - int rc; /* Return code */ 4241 + int rc = SQLITE_OK; /* Return code */ 4185 4242 const char *zTab = 0; /* Name of current table */ 4186 4243 int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ 4187 4244 SessionApplyCtx sApply; /* changeset_apply() context object */ 4188 4245 int bPatchset; 4189 4246 4190 4247 assert( xConflict!=0 ); 4191 4248 4192 4249 pIter->in.bNoDiscard = 1; 4193 4250 memset(&sApply, 0, sizeof(sApply)); 4194 4251 sqlite3_mutex_enter(sqlite3_db_mutex(db)); 4195 - rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); 4252 + if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ 4253 + rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); 4254 + } 4196 4255 if( rc==SQLITE_OK ){ 4197 4256 rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0); 4198 4257 } 4199 4258 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){ 4200 4259 int nCol; 4201 4260 int op; 4202 4261 const char *zNew; ................................................................................ 4212 4271 if( rc!=SQLITE_OK ) break; 4213 4272 4214 4273 sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ 4215 4274 sqlite3_finalize(sApply.pDelete); 4216 4275 sqlite3_finalize(sApply.pUpdate); 4217 4276 sqlite3_finalize(sApply.pInsert); 4218 4277 sqlite3_finalize(sApply.pSelect); 4219 - memset(&sApply, 0, sizeof(sApply)); 4220 4278 sApply.db = db; 4279 + sApply.pDelete = 0; 4280 + sApply.pUpdate = 0; 4281 + sApply.pInsert = 0; 4282 + sApply.pSelect = 0; 4283 + sApply.nCol = 0; 4284 + sApply.azCol = 0; 4285 + sApply.abPK = 0; 4286 + sApply.bStat1 = 0; 4221 4287 sApply.bDeferConstraints = 1; 4288 + sApply.bRebaseStarted = 0; 4289 + memset(&sApply.constraints, 0, sizeof(SessionBuffer)); 4222 4290 4223 4291 /* If an xFilter() callback was specified, invoke it now. If the 4224 4292 ** xFilter callback returns zero, skip this table. If it returns 4225 4293 ** non-zero, proceed. */ 4226 4294 schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew))); 4227 4295 if( schemaMismatch ){ 4228 4296 zTab = sqlite3_mprintf("%s", zNew); ................................................................................ 4317 4385 if( res!=SQLITE_CHANGESET_OMIT ){ 4318 4386 rc = SQLITE_CONSTRAINT; 4319 4387 } 4320 4388 } 4321 4389 } 4322 4390 sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0); 4323 4391 4324 - if( rc==SQLITE_OK ){ 4325 - rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); 4326 - }else{ 4327 - sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); 4328 - sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); 4392 + if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ 4393 + if( rc==SQLITE_OK ){ 4394 + rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); 4395 + }else{ 4396 + sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); 4397 + sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); 4398 + } 4329 4399 } 4330 4400 4401 + if( rc==SQLITE_OK && bPatchset==0 && ppRebase && pnRebase ){ 4402 + *ppRebase = (void*)sApply.rebase.aBuf; 4403 + *pnRebase = sApply.rebase.nBuf; 4404 + sApply.rebase.aBuf = 0; 4405 + } 4331 4406 sqlite3_finalize(sApply.pInsert); 4332 4407 sqlite3_finalize(sApply.pDelete); 4333 4408 sqlite3_finalize(sApply.pUpdate); 4334 4409 sqlite3_finalize(sApply.pSelect); 4335 4410 sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ 4336 4411 sqlite3_free((char*)sApply.constraints.aBuf); 4412 + sqlite3_free((char*)sApply.rebase.aBuf); 4337 4413 sqlite3_mutex_leave(sqlite3_db_mutex(db)); 4338 4414 return rc; 4339 4415 } 4416 + 4417 +/* 4418 +** Apply the changeset passed via pChangeset/nChangeset to the main 4419 +** database attached to handle "db". 4420 +*/ 4421 +int sqlite3changeset_apply_v2( 4422 + sqlite3 *db, /* Apply change to "main" db of this handle */ 4423 + int nChangeset, /* Size of changeset in bytes */ 4424 + void *pChangeset, /* Changeset blob */ 4425 + int(*xFilter)( 4426 + void *pCtx, /* Copy of sixth arg to _apply() */ 4427 + const char *zTab /* Table name */ 4428 + ), 4429 + int(*xConflict)( 4430 + void *pCtx, /* Copy of sixth arg to _apply() */ 4431 + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ 4432 + sqlite3_changeset_iter *p /* Handle describing change and conflict */ 4433 + ), 4434 + void *pCtx, /* First argument passed to xConflict */ 4435 + void **ppRebase, int *pnRebase, 4436 + int flags 4437 +){ 4438 + sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ 4439 + int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); 4440 + if( rc==SQLITE_OK ){ 4441 + rc = sessionChangesetApply( 4442 + db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags 4443 + ); 4444 + } 4445 + return rc; 4446 +} 4340 4447 4341 4448 /* 4342 4449 ** Apply the changeset passed via pChangeset/nChangeset to the main database 4343 4450 ** attached to handle "db". Invoke the supplied conflict handler callback 4344 4451 ** to resolve any conflicts encountered while applying the change. 4345 4452 */ 4346 4453 int sqlite3changeset_apply( ................................................................................ 4354 4461 int(*xConflict)( 4355 4462 void *pCtx, /* Copy of fifth arg to _apply() */ 4356 4463 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ 4357 4464 sqlite3_changeset_iter *p /* Handle describing change and conflict */ 4358 4465 ), 4359 4466 void *pCtx /* First argument passed to xConflict */ 4360 4467 ){ 4361 - sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ 4362 - int rc = sqlite3changeset_start(&pIter, nChangeset, pChangeset); 4363 - if( rc==SQLITE_OK ){ 4364 - rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx); 4365 - } 4366 - return rc; 4468 + return sqlite3changeset_apply_v2( 4469 + db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0, 0 4470 + ); 4367 4471 } 4368 4472 4369 4473 /* 4370 4474 ** Apply the changeset passed via xInput/pIn to the main database 4371 4475 ** attached to handle "db". Invoke the supplied conflict handler callback 4372 4476 ** to resolve any conflicts encountered while applying the change. 4373 4477 */ 4478 +int sqlite3changeset_apply_v2_strm( 4479 + sqlite3 *db, /* Apply change to "main" db of this handle */ 4480 + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ 4481 + void *pIn, /* First arg for xInput */ 4482 + int(*xFilter)( 4483 + void *pCtx, /* Copy of sixth arg to _apply() */ 4484 + const char *zTab /* Table name */ 4485 + ), 4486 + int(*xConflict)( 4487 + void *pCtx, /* Copy of sixth arg to _apply() */ 4488 + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ 4489 + sqlite3_changeset_iter *p /* Handle describing change and conflict */ 4490 + ), 4491 + void *pCtx, /* First argument passed to xConflict */ 4492 + void **ppRebase, int *pnRebase, 4493 + int flags 4494 +){ 4495 + sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ 4496 + int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); 4497 + if( rc==SQLITE_OK ){ 4498 + rc = sessionChangesetApply( 4499 + db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags 4500 + ); 4501 + } 4502 + return rc; 4503 +} 4374 4504 int sqlite3changeset_apply_strm( 4375 4505 sqlite3 *db, /* Apply change to "main" db of this handle */ 4376 4506 int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ 4377 4507 void *pIn, /* First arg for xInput */ 4378 4508 int(*xFilter)( 4379 4509 void *pCtx, /* Copy of sixth arg to _apply() */ 4380 4510 const char *zTab /* Table name */ ................................................................................ 4382 4512 int(*xConflict)( 4383 4513 void *pCtx, /* Copy of sixth arg to _apply() */ 4384 4514 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ 4385 4515 sqlite3_changeset_iter *p /* Handle describing change and conflict */ 4386 4516 ), 4387 4517 void *pCtx /* First argument passed to xConflict */ 4388 4518 ){ 4389 - sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ 4390 - int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); 4391 - if( rc==SQLITE_OK ){ 4392 - rc = sessionChangesetApply(db, pIter, xFilter, xConflict, pCtx); 4393 - } 4394 - return rc; 4519 + return sqlite3changeset_apply_v2_strm( 4520 + db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0, 0 4521 + ); 4395 4522 } 4396 4523 4397 4524 /* 4398 4525 ** sqlite3_changegroup handle. 4399 4526 */ 4400 4527 struct sqlite3_changegroup { 4401 4528 int rc; /* Error code */ ................................................................................ 4406 4533 /* 4407 4534 ** This function is called to merge two changes to the same row together as 4408 4535 ** part of an sqlite3changeset_concat() operation. A new change object is 4409 4536 ** allocated and a pointer to it stored in *ppNew. 4410 4537 */ 4411 4538 static int sessionChangeMerge( 4412 4539 SessionTable *pTab, /* Table structure */ 4540 + int bRebase, /* True for a rebase hash-table */ 4413 4541 int bPatchset, /* True for patchsets */ 4414 4542 SessionChange *pExist, /* Existing change */ 4415 4543 int op2, /* Second change operation */ 4416 4544 int bIndirect, /* True if second change is indirect */ 4417 4545 u8 *aRec, /* Second change record */ 4418 4546 int nRec, /* Number of bytes in aRec */ 4419 4547 SessionChange **ppNew /* OUT: Merged change */ 4420 4548 ){ 4421 4549 SessionChange *pNew = 0; 4550 + int rc = SQLITE_OK; 4422 4551 4423 4552 if( !pExist ){ 4424 4553 pNew = (SessionChange *)sqlite3_malloc(sizeof(SessionChange) + nRec); 4425 4554 if( !pNew ){ 4426 4555 return SQLITE_NOMEM; 4427 4556 } 4428 4557 memset(pNew, 0, sizeof(SessionChange)); 4429 4558 pNew->op = op2; 4430 4559 pNew->bIndirect = bIndirect; 4431 - pNew->nRecord = nRec; 4432 4560 pNew->aRecord = (u8*)&pNew[1]; 4433 - memcpy(pNew->aRecord, aRec, nRec); 4561 + if( bIndirect==0 || bRebase==0 ){ 4562 + pNew->nRecord = nRec; 4563 + memcpy(pNew->aRecord, aRec, nRec); 4564 + }else{ 4565 + int i; 4566 + u8 *pIn = aRec; 4567 + u8 *pOut = pNew->aRecord; 4568 + for(i=0; i<pTab->nCol; i++){ 4569 + int nIn = sessionSerialLen(pIn); 4570 + if( *pIn==0 ){ 4571 + *pOut++ = 0; 4572 + }else if( pTab->abPK[i]==0 ){ 4573 + *pOut++ = 0xFF; 4574 + }else{ 4575 + memcpy(pOut, pIn, nIn); 4576 + pOut += nIn; 4577 + } 4578 + pIn += nIn; 4579 + } 4580 + pNew->nRecord = pOut - pNew->aRecord; 4581 + } 4582 + }else if( bRebase ){ 4583 + if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){ 4584 + *ppNew = pExist; 4585 + }else{ 4586 + int nByte = nRec + pExist->nRecord + sizeof(SessionChange); 4587 + pNew = (SessionChange*)sqlite3_malloc(nByte); 4588 + if( pNew==0 ){ 4589 + rc = SQLITE_NOMEM; 4590 + }else{ 4591 + int i; 4592 + u8 *a1 = pExist->aRecord; 4593 + u8 *a2 = aRec; 4594 + u8 *pOut; 4595 + 4596 + memset(pNew, 0, nByte); 4597 + pNew->bIndirect = bIndirect || pExist->bIndirect; 4598 + pNew->op = op2; 4599 + pOut = pNew->aRecord = (u8*)&pNew[1]; 4600 + 4601 + for(i=0; i<pTab->nCol; i++){ 4602 + int n1 = sessionSerialLen(a1); 4603 + int n2 = sessionSerialLen(a2); 4604 + if( *a1==0xFF || (pTab->abPK[i]==0 && bIndirect) ){ 4605 + *pOut++ = 0xFF; 4606 + }else if( *a2==0 ){ 4607 + memcpy(pOut, a1, n1); 4608 + pOut += n1; 4609 + }else{ 4610 + memcpy(pOut, a2, n2); 4611 + pOut += n2; 4612 + } 4613 + a1 += n1; 4614 + a2 += n2; 4615 + } 4616 + pNew->nRecord = pOut - pNew->aRecord; 4617 + } 4618 + sqlite3_free(pExist); 4619 + } 4434 4620 }else{ 4435 4621 int op1 = pExist->op; 4436 4622 4437 4623 /* 4438 4624 ** op1=INSERT, op2=INSERT -> Unsupported. Discard op2. 4439 4625 ** op1=INSERT, op2=UPDATE -> INSERT. 4440 4626 ** op1=INSERT, op2=DELETE -> (none) ................................................................................ 4520 4706 pNew->nRecord = (int)(aCsr - pNew->aRecord); 4521 4707 } 4522 4708 sqlite3_free(pExist); 4523 4709 } 4524 4710 } 4525 4711 4526 4712 *ppNew = pNew; 4527 - return SQLITE_OK; 4713 + return rc; 4528 4714 } 4529 4715 4530 4716 /* 4531 4717 ** Add all changes in the changeset traversed by the iterator passed as 4532 4718 ** the first argument to the changegroup hash tables. 4533 4719 */ 4534 4720 static int sessionChangesetToHash( 4535 4721 sqlite3_changeset_iter *pIter, /* Iterator to read from */ 4536 - sqlite3_changegroup *pGrp /* Changegroup object to add changeset to */ 4722 + sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ 4723 + int bRebase /* True if hash table is for rebasing */ 4537 4724 ){ 4538 4725 u8 *aRec; 4539 4726 int nRec; 4540 4727 int rc = SQLITE_OK; 4541 4728 SessionTable *pTab = 0; 4542 4729 4543 - 4544 - while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec) ){ 4730 + while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){ 4545 4731 const char *zNew; 4546 4732 int nCol; 4547 4733 int op; 4548 4734 int iHash; 4549 4735 int bIndirect; 4550 4736 SessionChange *pChange; 4551 4737 SessionChange *pExist = 0; ................................................................................ 4617 4803 pExist = *pp; 4618 4804 *pp = (*pp)->pNext; 4619 4805 pTab->nEntry--; 4620 4806 break; 4621 4807 } 4622 4808 } 4623 4809 4624 - rc = sessionChangeMerge(pTab, 4810 + rc = sessionChangeMerge(pTab, bRebase, 4625 4811 pIter->bPatchset, pExist, op, bIndirect, aRec, nRec, &pChange 4626 4812 ); 4627 4813 if( rc ) break; 4628 4814 if( pChange ){ 4629 4815 pChange->pNext = pTab->apChange[iHash]; 4630 4816 pTab->apChange[iHash] = pChange; 4631 4817 pTab->nEntry++; ................................................................................ 4725 4911 */ 4726 4912 int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){ 4727 4913 sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */ 4728 4914 int rc; /* Return code */ 4729 4915 4730 4916 rc = sqlite3changeset_start(&pIter, nData, pData); 4731 4917 if( rc==SQLITE_OK ){ 4732 - rc = sessionChangesetToHash(pIter, pGrp); 4918 + rc = sessionChangesetToHash(pIter, pGrp, 0); 4733 4919 } 4734 4920 sqlite3changeset_finalize(pIter); 4735 4921 return rc; 4736 4922 } 4737 4923 4738 4924 /* 4739 4925 ** Obtain a buffer containing a changeset representing the concatenation ................................................................................ 4756 4942 void *pIn 4757 4943 ){ 4758 4944 sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */ 4759 4945 int rc; /* Return code */ 4760 4946 4761 4947 rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); 4762 4948 if( rc==SQLITE_OK ){ 4763 - rc = sessionChangesetToHash(pIter, pGrp); 4949 + rc = sessionChangesetToHash(pIter, pGrp, 0); 4764 4950 } 4765 4951 sqlite3changeset_finalize(pIter); 4766 4952 return rc; 4767 4953 } 4768 4954 4769 4955 /* 4770 4956 ** Streaming versions of changegroup_output(). ................................................................................ 4840 5026 if( rc==SQLITE_OK ){ 4841 5027 rc = sqlite3changegroup_output_strm(pGrp, xOutput, pOut); 4842 5028 } 4843 5029 sqlite3changegroup_delete(pGrp); 4844 5030 4845 5031 return rc; 4846 5032 } 5033 + 5034 +/* 5035 +** Changeset rebaser handle. 5036 +*/ 5037 +struct sqlite3_rebaser { 5038 + sqlite3_changegroup grp; /* Hash table */ 5039 +}; 5040 + 5041 +/* 5042 +** Buffers a1 and a2 must both contain a sessions module record nCol 5043 +** fields in size. This function appends an nCol sessions module 5044 +** record to buffer pBuf that is a copy of a1, except that for 5045 +** each field that is undefined in a1[], swap in the field from a2[]. 5046 +*/ 5047 +static void sessionAppendRecordMerge( 5048 + SessionBuffer *pBuf, /* Buffer to append to */ 5049 + int nCol, /* Number of columns in each record */ 5050 + u8 *a1, int n1, /* Record 1 */ 5051 + u8 *a2, int n2, /* Record 2 */ 5052 + int *pRc /* IN/OUT: error code */ 5053 +){ 5054 + sessionBufferGrow(pBuf, n1+n2, pRc); 5055 + if( *pRc==SQLITE_OK ){ 5056 + int i; 5057 + u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; 5058 + for(i=0; i<nCol; i++){ 5059 + int nn1 = sessionSerialLen(a1); 5060 + int nn2 = sessionSerialLen(a2); 5061 + if( *a1==0 || *a1==0xFF ){ 5062 + memcpy(pOut, a2, nn2); 5063 + pOut += nn2; 5064 + }else{ 5065 + memcpy(pOut, a1, nn1); 5066 + pOut += nn1; 5067 + } 5068 + a1 += nn1; 5069 + a2 += nn2; 5070 + } 5071 + 5072 + pBuf->nBuf = pOut-pBuf->aBuf; 5073 + assert( pBuf->nBuf<=pBuf->nAlloc ); 5074 + } 5075 +} 5076 + 5077 +/* 5078 +** This function is called when rebasing a local UPDATE change against one 5079 +** or more remote UPDATE changes. The aRec/nRec buffer contains the current 5080 +** old.* and new.* records for the change. The rebase buffer (a single 5081 +** record) is in aChange/nChange. The rebased change is appended to buffer 5082 +** pBuf. 5083 +** 5084 +** Rebasing the UPDATE involves: 5085 +** 5086 +** * Removing any changes to fields for which the corresponding field 5087 +** in the rebase buffer is set to "replaced" (type 0xFF). If this 5088 +** means the UPDATE change updates no fields, nothing is appended 5089 +** to the output buffer. 5090 +** 5091 +** * For each field modified by the local change for which the 5092 +** corresponding field in the rebase buffer is not "undefined" (0x00) 5093 +** or "replaced" (0xFF), the old.* value is replaced by the value 5094 +** in the rebase buffer. 5095 +*/ 5096 +static void sessionAppendPartialUpdate( 5097 + SessionBuffer *pBuf, /* Append record here */ 5098 + sqlite3_changeset_iter *pIter, /* Iterator pointed at local change */ 5099 + u8 *aRec, int nRec, /* Local change */ 5100 + u8 *aChange, int nChange, /* Record to rebase against */ 5101 + int *pRc /* IN/OUT: Return Code */ 5102 +){ 5103 + sessionBufferGrow(pBuf, 2+nRec+nChange, pRc); 5104 + if( *pRc==SQLITE_OK ){ 5105 + int bData = 0; 5106 + u8 *pOut = &pBuf->aBuf[pBuf->nBuf]; 5107 + int i; 5108 + u8 *a1 = aRec; 5109 + u8 *a2 = aChange; 5110 + 5111 + *pOut++ = SQLITE_UPDATE; 5112 + *pOut++ = pIter->bIndirect; 5113 + for(i=0; i<pIter->nCol; i++){ 5114 + int n1 = sessionSerialLen(a1); 5115 + int n2 = sessionSerialLen(a2); 5116 + if( pIter->abPK[i] || a2[0]==0 ){ 5117 + if( !pIter->abPK[i] ) bData = 1; 5118 + memcpy(pOut, a1, n1); 5119 + pOut += n1; 5120 + }else if( a2[0]!=0xFF ){ 5121 + bData = 1; 5122 + memcpy(pOut, a2, n2); 5123 + pOut += n2; 5124 + }else{ 5125 + *pOut++ = '\0'; 5126 + } 5127 + a1 += n1; 5128 + a2 += n2; 5129 + } 5130 + if( bData ){ 5131 + a2 = aChange; 5132 + for(i=0; i<pIter->nCol; i++){ 5133 + int n1 = sessionSerialLen(a1); 5134 + int n2 = sessionSerialLen(a2); 5135 + if( pIter->abPK[i] || a2[0]!=0xFF ){ 5136 + memcpy(pOut, a1, n1); 5137 + pOut += n1; 5138 + }else{ 5139 + *pOut++ = '\0'; 5140 + } 5141 + a1 += n1; 5142 + a2 += n2; 5143 + } 5144 + pBuf->nBuf = (pOut - pBuf->aBuf); 5145 + } 5146 + } 5147 +} 5148 + 5149 +/* 5150 +** pIter is configured to iterate through a changeset. This function rebases 5151 +** that changeset according to the current configuration of the rebaser 5152 +** object passed as the first argument. If no error occurs and argument xOutput 5153 +** is not NULL, then the changeset is returned to the caller by invoking 5154 +** xOutput zero or more times and SQLITE_OK returned. Or, if xOutput is NULL, 5155 +** then (*ppOut) is set to point to a buffer containing the rebased changeset 5156 +** before this function returns. In this case (*pnOut) is set to the size of 5157 +** the buffer in bytes. It is the responsibility of the caller to eventually 5158 +** free the (*ppOut) buffer using sqlite3_free(). 5159 +** 5160 +** If an error occurs, an SQLite error code is returned. If ppOut and 5161 +** pnOut are not NULL, then the two output parameters are set to 0 before 5162 +** returning. 5163 +*/ 5164 +static int sessionRebase( 5165 + sqlite3_rebaser *p, /* Rebaser hash table */ 5166 + sqlite3_changeset_iter *pIter, /* Input data */ 5167 + int (*xOutput)(void *pOut, const void *pData, int nData), 5168 + void *pOut, /* Context for xOutput callback */ 5169 + int *pnOut, /* OUT: Number of bytes in output changeset */ 5170 + void **ppOut /* OUT: Inverse of pChangeset */ 5171 +){ 5172 + int rc = SQLITE_OK; 5173 + u8 *aRec = 0; 5174 + int nRec = 0; 5175 + int bNew = 0; 5176 + SessionTable *pTab = 0; 5177 + SessionBuffer sOut = {0,0,0}; 5178 + 5179 + while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, &bNew) ){ 5180 + SessionChange *pChange = 0; 5181 + int bDone = 0; 5182 + 5183 + if( bNew ){ 5184 + const char *zTab = pIter->zTab; 5185 + for(pTab=p->grp.pList; pTab; pTab=pTab->pNext){ 5186 + if( 0==sqlite3_stricmp(pTab->zName, zTab) ) break; 5187 + } 5188 + bNew = 0; 5189 + 5190 + /* A patchset may not be rebased */ 5191 + if( pIter->bPatchset ){ 5192 + rc = SQLITE_ERROR; 5193 + } 5194 + 5195 + /* Append a table header to the output for this new table */ 5196 + sessionAppendByte(&sOut, pIter->bPatchset ? 'P' : 'T', &rc); 5197 + sessionAppendVarint(&sOut, pIter->nCol, &rc); 5198 + sessionAppendBlob(&sOut, pIter->abPK, pIter->nCol, &rc); 5199 + sessionAppendBlob(&sOut,(u8*)pIter->zTab,(int)strlen(pIter->zTab)+1,&rc); 5200 + } 5201 + 5202 + if( pTab && rc==SQLITE_OK ){ 5203 + int iHash = sessionChangeHash(pTab, 0, aRec, pTab->nChange); 5204 + 5205 + for(pChange=pTab->apChange[iHash]; pChange; pChange=pChange->pNext){ 5206 + if( sessionChangeEqual(pTab, 0, aRec, 0, pChange->aRecord) ){ 5207 + break; 5208 + } 5209 + } 5210 + } 5211 + 5212 + if( pChange ){ 5213 + assert( pChange->op==SQLITE_DELETE || pChange->op==SQLITE_INSERT ); 5214 + switch( pIter->op ){ 5215 + case SQLITE_INSERT: 5216 + if( pChange->op==SQLITE_INSERT ){ 5217 + bDone = 1; 5218 + if( pChange->bIndirect==0 ){ 5219 + sessionAppendByte(&sOut, SQLITE_UPDATE, &rc); 5220 + sessionAppendByte(&sOut, pIter->bIndirect, &rc); 5221 + sessionAppendBlob(&sOut, pChange->aRecord, pChange->nRecord, &rc); 5222 + sessionAppendBlob(&sOut, aRec, nRec, &rc); 5223 + } 5224 + } 5225 + break; 5226 + 5227 + case SQLITE_UPDATE: 5228 + bDone = 1; 5229 + if( pChange->op==SQLITE_DELETE ){ 5230 + if( pChange->bIndirect==0 ){ 5231 + u8 *pCsr = aRec; 5232 + sessionSkipRecord(&pCsr, pIter->nCol); 5233 + sessionAppendByte(&sOut, SQLITE_INSERT, &rc); 5234 + sessionAppendByte(&sOut, pIter->bIndirect, &rc); 5235 + sessionAppendRecordMerge(&sOut, pIter->nCol, 5236 + pCsr, nRec-(pCsr-aRec), 5237 + pChange->aRecord, pChange->nRecord, &rc 5238 + ); 5239 + } 5240 + }else{ 5241 + sessionAppendPartialUpdate(&sOut, pIter, 5242 + aRec, nRec, pChange->aRecord, pChange->nRecord, &rc 5243 + ); 5244 + } 5245 + break; 5246 + 5247 + default: 5248 + assert( pIter->op==SQLITE_DELETE ); 5249 + bDone = 1; 5250 + if( pChange->op==SQLITE_INSERT ){ 5251 + sessionAppendByte(&sOut, SQLITE_DELETE, &rc); 5252 + sessionAppendByte(&sOut, pIter->bIndirect, &rc); 5253 + sessionAppendRecordMerge(&sOut, pIter->nCol, 5254 + pChange->aRecord, pChange->nRecord, aRec, nRec, &rc 5255 + ); 5256 + } 5257 + break; 5258 + } 5259 + } 5260 + 5261 + if( bDone==0 ){ 5262 + sessionAppendByte(&sOut, pIter->op, &rc); 5263 + sessionAppendByte(&sOut, pIter->bIndirect, &rc); 5264 + sessionAppendBlob(&sOut, aRec, nRec, &rc); 5265 + } 5266 + if( rc==SQLITE_OK && xOutput && sOut.nBuf>SESSIONS_STRM_CHUNK_SIZE ){ 5267 + rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); 5268 + sOut.nBuf = 0; 5269 + } 5270 + if( rc ) break; 5271 + } 5272 + 5273 + if( rc!=SQLITE_OK ){ 5274 + sqlite3_free(sOut.aBuf); 5275 + memset(&sOut, 0, sizeof(sOut)); 5276 + } 5277 + 5278 + if( rc==SQLITE_OK ){ 5279 + if( xOutput ){ 5280 + if( sOut.nBuf>0 ){ 5281 + rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); 5282 + } 5283 + }else{ 5284 + *ppOut = (void*)sOut.aBuf; 5285 + *pnOut = sOut.nBuf; 5286 + sOut.aBuf = 0; 5287 + } 5288 + } 5289 + sqlite3_free(sOut.aBuf); 5290 + return rc; 5291 +} 5292 + 5293 +/* 5294 +** Create a new rebaser object. 5295 +*/ 5296 +int sqlite3rebaser_create(sqlite3_rebaser **ppNew){ 5297 + int rc = SQLITE_OK; 5298 + sqlite3_rebaser *pNew; 5299 + 5300 + pNew = sqlite3_malloc(sizeof(sqlite3_rebaser)); 5301 + if( pNew==0 ){ 5302 + rc = SQLITE_NOMEM; 5303 + }else{ 5304 + memset(pNew, 0, sizeof(sqlite3_rebaser)); 5305 + } 5306 + *ppNew = pNew; 5307 + return rc; 5308 +} 5309 + 5310 +/* 5311 +** Call this one or more times to configure a rebaser. 5312 +*/ 5313 +int sqlite3rebaser_configure( 5314 + sqlite3_rebaser *p, 5315 + int nRebase, const void *pRebase 5316 +){ 5317 + sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */ 5318 + int rc; /* Return code */ 5319 + rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase); 5320 + if( rc==SQLITE_OK ){ 5321 + rc = sessionChangesetToHash(pIter, &p->grp, 1); 5322 + } 5323 + sqlite3changeset_finalize(pIter); 5324 + return rc; 5325 +} 5326 + 5327 +/* 5328 +** Rebase a changeset according to current rebaser configuration 5329 +*/ 5330 +int sqlite3rebaser_rebase( 5331 + sqlite3_rebaser *p, 5332 + int nIn, const void *pIn, 5333 + int *pnOut, void **ppOut 5334 +){ 5335 + sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */ 5336 + int rc = sqlite3changeset_start(&pIter, nIn, (void*)pIn); 5337 + 5338 + if( rc==SQLITE_OK ){ 5339 + rc = sessionRebase(p, pIter, 0, 0, pnOut, ppOut); 5340 + sqlite3changeset_finalize(pIter); 5341 + } 5342 + 5343 + return rc; 5344 +} 5345 + 5346 +/* 5347 +** Rebase a changeset according to current rebaser configuration 5348 +*/ 5349 +int sqlite3rebaser_rebase_strm( 5350 + sqlite3_rebaser *p, 5351 + int (*xInput)(void *pIn, void *pData, int *pnData), 5352 + void *pIn, 5353 + int (*xOutput)(void *pOut, const void *pData, int nData), 5354 + void *pOut 5355 +){ 5356 + sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */ 5357 + int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); 5358 + 5359 + if( rc==SQLITE_OK ){ 5360 + rc = sessionRebase(p, pIter, xOutput, pOut, 0, 0); 5361 + sqlite3changeset_finalize(pIter); 5362 + } 5363 + 5364 + return rc; 5365 +} 5366 + 5367 +/* 5368 +** Destroy a rebaser object 5369 +*/ 5370 +void sqlite3rebaser_delete(sqlite3_rebaser *p){ 5371 + if( p ){ 5372 + sessionDeleteTable(p->grp.pList); 5373 + sqlite3_free(p); 5374 + } 5375 +} 4847 5376 4848 5377 #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */
Changes to ext/session/sqlite3session.h.
944 944 ** DESTRUCTOR: sqlite3_changegroup 945 945 */ 946 946 void sqlite3changegroup_delete(sqlite3_changegroup*); 947 947 948 948 /* 949 949 ** CAPI3REF: Apply A Changeset To A Database 950 950 ** 951 -** Apply a changeset to a database. This function attempts to update the 952 -** "main" database attached to handle db with the changes found in the 953 -** changeset passed via the second and third arguments. 951 +** Apply a changeset or patchset to a database. These functions attempt to 952 +** update the "main" database attached to handle db with the changes found in 953 +** the changeset passed via the second and third arguments. 954 954 ** 955 -** The fourth argument (xFilter) passed to this function is the "filter 955 +** The fourth argument (xFilter) passed to these functions is the "filter 956 956 ** callback". If it is not NULL, then for each table affected by at least one 957 957 ** change in the changeset, the filter callback is invoked with 958 958 ** the table name as the second argument, and a copy of the context pointer 959 -** passed as the sixth argument to this function as the first. If the "filter 960 -** callback" returns zero, then no attempt is made to apply any changes to 961 -** the table. Otherwise, if the return value is non-zero or the xFilter 962 -** argument to this function is NULL, all changes related to the table are 963 -** attempted. 959 +** passed as the sixth argument as the first. If the "filter callback" 960 +** returns zero, then no attempt is made to apply any changes to the table. 961 +** Otherwise, if the return value is non-zero or the xFilter argument to 962 +** is NULL, all changes related to the table are attempted. 964 963 ** 965 964 ** For each table that is not excluded by the filter callback, this function 966 965 ** tests that the target database contains a compatible table. A table is 967 966 ** considered compatible if all of the following are true: 968 967 ** 969 968 ** <ul> 970 969 ** <li> The table has the same name as the name recorded in the ................................................................................ 1001 1000 ** actions are taken by sqlite3changeset_apply() depending on the value 1002 1001 ** returned by each invocation of the conflict-handler function. Refer to 1003 1002 ** the documentation for the three 1004 1003 ** [SQLITE_CHANGESET_OMIT|available return values] for details. 1005 1004 ** 1006 1005 ** <dl> 1007 1006 ** <dt>DELETE Changes<dd> 1008 -** For each DELETE change, this function checks if the target database 1007 +** For each DELETE change, the function checks if the target database 1009 1008 ** contains a row with the same primary key value (or values) as the 1010 1009 ** original row values stored in the changeset. If it does, and the values 1011 1010 ** stored in all non-primary key columns also match the values stored in 1012 1011 ** the changeset the row is deleted from the target database. 1013 1012 ** 1014 1013 ** If a row with matching primary key values is found, but one or more of 1015 1014 ** the non-primary key fields contains a value different from the original ................................................................................ 1046 1045 ** violation (e.g. NOT NULL or UNIQUE), the conflict handler function is 1047 1046 ** invoked with the second argument set to [SQLITE_CHANGESET_CONSTRAINT]. 1048 1047 ** This includes the case where the INSERT operation is re-attempted because 1049 1048 ** an earlier call to the conflict handler function returned 1050 1049 ** [SQLITE_CHANGESET_REPLACE]. 1051 1050 ** 1052 1051 ** <dt>UPDATE Changes<dd> 1053 -** For each UPDATE change, this function checks if the target database 1052 +** For each UPDATE change, the function checks if the target database 1054 1053 ** contains a row with the same primary key value (or values) as the 1055 1054 ** original row values stored in the changeset. If it does, and the values 1056 1055 ** stored in all modified non-primary key columns also match the values 1057 1056 ** stored in the changeset the row is updated within the target database. 1058 1057 ** 1059 1058 ** If a row with matching primary key values is found, but one or more of 1060 1059 ** the modified non-primary key fields contains a value different from an ................................................................................ 1077 1076 ** </dl> 1078 1077 ** 1079 1078 ** It is safe to execute SQL statements, including those that write to the 1080 1079 ** table that the callback related to, from within the xConflict callback. 1081 1080 ** This can be used to further customize the applications conflict 1082 1081 ** resolution strategy. 1083 1082 ** 1084 -** All changes made by this function are enclosed in a savepoint transaction. 1083 +** All changes made by these functions are enclosed in a savepoint transaction. 1085 1084 ** If any other error (aside from a constraint failure when attempting to 1086 1085 ** write to the target database) occurs, then the savepoint transaction is 1087 1086 ** rolled back, restoring the target database to its original state, and an 1088 1087 ** SQLite error code returned. 1088 +** 1089 +** If the output parameters (ppRebase) and (pnRebase) are non-NULL and 1090 +** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2() 1091 +** may set (*ppRebase) to point to a "rebase" that may be used with the 1092 +** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase) 1093 +** is set to the size of the buffer in bytes. It is the responsibility of the 1094 +** caller to eventually free any such buffer using sqlite3_free(). The buffer 1095 +** is only allocated and populated if one or more conflicts were encountered 1096 +** while applying the patchset. See comments surrounding the sqlite3_rebaser 1097 +** APIs for further details. 1098 +** 1099 +** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent 1100 +** may be modified by passing a combination of 1101 +** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter. 1102 +** 1103 +** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b> 1104 +** and therefore subject to change. 1089 1105 */ 1090 1106 int sqlite3changeset_apply( 1091 1107 sqlite3 *db, /* Apply change to "main" db of this handle */ 1092 1108 int nChangeset, /* Size of changeset in bytes */ 1093 1109 void *pChangeset, /* Changeset blob */ 1094 1110 int(*xFilter)( 1095 1111 void *pCtx, /* Copy of sixth arg to _apply() */ ................................................................................ 1098 1114 int(*xConflict)( 1099 1115 void *pCtx, /* Copy of sixth arg to _apply() */ 1100 1116 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ 1101 1117 sqlite3_changeset_iter *p /* Handle describing change and conflict */ 1102 1118 ), 1103 1119 void *pCtx /* First argument passed to xConflict */ 1104 1120 ); 1121 +int sqlite3changeset_apply_v2( 1122 + sqlite3 *db, /* Apply change to "main" db of this handle */ 1123 + int nChangeset, /* Size of changeset in bytes */ 1124 + void *pChangeset, /* Changeset blob */ 1125 + int(*xFilter)( 1126 + void *pCtx, /* Copy of sixth arg to _apply() */ 1127 + const char *zTab /* Table name */ 1128 + ), 1129 + int(*xConflict)( 1130 + void *pCtx, /* Copy of sixth arg to _apply() */ 1131 + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ 1132 + sqlite3_changeset_iter *p /* Handle describing change and conflict */ 1133 + ), 1134 + void *pCtx, /* First argument passed to xConflict */ 1135 + void **ppRebase, int *pnRebase, /* OUT: Rebase data */ 1136 + int flags /* Combination of SESSION_APPLY_* flags */ 1137 +); 1138 + 1139 +/* 1140 +** CAPI3REF: Flags for sqlite3changeset_apply_v2 1141 +** 1142 +** The following flags may passed via the 9th parameter to 1143 +** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]: 1144 +** 1145 +** <dl> 1146 +** <dt>SQLITE_CHANGESETAPPLY_NOSAVEPOINT <dd> 1147 +** Usually, the sessions module encloses all operations performed by 1148 +** a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The 1149 +** SAVEPOINT is committed if the changeset or patchset is successfully 1150 +** applied, or rolled back if an error occurs. Specifying this flag 1151 +** causes the sessions module to omit this savepoint. In this case, if the 1152 +** caller has an open transaction or savepoint when apply_v2() is called, 1153 +** it may revert the partially applied changeset by rolling it back. 1154 +*/ 1155 +#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 1105 1156 1106 1157 /* 1107 1158 ** CAPI3REF: Constants Passed To The Conflict Handler 1108 1159 ** 1109 1160 ** Values that may be passed as the second argument to a conflict-handler. 1110 1161 ** 1111 1162 ** <dl> ................................................................................ 1195 1246 ** and the call to sqlite3changeset_apply() returns SQLITE_ABORT. 1196 1247 ** </dl> 1197 1248 */ 1198 1249 #define SQLITE_CHANGESET_OMIT 0 1199 1250 #define SQLITE_CHANGESET_REPLACE 1 1200 1251 #define SQLITE_CHANGESET_ABORT 2 1201 1252 1253 +/* 1254 +** CAPI3REF: Rebasing changesets 1255 +** EXPERIMENTAL 1256 +** 1257 +** Suppose there is a site hosting a database in state S0. And that 1258 +** modifications are made that move that database to state S1 and a 1259 +** changeset recorded (the "local" changeset). Then, a changeset based 1260 +** on S0 is received from another site (the "remote" changeset) and 1261 +** applied to the database. The database is then in state 1262 +** (S1+"remote"), where the exact state depends on any conflict 1263 +** resolution decisions (OMIT or REPLACE) made while applying "remote". 1264 +** Rebasing a changeset is to update it to take those conflict 1265 +** resolution decisions into account, so that the same conflicts 1266 +** do not have to be resolved elsewhere in the network. 1267 +** 1268 +** For example, if both the local and remote changesets contain an 1269 +** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)": 1270 +** 1271 +** local: INSERT INTO t1 VALUES(1, 'v1'); 1272 +** remote: INSERT INTO t1 VALUES(1, 'v2'); 1273 +** 1274 +** and the conflict resolution is REPLACE, then the INSERT change is 1275 +** removed from the local changeset (it was overridden). Or, if the 1276 +** conflict resolution was "OMIT", then the local changeset is modified 1277 +** to instead contain: 1278 +** 1279 +** UPDATE t1 SET b = 'v2' WHERE a=1; 1280 +** 1281 +** Changes within the local changeset are rebased as follows: 1282 +** 1283 +** <dl> 1284 +** <dt>Local INSERT<dd> 1285 +** This may only conflict with a remote INSERT. If the conflict 1286 +** resolution was OMIT, then add an UPDATE change to the rebased 1287 +** changeset. Or, if the conflict resolution was REPLACE, add 1288 +** nothing to the rebased changeset. 1289 +** 1290 +** <dt>Local DELETE<dd> 1291 +** This may conflict with a remote UPDATE or DELETE. In both cases the 1292 +** only possible resolution is OMIT. If the remote operation was a 1293 +** DELETE, then add no change to the rebased changeset. If the remote 1294 +** operation was an UPDATE, then the old.* fields of change are updated 1295 +** to reflect the new.* values in the UPDATE. 1296 +** 1297 +** <dt>Local UPDATE<dd> 1298 +** This may conflict with a remote UPDATE or DELETE. If it conflicts 1299 +** with a DELETE, and the conflict resolution was OMIT, then the update 1300 +** is changed into an INSERT. Any undefined values in the new.* record 1301 +** from the update change are filled in using the old.* values from 1302 +** the conflicting DELETE. Or, if the conflict resolution was REPLACE, 1303 +** the UPDATE change is simply omitted from the rebased changeset. 1304 +** 1305 +** If conflict is with a remote UPDATE and the resolution is OMIT, then 1306 +** the old.* values are rebased using the new.* values in the remote 1307 +** change. Or, if the resolution is REPLACE, then the change is copied 1308 +** into the rebased changeset with updates to columns also updated by 1309 +** the conflicting remote UPDATE removed. If this means no columns would 1310 +** be updated, the change is omitted. 1311 +** </dl> 1312 +** 1313 +** A local change may be rebased against multiple remote changes 1314 +** simultaneously. If a single key is modified by multiple remote 1315 +** changesets, they are combined as follows before the local changeset 1316 +** is rebased: 1317 +** 1318 +** <ul> 1319 +** <li> If there has been one or more REPLACE resolutions on a 1320 +** key, it is rebased according to a REPLACE. 1321 +** 1322 +** <li> If there have been no REPLACE resolutions on a key, then 1323 +** the local changeset is rebased according to the most recent 1324 +** of the OMIT resolutions. 1325 +** </ul> 1326 +** 1327 +** Note that conflict resolutions from multiple remote changesets are 1328 +** combined on a per-field basis, not per-row. This means that in the 1329 +** case of multiple remote UPDATE operations, some fields of a single 1330 +** local change may be rebased for REPLACE while others are rebased for 1331 +** OMIT. 1332 +** 1333 +** In order to rebase a local changeset, the remote changeset must first 1334 +** be applied to the local database using sqlite3changeset_apply_v2() and 1335 +** the buffer of rebase information captured. Then: 1336 +** 1337 +** <ol> 1338 +** <li> An sqlite3_rebaser object is created by calling 1339 +** sqlite3rebaser_create(). 1340 +** <li> The new object is configured with the rebase buffer obtained from 1341 +** sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure(). 1342 +** If the local changeset is to be rebased against multiple remote 1343 +** changesets, then sqlite3rebaser_configure() should be called 1344 +** multiple times, in the same order that the multiple 1345 +** sqlite3changeset_apply_v2() calls were made. 1346 +** <li> Each local changeset is rebased by calling sqlite3rebaser_rebase(). 1347 +** <li> The sqlite3_rebaser object is deleted by calling 1348 +** sqlite3rebaser_delete(). 1349 +** </ol> 1350 +*/ 1351 +typedef struct sqlite3_rebaser sqlite3_rebaser; 1352 + 1353 +/* 1354 +** CAPI3REF: Create a changeset rebaser object. 1355 +** EXPERIMENTAL 1356 +** 1357 +** Allocate a new changeset rebaser object. If successful, set (*ppNew) to 1358 +** point to the new object and return SQLITE_OK. Otherwise, if an error 1359 +** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew) 1360 +** to NULL. 1361 +*/ 1362 +int sqlite3rebaser_create(sqlite3_rebaser **ppNew); 1363 + 1364 +/* 1365 +** CAPI3REF: Configure a changeset rebaser object. 1366 +** EXPERIMENTAL 1367 +** 1368 +** Configure the changeset rebaser object to rebase changesets according 1369 +** to the conflict resolutions described by buffer pRebase (size nRebase 1370 +** bytes), which must have been obtained from a previous call to 1371 +** sqlite3changeset_apply_v2(). 1372 +*/ 1373 +int sqlite3rebaser_configure( 1374 + sqlite3_rebaser*, 1375 + int nRebase, const void *pRebase 1376 +); 1377 + 1378 +/* 1379 +** CAPI3REF: Rebase a changeset 1380 +** EXPERIMENTAL 1381 +** 1382 +** Argument pIn must point to a buffer containing a changeset nIn bytes 1383 +** in size. This function allocates and populates a buffer with a copy 1384 +** of the changeset rebased rebased according to the configuration of the 1385 +** rebaser object passed as the first argument. If successful, (*ppOut) 1386 +** is set to point to the new buffer containing the rebased changset and 1387 +** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the 1388 +** responsibility of the caller to eventually free the new buffer using 1389 +** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut) 1390 +** are set to zero and an SQLite error code returned. 1391 +*/ 1392 +int sqlite3rebaser_rebase( 1393 + sqlite3_rebaser*, 1394 + int nIn, const void *pIn, 1395 + int *pnOut, void **ppOut 1396 +); 1397 + 1398 +/* 1399 +** CAPI3REF: Delete a changeset rebaser object. 1400 +** EXPERIMENTAL 1401 +** 1402 +** Delete the changeset rebaser object and all associated resources. There 1403 +** should be one call to this function for each successful invocation 1404 +** of sqlite3rebaser_create(). 1405 +*/ 1406 +void sqlite3rebaser_delete(sqlite3_rebaser *p); 1407 + 1202 1408 /* 1203 1409 ** CAPI3REF: Streaming Versions of API functions. 1204 1410 ** 1205 1411 ** The six streaming API xxx_strm() functions serve similar purposes to the 1206 1412 ** corresponding non-streaming API functions: 1207 1413 ** 1208 1414 ** <table border=1 style="margin-left:8ex;margin-right:8ex"> 1209 1415 ** <tr><th>Streaming function<th>Non-streaming equivalent</th> 1210 1416 ** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply] 1417 +** <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2] 1211 1418 ** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat] 1212 1419 ** <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert] 1213 1420 ** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start] 1214 1421 ** <tr><td>sqlite3session_changeset_strm<td>[sqlite3session_changeset] 1215 1422 ** <tr><td>sqlite3session_patchset_strm<td>[sqlite3session_patchset] 1216 1423 ** </table> 1217 1424 ** ................................................................................ 1298 1505 ), 1299 1506 int(*xConflict)( 1300 1507 void *pCtx, /* Copy of sixth arg to _apply() */ 1301 1508 int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ 1302 1509 sqlite3_changeset_iter *p /* Handle describing change and conflict */ 1303 1510 ), 1304 1511 void *pCtx /* First argument passed to xConflict */ 1512 +); 1513 +int sqlite3changeset_apply_v2_strm( 1514 + sqlite3 *db, /* Apply change to "main" db of this handle */ 1515 + int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ 1516 + void *pIn, /* First arg for xInput */ 1517 + int(*xFilter)( 1518 + void *pCtx, /* Copy of sixth arg to _apply() */ 1519 + const char *zTab /* Table name */ 1520 + ), 1521 + int(*xConflict)( 1522 + void *pCtx, /* Copy of sixth arg to _apply() */ 1523 + int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ 1524 + sqlite3_changeset_iter *p /* Handle describing change and conflict */ 1525 + ), 1526 + void *pCtx, /* First argument passed to xConflict */ 1527 + void **ppRebase, int *pnRebase, 1528 + int flags 1305 1529 ); 1306 1530 int sqlite3changeset_concat_strm( 1307 1531 int (*xInputA)(void *pIn, void *pData, int *pnData), 1308 1532 void *pInA, 1309 1533 int (*xInputB)(void *pIn, void *pData, int *pnData), 1310 1534 void *pInB, 1311 1535 int (*xOutput)(void *pOut, const void *pData, int nData), ................................................................................ 1335 1559 int sqlite3changegroup_add_strm(sqlite3_changegroup*, 1336 1560 int (*xInput)(void *pIn, void *pData, int *pnData), 1337 1561 void *pIn 1338 1562 ); 1339 1563 int sqlite3changegroup_output_strm(sqlite3_changegroup*, 1340 1564 int (*xOutput)(void *pOut, const void *pData, int nData), 1341 1565 void *pOut 1566 +); 1567 +int sqlite3rebaser_rebase_strm( 1568 + sqlite3_rebaser *pRebaser, 1569 + int (*xInput)(void *pIn, void *pData, int *pnData), 1570 + void *pIn, 1571 + int (*xOutput)(void *pOut, const void *pData, int nData), 1572 + void *pOut 1342 1573 ); 1343 1574 1344 1575 1345 1576 /* 1346 1577 ** Make sure we can call this stuff from C++. 1347 1578 */ 1348 1579 #ifdef __cplusplus 1349 1580 } 1350 1581 #endif 1351 1582 1352 1583 #endif /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */
Changes to ext/session/test_session.c.
9 9 # include "sqlite_tcl.h" 10 10 #else 11 11 # include "tcl.h" 12 12 # ifndef SQLITE_TCLAPI 13 13 # define SQLITE_TCLAPI 14 14 # endif 15 15 #endif 16 + 17 +#ifndef SQLITE_AMALGAMATION 18 + typedef unsigned char u8; 19 +#endif 16 20 17 21 typedef struct TestSession TestSession; 18 22 struct TestSession { 19 23 sqlite3_session *pSession; 20 24 Tcl_Interp *interp; 21 25 Tcl_Obj *pFilterScript; 22 26 }; ................................................................................ 707 711 } 708 712 709 713 *pnData = nRet; 710 714 return SQLITE_OK; 711 715 } 712 716 713 717 714 -/* 715 -** sqlite3changeset_apply DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT? 716 -*/ 717 -static int SQLITE_TCLAPI test_sqlite3changeset_apply( 718 +static int SQLITE_TCLAPI testSqlite3changesetApply( 719 + int bV2, 718 720 void * clientData, 719 721 Tcl_Interp *interp, 720 722 int objc, 721 723 Tcl_Obj *CONST objv[] 722 724 ){ 723 725 sqlite3 *db; /* Database handle */ 724 726 Tcl_CmdInfo info; /* Database Tcl command (objv[1]) info */ 725 727 int rc; /* Return code from changeset_invert() */ 726 728 void *pChangeset; /* Buffer containing changeset */ 727 729 int nChangeset; /* Size of buffer aChangeset in bytes */ 728 730 TestConflictHandler ctx; 729 731 TestStreamInput sStr; 732 + void *pRebase = 0; 733 + int nRebase = 0; 734 + int flags = 0; /* Flags for apply_v2() */ 730 735 731 736 memset(&sStr, 0, sizeof(sStr)); 732 737 sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); 738 + 739 + /* Check for the -nosavepoint flag */ 740 + if( bV2 && objc>1 ){ 741 + const char *z1 = Tcl_GetString(objv[1]); 742 + int n = strlen(z1); 743 + if( n>1 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){ 744 + flags = SQLITE_CHANGESETAPPLY_NOSAVEPOINT; 745 + objc--; 746 + objv++; 747 + } 748 + } 733 749 734 750 if( objc!=4 && objc!=5 ){ 735 - Tcl_WrongNumArgs(interp, 1, objv, 736 - "DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?" 737 - ); 751 + const char *zMsg; 752 + if( bV2 ){ 753 + zMsg = "?-nosavepoint? DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?"; 754 + }else{ 755 + zMsg = "DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?"; 756 + } 757 + Tcl_WrongNumArgs(interp, 1, objv, zMsg); 738 758 return TCL_ERROR; 739 759 } 740 760 if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &info) ){ 741 - Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(objv[2]), 0); 761 + Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(objv[1]), 0); 742 762 return TCL_ERROR; 743 763 } 744 764 db = *(sqlite3 **)info.objClientData; 745 765 pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[2], &nChangeset); 746 766 ctx.pConflictScript = objv[3]; 747 767 ctx.pFilterScript = objc==5 ? objv[4] : 0; 748 768 ctx.interp = interp; 749 769 750 770 if( sStr.nStream==0 ){ 751 - rc = sqlite3changeset_apply(db, nChangeset, pChangeset, 752 - (objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx 753 - ); 771 + if( bV2==0 ){ 772 + rc = sqlite3changeset_apply(db, nChangeset, pChangeset, 773 + (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx 774 + ); 775 + }else{ 776 + rc = sqlite3changeset_apply_v2(db, nChangeset, pChangeset, 777 + (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx, 778 + &pRebase, &nRebase, flags 779 + ); 780 + } 754 781 }else{ 755 782 sStr.aData = (unsigned char*)pChangeset; 756 783 sStr.nData = nChangeset; 757 - rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr, 758 - (objc==5) ? test_filter_handler : 0, test_conflict_handler, (void *)&ctx 759 - ); 784 + if( bV2==0 ){ 785 + rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr, 786 + (objc==5) ? test_filter_handler : 0, 787 + test_conflict_handler, (void *)&ctx 788 + ); 789 + }else{ 790 + rc = sqlite3changeset_apply_v2_strm(db, testStreamInput, (void*)&sStr, 791 + (objc==5) ? test_filter_handler : 0, 792 + test_conflict_handler, (void *)&ctx, 793 + &pRebase, &nRebase, flags 794 + ); 795 + } 760 796 } 761 797 762 798 if( rc!=SQLITE_OK ){ 763 799 return test_session_error(interp, rc, 0); 800 + }else{ 801 + Tcl_ResetResult(interp); 802 + if( bV2 && pRebase ){ 803 + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pRebase, nRebase)); 804 + } 764 805 } 765 - Tcl_ResetResult(interp); 806 + sqlite3_free(pRebase); 766 807 return TCL_OK; 767 808 } 809 + 810 +/* 811 +** sqlite3changeset_apply DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT? 812 +*/ 813 +static int SQLITE_TCLAPI test_sqlite3changeset_apply( 814 + void * clientData, 815 + Tcl_Interp *interp, 816 + int objc, 817 + Tcl_Obj *CONST objv[] 818 +){ 819 + return testSqlite3changesetApply(0, clientData, interp, objc, objv); 820 +} 821 +/* 822 +** sqlite3changeset_apply_v2 DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT? 823 +*/ 824 +static int SQLITE_TCLAPI test_sqlite3changeset_apply_v2( 825 + void * clientData, 826 + Tcl_Interp *interp, 827 + int objc, 828 + Tcl_Obj *CONST objv[] 829 +){ 830 + return testSqlite3changesetApply(1, clientData, interp, objc, objv); 831 +} 768 832 769 833 /* 770 834 ** sqlite3changeset_apply_replace_all DB CHANGESET 771 835 */ 772 836 static int SQLITE_TCLAPI test_sqlite3changeset_apply_replace_all( 773 837 void * clientData, 774 838 Tcl_Interp *interp, ................................................................................ 1014 1078 } 1015 1079 if( rc!=SQLITE_OK ){ 1016 1080 return test_session_error(interp, rc, 0); 1017 1081 } 1018 1082 1019 1083 return TCL_OK; 1020 1084 } 1085 + 1086 +/* 1087 +** tclcmd: CMD configure REBASE-BLOB 1088 +** tclcmd: CMD rebase CHANGESET 1089 +** tclcmd: CMD delete 1090 +*/ 1091 +static int SQLITE_TCLAPI test_rebaser_cmd( 1092 + void * clientData, 1093 + Tcl_Interp *interp, 1094 + int objc, 1095 + Tcl_Obj *CONST objv[] 1096 +){ 1097 + struct RebaseSubcmd { 1098 + const char *zSub; 1099 + int nArg; 1100 + const char *zMsg; 1101 + int iSub; 1102 + } aSub[] = { 1103 + { "configure", 1, "REBASE-BLOB" }, /* 0 */ 1104 + { "delete", 0, "" }, /* 1 */ 1105 + { "rebase", 1, "CHANGESET" }, /* 2 */ 1106 + { 0 } 1107 + }; 1108 + 1109 + sqlite3_rebaser *p = (sqlite3_rebaser*)clientData; 1110 + int iSub; 1111 + int rc; 1112 + 1113 + if( objc<2 ){ 1114 + Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); 1115 + return TCL_ERROR; 1116 + } 1117 + rc = Tcl_GetIndexFromObjStruct(interp, 1118 + objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub 1119 + ); 1120 + if( rc!=TCL_OK ) return rc; 1121 + if( objc!=2+aSub[iSub].nArg ){ 1122 + Tcl_WrongNumArgs(interp, 2, objv, aSub[iSub].zMsg); 1123 + return TCL_ERROR; 1124 + } 1125 + 1126 + assert( iSub==0 || iSub==1 || iSub==2 ); 1127 + assert( rc==SQLITE_OK ); 1128 + switch( iSub ){ 1129 + case 0: { /* configure */ 1130 + int nRebase = 0; 1131 + unsigned char *pRebase = Tcl_GetByteArrayFromObj(objv[2], &nRebase); 1132 + rc = sqlite3rebaser_configure(p, nRebase, pRebase); 1133 + break; 1134 + } 1135 + 1136 + case 1: /* delete */ 1137 + Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); 1138 + break; 1139 + 1140 + default: { /* rebase */ 1141 + TestStreamInput sStr; /* Input stream */ 1142 + TestSessionsBlob sOut; /* Output blob */ 1143 + 1144 + memset(&sStr, 0, sizeof(sStr)); 1145 + memset(&sOut, 0, sizeof(sOut)); 1146 + sStr.aData = Tcl_GetByteArrayFromObj(objv[2], &sStr.nData); 1147 + sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR); 1148 + 1149 + if( sStr.nStream ){ 1150 + rc = sqlite3rebaser_rebase_strm(p, 1151 + testStreamInput, (void*)&sStr, 1152 + testStreamOutput, (void*)&sOut 1153 + ); 1154 + }else{ 1155 + rc = sqlite3rebaser_rebase(p, sStr.nData, sStr.aData, &sOut.n, &sOut.p); 1156 + } 1157 + 1158 + if( rc==SQLITE_OK ){ 1159 + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(sOut.p, sOut.n)); 1160 + } 1161 + sqlite3_free(sOut.p); 1162 + break; 1163 + } 1164 + } 1165 + 1166 + if( rc!=SQLITE_OK ){ 1167 + return test_session_error(interp, rc, 0); 1168 + } 1169 + return TCL_OK; 1170 +} 1171 + 1172 +static void SQLITE_TCLAPI test_rebaser_del(void *clientData){ 1173 + sqlite3_rebaser *p = (sqlite3_rebaser*)clientData; 1174 + sqlite3rebaser_delete(p); 1175 +} 1176 + 1177 +/* 1178 +** tclcmd: sqlite3rebaser_create NAME 1179 +*/ 1180 +static int SQLITE_TCLAPI test_sqlite3rebaser_create( 1181 + void * clientData, 1182 + Tcl_Interp *interp, 1183 + int objc, 1184 + Tcl_Obj *CONST objv[] 1185 +){ 1186 + int rc; 1187 + sqlite3_rebaser *pNew = 0; 1188 + if( objc!=2 ){ 1189 + Tcl_WrongNumArgs(interp, 1, objv, "NAME"); 1190 + return SQLITE_ERROR; 1191 + } 1192 + 1193 + rc = sqlite3rebaser_create(&pNew); 1194 + if( rc!=SQLITE_OK ){ 1195 + return test_session_error(interp, rc, 0); 1196 + } 1197 + 1198 + Tcl_CreateObjCommand(interp, Tcl_GetString(objv[1]), test_rebaser_cmd, 1199 + (ClientData)pNew, test_rebaser_del 1200 + ); 1201 + Tcl_SetObjResult(interp, objv[1]); 1202 + return TCL_OK; 1203 +} 1021 1204 1022 1205 int TestSession_Init(Tcl_Interp *interp){ 1023 1206 struct Cmd { 1024 1207 const char *zCmd; 1025 1208 Tcl_ObjCmdProc *xProc; 1026 1209 } aCmd[] = { 1027 1210 { "sqlite3session", test_sqlite3session }, 1028 1211 { "sqlite3session_foreach", test_sqlite3session_foreach }, 1029 1212 { "sqlite3changeset_invert", test_sqlite3changeset_invert }, 1030 1213 { "sqlite3changeset_concat", test_sqlite3changeset_concat }, 1031 1214 { "sqlite3changeset_apply", test_sqlite3changeset_apply }, 1215 + { "sqlite3changeset_apply_v2", test_sqlite3changeset_apply_v2 }, 1032 1216 { "sqlite3changeset_apply_replace_all", 1033 1217 test_sqlite3changeset_apply_replace_all }, 1034 1218 { "sql_exec_changeset", test_sql_exec_changeset }, 1219 + { "sqlite3rebaser_create", test_sqlite3rebaser_create }, 1035 1220 }; 1036 1221 int i; 1037 1222 1038 1223 for(i=0; i<sizeof(aCmd)/sizeof(struct Cmd); i++){ 1039 1224 struct Cmd *p = &aCmd[i]; 1040 1225 Tcl_CreateObjCommand(interp, p->zCmd, p->xProc, 0, 0); 1041 1226 } 1042 1227 1043 1228 return TCL_OK; 1044 1229 } 1045 1230 1046 1231 #endif /* SQLITE_TEST && SQLITE_SESSION && SQLITE_PREUPDATE_HOOK */
Changes to src/analyze.c.
1011 1011 if( v==0 || NEVER(pTab==0) ){ 1012 1012 return; 1013 1013 } 1014 1014 if( pTab->tnum==0 ){ 1015 1015 /* Do not gather statistics on views or virtual tables */ 1016 1016 return; 1017 1017 } 1018 - if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){ 1018 + if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){ 1019 1019 /* Do not gather statistics on system tables */ 1020 1020 return; 1021 1021 } 1022 1022 assert( sqlite3BtreeHoldsAllMutexes(db) ); 1023 1023 iDb = sqlite3SchemaToIndex(db, pTab->pSchema); 1024 1024 assert( iDb>=0 ); 1025 1025 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
Changes to src/btree.c.
2233 2233 /* 2234 2234 ** Invoke the busy handler for a btree. 2235 2235 */ 2236 2236 static int btreeInvokeBusyHandler(void *pArg){ 2237 2237 BtShared *pBt = (BtShared*)pArg; 2238 2238 assert( pBt->db ); 2239 2239 assert( sqlite3_mutex_held(pBt->db->mutex) ); 2240 - return sqlite3InvokeBusyHandler(&pBt->db->busyHandler); 2240 + return sqlite3InvokeBusyHandler(&pBt->db->busyHandler, 2241 + sqlite3PagerFile(pBt->pPager)); 2241 2242 } 2242 2243 2243 2244 /* 2244 2245 ** Open a database file. 2245 2246 ** 2246 2247 ** zFilename is the name of the database file. If zFilename is NULL 2247 2248 ** then an ephemeral database is created. The ephemeral database might ................................................................................ 2411 2412 rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); 2412 2413 } 2413 2414 if( rc!=SQLITE_OK ){ 2414 2415 goto btree_open_out; 2415 2416 } 2416 2417 pBt->openFlags = (u8)flags; 2417 2418 pBt->db = db; 2418 - sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt); 2419 + sqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt); 2419 2420 p->pBt = pBt; 2420 2421 2421 2422 pBt->pCursor = 0; 2422 2423 pBt->pPage1 = 0; 2423 2424 if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY; 2424 2425 #if defined(SQLITE_SECURE_DELETE) 2425 2426 pBt->btsFlags |= BTS_SECURE_DELETE; ................................................................................ 3374 3375 } 3375 3376 3376 3377 if( rc!=SQLITE_OK ){ 3377 3378 unlockBtreeIfUnused(pBt); 3378 3379 } 3379 3380 }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && 3380 3381 btreeInvokeBusyHandler(pBt) ); 3382 + sqlite3PagerResetLockTimeout(pBt->pPager); 3381 3383 3382 3384 if( rc==SQLITE_OK ){ 3383 3385 if( p->inTrans==TRANS_NONE ){ 3384 3386 pBt->nTransaction++; 3385 3387 #ifndef SQLITE_OMIT_SHARED_CACHE 3386 3388 if( p->sharable ){ 3387 3389 assert( p->lock.pBtree==p && p->lock.iTable==1 );
Changes to src/build.c.
1248 1248 if( p!=0 ){ 1249 1249 pCol = &(p->aCol[p->nCol-1]); 1250 1250 if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){ 1251 1251 sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", 1252 1252 pCol->zName); 1253 1253 }else{ 1254 1254 /* A copy of pExpr is used instead of the original, as pExpr contains 1255 - ** tokens that point to volatile memory. 1255 + ** tokens that point to volatile memory. 1256 1256 */ 1257 1257 Expr x; 1258 1258 sqlite3ExprDelete(db, pCol->pDflt); 1259 1259 memset(&x, 0, sizeof(x)); 1260 1260 x.op = TK_SPAN; 1261 1261 x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd); 1262 1262 x.pLeft = pExpr; ................................................................................ 1492 1492 ** the schema-version whenever the schema changes. 1493 1493 */ 1494 1494 void sqlite3ChangeCookie(Parse *pParse, int iDb){ 1495 1495 sqlite3 *db = pParse->db; 1496 1496 Vdbe *v = pParse->pVdbe; 1497 1497 assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); 1498 1498 sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, 1499 - db->aDb[iDb].pSchema->schema_cookie+1); 1499 + (int)(1+(unsigned)db->aDb[iDb].pSchema->schema_cookie)); 1500 1500 } 1501 1501 1502 1502 /* 1503 1503 ** Measure the number of characters needed to output the given 1504 1504 ** identifier. The number returned includes any quotes used 1505 1505 ** but does not include the null terminator. 1506 1506 ** ................................................................................ 1866 1866 if( pEnd==0 && pSelect==0 ){ 1867 1867 return; 1868 1868 } 1869 1869 assert( !db->mallocFailed ); 1870 1870 p = pParse->pNewTable; 1871 1871 if( p==0 ) return; 1872 1872 1873 - assert( !db->init.busy || !pSelect ); 1874 - 1875 1873 /* If the db->init.busy is 1 it means we are reading the SQL off the 1876 1874 ** "sqlite_master" or "sqlite_temp_master" table on the disk. 1877 1875 ** So do not write to the disk again. Extract the root page number 1878 1876 ** for the table from the db->init.newTnum field. (The page number 1879 1877 ** should have been put there by the sqliteOpenCb routine.) 1880 1878 ** 1881 1879 ** If the root page number is 1, that means this is the sqlite_master 1882 1880 ** table itself. So mark it read-only. 1883 1881 */ 1884 1882 if( db->init.busy ){ 1883 + if( pSelect ){ 1884 + sqlite3ErrorMsg(pParse, ""); 1885 + return; 1886 + } 1885 1887 p->tnum = db->init.newTnum; 1886 1888 if( p->tnum==1 ) p->tabFlags |= TF_Readonly; 1887 1889 } 1888 1890 1889 1891 /* Special processing for WITHOUT ROWID Tables */ 1890 1892 if( tabOpts & TF_WithoutRowid ){ 1891 1893 if( (p->tabFlags & TF_Autoincrement) ){ ................................................................................ 2168 2170 */ 2169 2171 int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ 2170 2172 Table *pSelTab; /* A fake table from which we get the result set */ 2171 2173 Select *pSel; /* Copy of the SELECT that implements the view */ 2172 2174 int nErr = 0; /* Number of errors encountered */ 2173 2175 int n; /* Temporarily holds the number of cursors assigned */ 2174 2176 sqlite3 *db = pParse->db; /* Database connection for malloc errors */ 2175 -#ifndef SQLITE_OMIT_VIRTUALTABLE 2177 +#ifndef SQLITE_OMIT_VIRTUALTABLE 2176 2178 int rc; 2177 2179 #endif 2178 2180 #ifndef SQLITE_OMIT_AUTHORIZATION 2179 2181 sqlite3_xauth xAuth; /* Saved xAuth pointer */ 2180 2182 #endif 2181 2183 2182 2184 assert( pTable );
Changes to src/ctime.c.
184 184 #if SQLITE_ENABLE_ATOMIC_WRITE 185 185 "ENABLE_ATOMIC_WRITE", 186 186 #endif 187 187 #if SQLITE_ENABLE_BATCH_ATOMIC_WRITE 188 188 "ENABLE_BATCH_ATOMIC_WRITE", 189 189 #endif 190 190 #if SQLITE_ENABLE_CEROD 191 - "ENABLE_CEROD", 191 + "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD), 192 192 #endif 193 193 #if SQLITE_ENABLE_COLUMN_METADATA 194 194 "ENABLE_COLUMN_METADATA", 195 195 #endif 196 196 #if SQLITE_ENABLE_COLUMN_USED_MASK 197 197 "ENABLE_COLUMN_USED_MASK", 198 198 #endif
Changes to src/dbstat.c.
420 420 pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1); 421 421 422 422 /* If connected to a ZIPVFS backend, override the page size and 423 423 ** offset with actual values obtained from ZIPVFS. 424 424 */ 425 425 fd = sqlite3PagerFile(pPager); 426 426 x[0] = pCsr->iPageno; 427 - if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ 427 + if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ 428 428 pCsr->iOffset = x[0]; 429 429 pCsr->szPage = (int)x[1]; 430 430 } 431 431 } 432 432 433 433 /* 434 434 ** Move a statvfs cursor to the next entry in the file.
Changes to src/expr.c.
4996 4996 if( pE2->op==TK_NOTNULL && pE1->op!=TK_ISNULL && pE1->op!=TK_IS ){ 4997 4997 Expr *pX = sqlite3ExprSkipCollate(pE1->pLeft); 4998 4998 testcase( pX!=pE1->pLeft ); 4999 4999 if( sqlite3ExprCompare(pParse, pX, pE2->pLeft, iTab)==0 ) return 1; 5000 5000 } 5001 5001 return 0; 5002 5002 } 5003 + 5004 +/* 5005 +** This is the Expr node callback for sqlite3ExprImpliesNotNullRow(). 5006 +** If the expression node requires that the table at pWalker->iCur 5007 +** have a non-NULL column, then set pWalker->eCode to 1 and abort. 5008 +*/ 5009 +static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ 5010 + /* This routine is only called for WHERE clause expressions and so it 5011 + ** cannot have any TK_AGG_COLUMN entries because those are only found 5012 + ** in HAVING clauses. We can get a TK_AGG_FUNCTION in a WHERE clause, 5013 + ** but that is an illegal construct and the query will be rejected at 5014 + ** a later stage of processing, so the TK_AGG_FUNCTION case does not 5015 + ** need to be considered here. */ 5016 + assert( pExpr->op!=TK_AGG_COLUMN ); 5017 + testcase( pExpr->op==TK_AGG_FUNCTION ); 5018 + 5019 + if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune; 5020 + switch( pExpr->op ){ 5021 + case TK_ISNOT: 5022 + case TK_NOT: 5023 + case TK_ISNULL: 5024 + case TK_IS: 5025 + case TK_OR: 5026 + case TK_CASE: 5027 + case TK_IN: 5028 + case TK_FUNCTION: 5029 + testcase( pExpr->op==TK_ISNOT ); 5030 + testcase( pExpr->op==TK_NOT ); 5031 + testcase( pExpr->op==TK_ISNULL ); 5032 + testcase( pExpr->op==TK_IS ); 5033 + testcase( pExpr->op==TK_OR ); 5034 + testcase( pExpr->op==TK_CASE ); 5035 + testcase( pExpr->op==TK_IN ); 5036 + testcase( pExpr->op==TK_FUNCTION ); 5037 + return WRC_Prune; 5038 + case TK_COLUMN: 5039 + if( pWalker->u.iCur==pExpr->iTable ){ 5040 + pWalker->eCode = 1; 5041 + return WRC_Abort; 5042 + } 5043 + return WRC_Prune; 5044 + 5045 + /* Virtual tables are allowed to use constraints like x=NULL. So 5046 + ** a term of the form x=y does not prove that y is not null if x 5047 + ** is the column of a virtual table */ 5048 + case TK_EQ: 5049 + case TK_NE: 5050 + case TK_LT: 5051 + case TK_LE: 5052 + case TK_GT: 5053 + case TK_GE: 5054 + testcase( pExpr->op==TK_EQ ); 5055 + testcase( pExpr->op==TK_NE ); 5056 + testcase( pExpr->op==TK_LT ); 5057 + testcase( pExpr->op==TK_LE ); 5058 + testcase( pExpr->op==TK_GT ); 5059 + testcase( pExpr->op==TK_GE ); 5060 + if( (pExpr->pLeft->op==TK_COLUMN && IsVirtual(pExpr->pLeft->pTab)) 5061 + || (pExpr->pRight->op==TK_COLUMN && IsVirtual(pExpr->pRight->pTab)) 5062 + ){ 5063 + return WRC_Prune; 5064 + } 5065 + default: 5066 + return WRC_Continue; 5067 + } 5068 +} 5069 + 5070 +/* 5071 +** Return true (non-zero) if expression p can only be true if at least 5072 +** one column of table iTab is non-null. In other words, return true 5073 +** if expression p will always be NULL or false if every column of iTab 5074 +** is NULL. 5075 +** 5076 +** False negatives are acceptable. In other words, it is ok to return 5077 +** zero even if expression p will never be true of every column of iTab 5078 +** is NULL. A false negative is merely a missed optimization opportunity. 5079 +** 5080 +** False positives are not allowed, however. A false positive may result 5081 +** in an incorrect answer. 5082 +** 5083 +** Terms of p that are marked with EP_FromJoin (and hence that come from 5084 +** the ON or USING clauses of LEFT JOINS) are excluded from the analysis. 5085 +** 5086 +** This routine is used to check if a LEFT JOIN can be converted into 5087 +** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE 5088 +** clause requires that some column of the right table of the LEFT JOIN 5089 +** be non-NULL, then the LEFT JOIN can be safely converted into an 5090 +** ordinary join. 5091 +*/ 5092 +int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ 5093 + Walker w; 5094 + w.xExprCallback = impliesNotNullRow; 5095 + w.xSelectCallback = 0; 5096 + w.xSelectCallback2 = 0; 5097 + w.eCode = 0; 5098 + w.u.iCur = iTab; 5099 + sqlite3WalkExpr(&w, p); 5100 + return w.eCode; 5101 +} 5003 5102 5004 5103 /* 5005 5104 ** An instance of the following structure is used by the tree walker 5006 5105 ** to determine if an expression can be evaluated by reference to the 5007 5106 ** index only, without having to do a search for the corresponding 5008 5107 ** table entry. The IdxCover.pIdx field is the index. IdxCover.iCur 5009 5108 ** is the cursor for the table.
Changes to src/insert.c.
206 206 ** 207 207 ** There is at most one AutoincInfo structure per table even if the 208 208 ** same table is autoincremented multiple times due to inserts within 209 209 ** triggers. A new AutoincInfo structure is created if this is the 210 210 ** first use of table pTab. On 2nd and subsequent uses, the original 211 211 ** AutoincInfo structure is used. 212 212 ** 213 -** Three memory locations are allocated: 213 +** Four consecutive registers are allocated: 214 214 ** 215 -** (1) Register to hold the name of the pTab table. 216 -** (2) Register to hold the maximum ROWID of pTab. 217 -** (3) Register to hold the rowid in sqlite_sequence of pTab 215 +** (1) The name of the pTab table. 216 +** (2) The maximum ROWID of pTab. 217 +** (3) The rowid in sqlite_sequence of pTab 218 +** (4) The original value of the max ROWID in pTab, or NULL if none 218 219 ** 219 220 ** The 2nd register is the one that is returned. That is all the 220 221 ** insert routine needs to know about. 221 222 */ 222 223 static int autoIncBegin( 223 224 Parse *pParse, /* Parsing context */ 224 225 int iDb, /* Index of the database holding pTab */ ................................................................................ 238 239 if( pInfo==0 ) return 0; 239 240 pInfo->pNext = pToplevel->pAinc; 240 241 pToplevel->pAinc = pInfo; 241 242 pInfo->pTab = pTab; 242 243 pInfo->iDb = iDb; 243 244 pToplevel->nMem++; /* Register to hold name of table */ 244 245 pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */ 245 - pToplevel->nMem++; /* Rowid in sqlite_sequence */ 246 + pToplevel->nMem +=2; /* Rowid in sqlite_sequence + orig max val */ 246 247 } 247 248 memId = pInfo->regCtr; 248 249 } 249 250 return memId; 250 251 } 251 252 252 253 /* ................................................................................ 266 267 assert( sqlite3IsToplevel(pParse) ); 267 268 268 269 assert( v ); /* We failed long ago if this is not so */ 269 270 for(p = pParse->pAinc; p; p = p->pNext){ 270 271 static const int iLn = VDBE_OFFSET_LINENO(2); 271 272 static const VdbeOpList autoInc[] = { 272 273 /* 0 */ {OP_Null, 0, 0, 0}, 273 - /* 1 */ {OP_Rewind, 0, 9, 0}, 274 + /* 1 */ {OP_Rewind, 0, 10, 0}, 274 275 /* 2 */ {OP_Column, 0, 0, 0}, 275 - /* 3 */ {OP_Ne, 0, 7, 0}, 276 + /* 3 */ {OP_Ne, 0, 9, 0}, 276 277 /* 4 */ {OP_Rowid, 0, 0, 0}, 277 278 /* 5 */ {OP_Column, 0, 1, 0}, 278 - /* 6 */ {OP_Goto, 0, 9, 0}, 279 - /* 7 */ {OP_Next, 0, 2, 0}, 280 - /* 8 */ {OP_Integer, 0, 0, 0}, 281 - /* 9 */ {OP_Close, 0, 0, 0} 279 + /* 6 */ {OP_AddImm, 0, 0, 0}, 280 + /* 7 */ {OP_Copy, 0, 0, 0}, 281 + /* 8 */ {OP_Goto, 0, 11, 0}, 282 + /* 9 */ {OP_Next, 0, 2, 0}, 283 + /* 10 */ {OP_Integer, 0, 0, 0}, 284 + /* 11 */ {OP_Close, 0, 0, 0} 282 285 }; 283 286 VdbeOp *aOp; 284 287 pDb = &db->aDb[p->iDb]; 285 288 memId = p->regCtr; 286 289 assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); 287 290 sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); 288 291 sqlite3VdbeLoadString(v, memId-1, p->pTab->zName); 289 292 aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn); 290 293 if( aOp==0 ) break; 291 294 aOp[0].p2 = memId; 292 - aOp[0].p3 = memId+1; 295 + aOp[0].p3 = memId+2; 293 296 aOp[2].p3 = memId; 294 297 aOp[3].p1 = memId-1; 295 298 aOp[3].p3 = memId; 296 299 aOp[3].p5 = SQLITE_JUMPIFNULL; 297 300 aOp[4].p2 = memId+1; 298 301 aOp[5].p3 = memId; 299 - aOp[8].p2 = memId; 302 + aOp[6].p1 = memId; 303 + aOp[7].p2 = memId+2; 304 + aOp[7].p1 = memId; 305 + aOp[10].p2 = memId; 300 306 } 301 307 } 302 308 303 309 /* 304 310 ** Update the maximum rowid for an autoincrement calculation. 305 311 ** 306 312 ** This routine should be called when the regRowid register holds a ................................................................................ 339 345 VdbeOp *aOp; 340 346 Db *pDb = &db->aDb[p->iDb]; 341 347 int iRec; 342 348 int memId = p->regCtr; 343 349 344 350 iRec = sqlite3GetTempReg(pParse); 345 351 assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); 352 + sqlite3VdbeAddOp3(v, OP_Le, memId+2, sqlite3VdbeCurrentAddr(v)+7, memId); 353 + VdbeCoverage(v); 346 354 sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); 347 355 aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn); 348 356 if( aOp==0 ) break; 349 357 aOp[0].p1 = memId+1; 350 358 aOp[1].p2 = memId+1; 351 359 aOp[2].p1 = memId-1; 352 360 aOp[2].p3 = iRec;
Changes to src/main.c.
1480 1480 } 1481 1481 1482 1482 /* 1483 1483 ** This routine implements a busy callback that sleeps and tries 1484 1484 ** again until a timeout value is reached. The timeout value is 1485 1485 ** an integer number of milliseconds passed in as the first 1486 1486 ** argument. 1487 +** 1488 +** Return non-zero to retry the lock. Return zero to stop trying 1489 +** and cause SQLite to return SQLITE_BUSY. 1487 1490 */ 1488 1491 static int sqliteDefaultBusyCallback( 1489 - void *ptr, /* Database connection */ 1490 - int count /* Number of times table has been busy */ 1492 + void *ptr, /* Database connection */ 1493 + int count, /* Number of times table has been busy */ 1494 + sqlite3_file *pFile /* The file on which the lock occurred */ 1491 1495 ){ 1492 1496 #if SQLITE_OS_WIN || HAVE_USLEEP 1497 + /* This case is for systems that have support for sleeping for fractions of 1498 + ** a second. Examples: All windows systems, unix systems with usleep() */ 1493 1499 static const u8 delays[] = 1494 1500 { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; 1495 1501 static const u8 totals[] = 1496 1502 { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 }; 1497 1503 # define NDELAY ArraySize(delays) 1498 1504 sqlite3 *db = (sqlite3 *)ptr; 1499 - int timeout = db->busyTimeout; 1505 + int tmout = db->busyTimeout; 1500 1506 int delay, prior; 1501 1507 1508 +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT 1509 + if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){ 1510 + if( count ){ 1511 + tmout = 0; 1512 + sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout); 1513 + return 0; 1514 + }else{ 1515 + return 1; 1516 + } 1517 + } 1518 +#else 1519 + UNUSED_PARAMETER(pFile); 1520 +#endif 1502 1521 assert( count>=0 ); 1503 1522 if( count < NDELAY ){ 1504 1523 delay = delays[count]; 1505 1524 prior = totals[count]; 1506 1525 }else{ 1507 1526 delay = delays[NDELAY-1]; 1508 1527 prior = totals[NDELAY-1] + delay*(count-(NDELAY-1)); 1509 1528 } 1510 - if( prior + delay > timeout ){ 1511 - delay = timeout - prior; 1529 + if( prior + delay > tmout ){ 1530 + delay = tmout - prior; 1512 1531 if( delay<=0 ) return 0; 1513 1532 } 1514 1533 sqlite3OsSleep(db->pVfs, delay*1000); 1515 1534 return 1; 1516 1535 #else 1536 + /* This case for unix systems that lack usleep() support. Sleeping 1537 + ** must be done in increments of whole seconds */ 1517 1538 sqlite3 *db = (sqlite3 *)ptr; 1518 - int timeout = ((sqlite3 *)ptr)->busyTimeout; 1519 - if( (count+1)*1000 > timeout ){ 1539 + int tmout = ((sqlite3 *)ptr)->busyTimeout; 1540 + UNUSED_PARAMETER(pFile); 1541 + if( (count+1)*1000 > tmout ){ 1520 1542 return 0; 1521 1543 } 1522 1544 sqlite3OsSleep(db->pVfs, 1000000); 1523 1545 return 1; 1524 1546 #endif 1525 1547 } 1526 1548 1527 1549 /* 1528 1550 ** Invoke the given busy handler. 1529 1551 ** 1530 -** This routine is called when an operation failed with a lock. 1552 +** This routine is called when an operation failed to acquire a 1553 +** lock on VFS file pFile. 1554 +** 1531 1555 ** If this routine returns non-zero, the lock is retried. If it 1532 1556 ** returns 0, the operation aborts with an SQLITE_BUSY error. 1533 1557 */ 1534 -int sqlite3InvokeBusyHandler(BusyHandler *p){ 1558 +int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){ 1535 1559 int rc; 1536 - if( NEVER(p==0) || p->xFunc==0 || p->nBusy<0 ) return 0; 1537 - rc = p->xFunc(p->pArg, p->nBusy); 1560 + if( p->xBusyHandler==0 || p->nBusy<0 ) return 0; 1561 + if( p->bExtraFileArg ){ 1562 + /* Add an extra parameter with the pFile pointer to the end of the 1563 + ** callback argument list */ 1564 + int (*xTra)(void*,int,sqlite3_file*); 1565 + xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler; 1566 + rc = xTra(p->pBusyArg, p->nBusy, pFile); 1567 + }else{ 1568 + /* Legacy style busy handler callback */ 1569 + rc = p->xBusyHandler(p->pBusyArg, p->nBusy); 1570 + } 1538 1571 if( rc==0 ){ 1539 1572 p->nBusy = -1; 1540 1573 }else{ 1541 1574 p->nBusy++; 1542 1575 } 1543 1576 return rc; 1544 1577 } ................................................................................ 1552 1585 int (*xBusy)(void*,int), 1553 1586 void *pArg 1554 1587 ){ 1555 1588 #ifdef SQLITE_ENABLE_API_ARMOR 1556 1589 if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; 1557 1590 #endif 1558 1591 sqlite3_mutex_enter(db->mutex); 1559 - db->busyHandler.xFunc = xBusy; 1560 - db->busyHandler.pArg = pArg; 1592 + db->busyHandler.xBusyHandler = xBusy; 1593 + db->busyHandler.pBusyArg = pArg; 1561 1594 db->busyHandler.nBusy = 0; 1595 + db->busyHandler.bExtraFileArg = 0; 1562 1596 db->busyTimeout = 0; 1563 1597 sqlite3_mutex_leave(db->mutex); 1564 1598 return SQLITE_OK; 1565 1599 } 1566 1600 1567 1601 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK 1568 1602 /* ................................................................................ 1602 1636 ** specified number of milliseconds before returning 0. 1603 1637 */ 1604 1638 int sqlite3_busy_timeout(sqlite3 *db, int ms){ 1605 1639 #ifdef SQLITE_ENABLE_API_ARMOR 1606 1640 if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; 1607 1641 #endif 1608 1642 if( ms>0 ){ 1609 - sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); 1643 + sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, 1644 + (void*)db); 1610 1645 db->busyTimeout = ms; 1646 + db->busyHandler.bExtraFileArg = 1; 1611 1647 }else{ 1612 1648 sqlite3_busy_handler(db, 0, 0); 1613 1649 } 1614 1650 return SQLITE_OK; 1615 1651 } 1616 1652 1617 1653 /* ................................................................................ 3708 3744 rc = SQLITE_OK; 3709 3745 }else if( op==SQLITE_FCNTL_VFS_POINTER ){ 3710 3746 *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager); 3711 3747 rc = SQLITE_OK; 3712 3748 }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){ 3713 3749 *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager); 3714 3750 rc = SQLITE_OK; 3715 - }else if( fd->pMethods ){ 3716 - rc = sqlite3OsFileControl(fd, op, pArg); 3717 3751 #ifndef SQLITE_OMIT_WAL 3718 3752 if( (rc==SQLITE_OK)&&(op==SQLITE_FCNTL_LAST_ERRNO)&&(*(int *)pArg==0) ){ 3719 3753 sqlite3_file *pWalFd = sqlite3PagerWalFile(pPager); 3720 3754 if( pWalFd&&(pWalFd->pMethods) ){ 3721 3755 rc = sqlite3OsFileControl(pWalFd, op, pArg); 3722 3756 } 3723 3757 } 3724 3758 #endif 3725 3759 }else{ 3726 - rc = SQLITE_NOTFOUND; 3760 + rc = sqlite3OsFileControl(fd, op, pArg); 3727 3761 } 3728 3762 sqlite3BtreeLeave(pBtree); 3729 3763 } 3730 3764 sqlite3Error(db, rc); 3731 3765 sqlite3_mutex_leave(db->mutex); 3732 3766 return rc; 3733 3767 }
Changes to src/memdb.c.
6 6 ** 7 7 ** May you do good and not evil. 8 8 ** May you find forgiveness for yourself and forgive others. 9 9 ** May you share freely, never taking more than you give. 10 10 ** 11 11 ****************************************************************************** 12 12 ** 13 -** This file implements in-memory VFS. A database is held as a contiguous 13 +** This file implements an in-memory VFS. A database is held as a contiguous 14 14 ** block of memory. 15 15 ** 16 16 ** This file also implements interface sqlite3_serialize() and 17 17 ** sqlite3_deserialize(). 18 18 */ 19 19 #ifdef SQLITE_ENABLE_DESERIALIZE 20 20 #include "sqliteInt.h"
Changes to src/os.c.
121 121 ** and we need to know about the failures. Use sqlite3OsFileControlHint() 122 122 ** when simply tossing information over the wall to the VFS and we do not 123 123 ** really care if the VFS receives and understands the information since it 124 124 ** is only a hint and can be safely ignored. The sqlite3OsFileControlHint() 125 125 ** routine has no return value since the return value would be meaningless. 126 126 */ 127 127 int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ 128 + if( id->pMethods==0 ) return SQLITE_NOTFOUND; 128 129 #ifdef SQLITE_TEST 129 - if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){ 130 + if( op!=SQLITE_FCNTL_COMMIT_PHASETWO 131 + && op!=SQLITE_FCNTL_LOCK_TIMEOUT 132 + ){ 130 133 /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite 131 134 ** is using a regular VFS, it is called after the corresponding 132 135 ** transaction has been committed. Injecting a fault at this point 133 136 ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM 134 137 ** but the transaction is committed anyway. 135 138 ** 136 139 ** The core must call OsFileControl() though, not OsFileControlHint(), ................................................................................ 139 142 ** to the user. */ 140 143 DO_OS_MALLOC_TEST(id); 141 144 } 142 145 #endif 143 146 return id->pMethods->xFileControl(id, op, pArg); 144 147 } 145 148 void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ 146 - (void)id->pMethods->xFileControl(id, op, pArg); 149 + if( id->pMethods ) (void)id->pMethods->xFileControl(id, op, pArg); 147 150 } 148 151 149 152 int sqlite3OsSectorSize(sqlite3_file *id){ 150 153 int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; 151 154 return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); 152 155 } 153 156 int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
Changes to src/os_unix.c.
229 229 #endif 230 230 #if SQLITE_ENABLE_DATA_PROTECTION 231 231 int protFlags; /* Data protection flags from unixOpen */ 232 232 #endif 233 233 #if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__) 234 234 unsigned fsFlags; /* cached details from statfs() */ 235 235 #endif 236 +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT 237 + unsigned iBusyTimeout; /* Wait this many millisec on locks */ 238 +#endif 236 239 #if OS_VXWORKS 237 240 struct vxworksFileId *pId; /* Unique file ID */ 238 241 #endif 239 242 #ifdef SQLITE_DEBUG 240 243 /* The next group of variables are used to track whether or not the 241 244 ** transaction counter in bytes 24-27 of database files are updated 242 245 ** whenever any part of the database changes. An assertion fault will ................................................................................ 1765 1768 1766 1769 unixLeaveMutex(); 1767 1770 OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); 1768 1771 1769 1772 *pResOut = reserved; 1770 1773 return rc; 1771 1774 } 1775 + 1776 +/* 1777 +** Set a posix-advisory-lock. 1778 +** 1779 +** There are two versions of this routine. If compiled with 1780 +** SQLITE_ENABLE_SETLK_TIMEOUT then the routine has an extra parameter 1781 +** which is a pointer to a unixFile. If the unixFile->iBusyTimeout 1782 +** value is set, then it is the number of milliseconds to wait before 1783 +** failing the lock. The iBusyTimeout value is always reset back to 1784 +** zero on each call. 1785 +** 1786 +** If SQLITE_ENABLE_SETLK_TIMEOUT is not defined, then do a non-blocking 1787 +** attempt to set the lock. 1788 +*/ 1789 +#ifndef SQLITE_ENABLE_SETLK_TIMEOUT 1790 +# define osSetPosixAdvisoryLock(h,x,t) osFcntl(h,F_SETLK,x) 1791 +#else 1792 +static int osSetPosixAdvisoryLock( 1793 + int h, /* The file descriptor on which to take the lock */ 1794 + struct flock *pLock, /* The description of the lock */ 1795 + unixFile *pFile /* Structure holding timeout value */ 1796 +){ 1797 + int rc = osFcntl(h,F_SETLK,pLock); 1798 + while( rc<0 && pFile->iBusyTimeout>0 ){ 1799 + /* On systems that support some kind of blocking file lock with a timeout, 1800 + ** make appropriate changes here to invoke that blocking file lock. On 1801 + ** generic posix, however, there is no such API. So we simply try the 1802 + ** lock once every millisecond until either the timeout expires, or until 1803 + ** the lock is obtained. */ 1804 + usleep(1000); 1805 + rc = osFcntl(h,F_SETLK,pLock); 1806 + pFile->iBusyTimeout--; 1807 + } 1808 + return rc; 1809 +} 1810 +#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */ 1811 + 1772 1812 1773 1813 /* 1774 1814 ** Attempt to set a system-lock on the file pFile. The lock is 1775 1815 ** described by pLock. 1776 1816 ** 1777 1817 ** If the pFile was opened read/write from unix-excl, then the only lock 1778 1818 ** ever obtained is an exclusive lock, and it is obtained exactly once ................................................................................ 1798 1838 if( pInode->bProcessLock==0 ){ 1799 1839 struct flock lock; 1800 1840 assert( pInode->nLock==0 ); 1801 1841 lock.l_whence = SEEK_SET; 1802 1842 lock.l_start = SHARED_FIRST; 1803 1843 lock.l_len = SHARED_SIZE; 1804 1844 lock.l_type = F_WRLCK; 1805 - rc = osFcntl(pFile->h, F_SETLK, &lock); 1845 + rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile); 1806 1846 if( rc<0 ) return rc; 1807 1847 pInode->bProcessLock = 1; 1808 1848 pInode->nLock++; 1809 1849 }else{ 1810 1850 rc = 0; 1811 1851 } 1812 1852 }else{ 1813 - int i = 0; 1814 - for(;;){ 1815 - rc = osFcntl(pFile->h, F_SETLK, pLock); 1816 - if( rc && nRetry-- ){ 1817 - usleep(100 * (++i)); 1818 - }else{ 1819 - break; 1820 - } 1821 - } 1853 + rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile); 1822 1854 } 1823 1855 return rc; 1824 1856 } 1825 1857 1826 1858 /* 1827 1859 ** Lock the file with the lock specified by parameter eFileLock - one 1828 1860 ** of the following: ................................................................................ 4572 4604 } 4573 4605 return SQLITE_OK; 4574 4606 } 4575 4607 case SQLITE_FCNTL_HAS_MOVED: { 4576 4608 *(int*)pArg = fileHasMoved(pFile); 4577 4609 return SQLITE_OK; 4578 4610 } 4611 +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT 4612 + case SQLITE_FCNTL_LOCK_TIMEOUT: { 4613 + pFile->iBusyTimeout = *(int*)pArg; 4614 + return SQLITE_OK; 4615 + } 4616 +#endif 4579 4617 #if SQLITE_MAX_MMAP_SIZE>0 4580 4618 case SQLITE_FCNTL_MMAP_SIZE: { 4581 4619 i64 newLimit = *(i64*)pArg; 4582 4620 int rc = SQLITE_OK; 4583 4621 if( newLimit>sqlite3GlobalConfig.mxMmap ){ 4584 4622 newLimit = sqlite3GlobalConfig.mxMmap; 4585 4623 } ................................................................................ 4911 4949 4912 4950 if( pShmNode->h>=0 ){ 4913 4951 /* Initialize the locking parameters */ 4914 4952 f.l_type = lockType; 4915 4953 f.l_whence = SEEK_SET; 4916 4954 f.l_start = ofst; 4917 4955 f.l_len = n; 4918 - rc = osFcntl(pShmNode->h, F_SETLK, &f); 4956 + rc = osSetPosixAdvisoryLock(pShmNode->h, &f, pFile); 4919 4957 rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; 4920 4958 } 4921 4959 4922 4960 /* Update the global lock state and do debug tracing */ 4923 4961 #ifdef SQLITE_DEBUG 4924 4962 { u16 mask; 4925 4963 OSTRACE(("SHM-LOCK "));
Changes to src/pager.c.
2126 2126 ** successfully committed, but the EXCLUSIVE lock is still held on the 2127 2127 ** file. So it is safe to truncate the database file to its minimum 2128 2128 ** required size. */ 2129 2129 assert( pPager->eLock==EXCLUSIVE_LOCK ); 2130 2130 rc = pager_truncate(pPager, pPager->dbSize); 2131 2131 } 2132 2132 2133 - if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){ 2133 + if( rc==SQLITE_OK && bCommit ){ 2134 2134 rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0); 2135 2135 if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; 2136 2136 } 2137 2137 2138 2138 if( !pPager->exclusiveMode 2139 2139 && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) 2140 2140 ){ ................................................................................ 2953 2953 } 2954 2954 /* Following a rollback, the database file should be back in its original 2955 2955 ** state prior to the start of the transaction, so invoke the 2956 2956 ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the 2957 2957 ** assertion that the transaction counter was modified. 2958 2958 */ 2959 2959 #ifdef SQLITE_DEBUG 2960 - if( pPager->fd->pMethods ){ 2961 - sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); 2962 - } 2960 + sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); 2963 2961 #endif 2964 2962 2965 2963 /* If this playback is happening automatically as a result of an IO or 2966 2964 ** malloc error that occurred after the change-counter was updated but 2967 2965 ** before the transaction was committed, then the change-counter 2968 2966 ** modification may just have been reverted. If this happens in exclusive 2969 2967 ** mode, then subsequent transactions performed by the connection will not ................................................................................ 3712 3710 ** SHARED_LOCK -> EXCLUSIVE_LOCK | No 3713 3711 ** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes 3714 3712 ** 3715 3713 ** If the busy-handler callback returns non-zero, the lock is 3716 3714 ** retried. If it returns zero, then the SQLITE_BUSY error is 3717 3715 ** returned to the caller of the pager API function. 3718 3716 */ 3719 -void sqlite3PagerSetBusyhandler( 3717 +void sqlite3PagerSetBusyHandler( 3720 3718 Pager *pPager, /* Pager object */ 3721 3719 int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ 3722 3720 void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ 3723 3721 ){ 3722 + void **ap; 3724 3723 pPager->xBusyHandler = xBusyHandler; 3725 3724 pPager->pBusyHandlerArg = pBusyHandlerArg; 3726 - 3727 - if( isOpen(pPager->fd) ){ 3728 - void **ap = (void **)&pPager->xBusyHandler; 3729 - assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); 3730 - assert( ap[1]==pBusyHandlerArg ); 3731 - sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); 3732 - } 3725 + ap = (void **)&pPager->xBusyHandler; 3726 + assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); 3727 + assert( ap[1]==pBusyHandlerArg ); 3728 + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); 3733 3729 } 3734 3730 3735 3731 /* 3736 3732 ** Change the page size used by the Pager object. The new page size 3737 3733 ** is passed in *pPageSize. 3738 3734 ** 3739 3735 ** If the pager is in the error state when this function is called, it ................................................................................ 5709 5705 } 5710 5706 void sqlite3PagerUnrefPageOne(DbPage *pPg){ 5711 5707 Pager *pPager; 5712 5708 assert( pPg!=0 ); 5713 5709 assert( pPg->pgno==1 ); 5714 5710 assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */ 5715 5711 pPager = pPg->pPager; 5712 + sqlite3PagerResetLockTimeout(pPager); 5716 5713 sqlite3PcacheRelease(pPg); 5717 5714 pagerUnlockIfUnused(pPager); 5718 5715 } 5719 5716 5720 5717 /* 5721 5718 ** This function is called at the start of every write transaction. 5722 5719 ** There must already be a RESERVED or EXCLUSIVE lock on the database ................................................................................ 6307 6304 ** or pages with the Pager.noSync flag set. 6308 6305 ** 6309 6306 ** If successful, or if called on a pager for which it is a no-op, this 6310 6307 ** function returns SQLITE_OK. Otherwise, an IO error code is returned. 6311 6308 */ 6312 6309 int sqlite3PagerSync(Pager *pPager, const char *zMaster){ 6313 6310 int rc = SQLITE_OK; 6314 - 6315 - if( isOpen(pPager->fd) ){ 6316 - void *pArg = (void*)zMaster; 6317 - rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); 6318 - if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; 6319 - } 6311 + void *pArg = (void*)zMaster; 6312 + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); 6313 + if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; 6320 6314 if( rc==SQLITE_OK && !pPager->noSync ){ 6321 6315 assert( !MEMDB ); 6322 6316 rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); 6323 6317 } 6324 6318 return rc; 6325 6319 } 6326 6320 ................................................................................ 7001 6995 */ 7002 6996 sqlite3_file *sqlite3PagerWalFile(Pager *pPager){ 7003 6997 return ((pPager->pWal) ? sqlite3WalFile(pPager->pWal) : (NULL)); 7004 6998 } 7005 6999 #endif 7006 7000 7007 7001 7002 +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT 7003 +/* 7004 +** Reset the lock timeout for pager. 7005 +*/ 7006 +void sqlite3PagerResetLockTimeout(Pager *pPager){ 7007 + int x = 0; 7008 + sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x); 7009 +} 7010 +#endif 7011 + 7008 7012 /* 7009 7013 ** Return the file handle for the journal file (if it exists). 7010 7014 ** This will be either the rollback journal or the WAL file. 7011 7015 */ 7012 7016 sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){ 7013 7017 #if SQLITE_OMIT_WAL 7014 7018 return pPager->jfd; ................................................................................ 7461 7465 if( pPager->pWal ){ 7462 7466 rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, 7463 7467 (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), 7464 7468 pPager->pBusyHandlerArg, 7465 7469 pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, 7466 7470 pnLog, pnCkpt 7467 7471 ); 7472 + sqlite3PagerResetLockTimeout(pPager); 7468 7473 } 7469 7474 return rc; 7470 7475 } 7471 7476 7472 7477 int sqlite3PagerWalCallback(Pager *pPager){ 7473 7478 return sqlite3WalCallback(pPager->pWal); 7474 7479 }
Changes to src/pager.h.
122 122 int, 123 123 void(*)(DbPage*) 124 124 ); 125 125 int sqlite3PagerClose(Pager *pPager, sqlite3*); 126 126 int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); 127 127 128 128 /* Functions used to configure a Pager object. */ 129 -void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); 129 +void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *); 130 130 int sqlite3PagerSetPagesize(Pager*, u32*, int); 131 131 #ifdef SQLITE_HAS_CODEC 132 132 void sqlite3PagerAlignReserve(Pager*,Pager*); 133 133 #endif 134 134 int sqlite3PagerMaxPageCount(Pager*, int); 135 135 void sqlite3PagerSetCachesize(Pager*, int); 136 136 int sqlite3PagerSetSpillsize(Pager*, int); ................................................................................ 209 209 sqlite3_file *sqlite3PagerJrnlFile(Pager*); 210 210 const char *sqlite3PagerJournalname(Pager*); 211 211 void *sqlite3PagerTempSpace(Pager*); 212 212 int sqlite3PagerIsMemdb(Pager*); 213 213 void sqlite3PagerCacheStat(Pager *, int, int, int *); 214 214 void sqlite3PagerClearCache(Pager*); 215 215 int sqlite3SectorSize(sqlite3_file *); 216 +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT 217 +void sqlite3PagerResetLockTimeout(Pager *pPager); 218 +#else 219 +# define sqlite3PagerResetLockTimeout(X) 220 +#endif 216 221 217 222 /* Functions used to truncate the database file. */ 218 223 void sqlite3PagerTruncateImage(Pager*,Pgno); 219 224 220 225 void sqlite3PagerRekey(DbPage*, Pgno, u16); 221 226 222 227 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
Changes to src/parse.y.
460 460 ){ 461 461 sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); 462 462 } 463 463 } 464 464 } 465 465 } 466 466 467 -select(A) ::= with(W) selectnowith(X). { 467 +select(A) ::= WITH wqlist(W) selectnowith(X). { 468 + Select *p = X; 469 + if( p ){ 470 + p->pWith = W; 471 + parserDoubleLinkSelect(pParse, p); 472 + }else{ 473 + sqlite3WithDelete(pParse->db, W); 474 + } 475 + A = p; 476 +} 477 +select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X). { 468 478 Select *p = X; 469 479 if( p ){ 470 480 p->pWith = W; 471 481 parserDoubleLinkSelect(pParse, p); 472 482 }else{ 473 483 sqlite3WithDelete(pParse->db, W); 474 484 } 475 - A = p; /*A-overwrites-W*/ 485 + A = p; 486 +} 487 +select(A) ::= selectnowith(X). { 488 + Select *p = X; 489 + if( p ){ 490 + parserDoubleLinkSelect(pParse, p); 491 + } 492 + A = p; /*A-overwrites-X*/ 476 493 } 477 494 478 495 selectnowith(A) ::= oneselect(A). 479 496 %ifndef SQLITE_OMIT_COMPOUND_SELECT 480 497 selectnowith(A) ::= selectnowith(A) multiselect_op(Y) oneselect(Z). { 481 498 Select *pRhs = Z; 482 499 Select *pLhs = A; ................................................................................ 519 536 ** then extract the first few alphanumeric characters from within that 520 537 ** comment to be the zSelName value. Otherwise, the label is #N where 521 538 ** is an integer that is incremented with each SELECT statement seen. 522 539 */ 523 540 if( A!=0 ){ 524 541 const char *z = s.z+6; 525 542 int i; 526 - sqlite3_snprintf(sizeof(A->zSelName), A->zSelName, "#%d", 527 - ++pParse->nSelect); 543 + sqlite3_snprintf(sizeof(A->zSelName), A->zSelName,"#%d",++pParse->nSelect); 528 544 while( z[0]==' ' ) z++; 529 545 if( z[0]=='/' && z[1]=='*' ){ 530 546 z += 2; 531 547 while( z[0]==' ' ) z++; 532 548 for(i=0; sqlite3Isalnum(z[i]); i++){} 533 549 sqlite3_snprintf(sizeof(A->zSelName), A->zSelName, "%.*s", i, z); 534 550 } ................................................................................ 663 679 664 680 %type dbnm {Token} 665 681 dbnm(A) ::= . {A.z=0; A.n=0;} 666 682 dbnm(A) ::= DOT nm(X). {A = X;} 667 683 668 684 %type fullname {SrcList*} 669 685 %destructor fullname {sqlite3SrcListDelete(pParse->db, $$);} 670 -fullname(A) ::= nm(X) dbnm(Y). 686 +fullname(A) ::= nm(X). 687 + {A = sqlite3SrcListAppend(pParse->db,0,&X,0); /*A-overwrites-X*/} 688 +fullname(A) ::= nm(X) DOT nm(Y). 671 689 {A = sqlite3SrcListAppend(pParse->db,0,&X,&Y); /*A-overwrites-X*/} 672 690 673 691 %type joinop {int} 674 692 joinop(X) ::= COMMA|JOIN. { X = JT_INNER; } 675 693 joinop(X) ::= JOIN_KW(A) JOIN. 676 694 {X = sqlite3JoinType(pParse,&A,0,0); /*X-overwrites-A*/} 677 695 joinop(X) ::= JOIN_KW(A) nm(B) JOIN. ................................................................................ 759 777 {A = sqlite3PExpr(pParse,TK_LIMIT,X,Y);} 760 778 limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y). 761 779 {A = sqlite3PExpr(pParse,TK_LIMIT,Y,X);} 762 780 763 781 /////////////////////////// The DELETE statement ///////////////////////////// 764 782 // 765 783 %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT 766 -cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W) 784 +cmd ::= with DELETE FROM fullname(X) indexed_opt(I) where_opt(W) 767 785 orderby_opt(O) limit_opt(L). { 768 - sqlite3WithPush(pParse, C, 1); 769 786 sqlite3SrcListIndexedBy(pParse, X, &I); 770 787 sqlite3DeleteFrom(pParse,X,W,O,L); 771 788 } 772 789 %endif 773 790 %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT 774 -cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { 775 - sqlite3WithPush(pParse, C, 1); 791 +cmd ::= with DELETE FROM fullname(X) indexed_opt(I) where_opt(W). { 776 792 sqlite3SrcListIndexedBy(pParse, X, &I); 777 793 sqlite3DeleteFrom(pParse,X,W,0,0); 778 794 } 779 795 %endif 780 796 781 797 %type where_opt {Expr*} 782 798 %destructor where_opt {sqlite3ExprDelete(pParse->db, $$);} ................................................................................ 783 799 784 800 where_opt(A) ::= . {A = 0;} 785 801 where_opt(A) ::= WHERE expr(X). {A = X;} 786 802 787 803 ////////////////////////// The UPDATE command //////////////////////////////// 788 804 // 789 805 %ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT 790 -cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) 806 +cmd ::= with UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) 791 807 where_opt(W) orderby_opt(O) limit_opt(L). { 792 - sqlite3WithPush(pParse, C, 1); 793 808 sqlite3SrcListIndexedBy(pParse, X, &I); 794 809 sqlite3ExprListCheckLength(pParse,Y,"set list"); 795 810 sqlite3Update(pParse,X,Y,W,R,O,L); 796 811 } 797 812 %endif 798 813 %ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT 799 -cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) 814 +cmd ::= with UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y) 800 815 where_opt(W). { 801 - sqlite3WithPush(pParse, C, 1); 802 816 sqlite3SrcListIndexedBy(pParse, X, &I); 803 817 sqlite3ExprListCheckLength(pParse,Y,"set list"); 804 818 sqlite3Update(pParse,X,Y,W,R,0,0); 805 819 } 806 820 %endif 807 821 808 822 %type setlist {ExprList*} ................................................................................ 821 835 } 822 836 setlist(A) ::= LP idlist(X) RP EQ expr(Y). { 823 837 A = sqlite3ExprListAppendVector(pParse, 0, X, Y); 824 838 } 825 839 826 840 ////////////////////////// The INSERT command ///////////////////////////////// 827 841 // 828 -cmd ::= with(W) insert_cmd(R) INTO fullname(X) idlist_opt(F) select(S). { 829 - sqlite3WithPush(pParse, W, 1); 842 +cmd ::= with insert_cmd(R) INTO fullname(X) idlist_opt(F) select(S). { 830 843 sqlite3Insert(pParse, X, S, F, R); 831 844 } 832 -cmd ::= with(W) insert_cmd(R) INTO fullname(X) idlist_opt(F) DEFAULT VALUES. 845 +cmd ::= with insert_cmd(R) INTO fullname(X) idlist_opt(F) DEFAULT VALUES. 833 846 { 834 - sqlite3WithPush(pParse, W, 1); 835 847 sqlite3Insert(pParse, X, 0, F, R); 836 848 } 837 849 838 850 %type insert_cmd {int} 839 851 insert_cmd(A) ::= INSERT orconf(R). {A = R;} 840 852 insert_cmd(A) ::= REPLACE. {A = OE_Replace;} 841 853 ................................................................................ 1485 1497 anylist ::= . 1486 1498 anylist ::= anylist LP anylist RP. 1487 1499 anylist ::= anylist ANY. 1488 1500 %endif SQLITE_OMIT_VIRTUALTABLE 1489 1501 1490 1502 1491 1503 //////////////////////// COMMON TABLE EXPRESSIONS //////////////////////////// 1492 -%type with {With*} 1493 1504 %type wqlist {With*} 1494 -%destructor with {sqlite3WithDelete(pParse->db, $$);} 1495 1505 %destructor wqlist {sqlite3WithDelete(pParse->db, $$);} 1496 1506 1497 -with(A) ::= . {A = 0;} 1507 +with ::= . 1498 1508 %ifndef SQLITE_OMIT_CTE 1499 -with(A) ::= WITH wqlist(W). { A = W; } 1500 -with(A) ::= WITH RECURSIVE wqlist(W). { A = W; } 1509 +with ::= WITH wqlist(W). { sqlite3WithPush(pParse, W, 1); } 1510 +with ::= WITH RECURSIVE wqlist(W). { sqlite3WithPush(pParse, W, 1); } 1501 1511 1502 1512 wqlist(A) ::= nm(X) eidlist_opt(Y) AS LP select(Z) RP. { 1503 1513 A = sqlite3WithAdd(pParse, 0, &X, Y, Z); /*A-overwrites-X*/ 1504 1514 } 1505 1515 wqlist(A) ::= wqlist(A) COMMA nm(X) eidlist_opt(Y) AS LP select(Z) RP. { 1506 1516 A = sqlite3WithAdd(pParse, A, &X, Y, Z); 1507 1517 } 1508 1518 %endif SQLITE_OMIT_CTE
Changes to src/prepare.c.
28 28 const char *zExtra /* Error information */ 29 29 ){ 30 30 sqlite3 *db = pData->db; 31 31 if( !db->mallocFailed && (db->flags & SQLITE_WriteSchema)==0 ){ 32 32 char *z; 33 33 if( zObj==0 ) zObj = "?"; 34 34 z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); 35 - if( zExtra ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); 35 + if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); 36 36 sqlite3DbFree(db, *pData->pzErrMsg); 37 37 *pData->pzErrMsg = z; 38 38 } 39 39 pData->rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_CORRUPT_BKPT; 40 40 } 41 41 42 42 /*
Changes to src/select.c.
17 17 /* 18 18 ** Trace output macros 19 19 */ 20 20 #if SELECTTRACE_ENABLED 21 21 /***/ int sqlite3SelectTrace = 0; 22 22 # define SELECTTRACE(K,P,S,X) \ 23 23 if(sqlite3SelectTrace&(K)) \ 24 - sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",\ 25 - (S)->zSelName,(S)),\ 24 + sqlite3DebugPrintf("%s/%p: ",(S)->zSelName,(S)),\ 26 25 sqlite3DebugPrintf X 27 26 #else 28 27 # define SELECTTRACE(K,P,S,X) 29 28 #endif 30 29 31 30 32 31 /* ................................................................................ 378 377 setJoinExpr(p->x.pList->a[i].pExpr, iTable); 379 378 } 380 379 } 381 380 setJoinExpr(p->pLeft, iTable); 382 381 p = p->pRight; 383 382 } 384 383 } 384 + 385 +/* Undo the work of setJoinExpr(). In the expression tree p, convert every 386 +** term that is marked with EP_FromJoin and iRightJoinTable==iTable into 387 +** an ordinary term that omits the EP_FromJoin mark. 388 +** 389 +** This happens when a LEFT JOIN is simplified into an ordinary JOIN. 390 +*/ 391 +static void unsetJoinExpr(Expr *p, int iTable){ 392 + while( p ){ 393 + if( ExprHasProperty(p, EP_FromJoin) 394 + && (iTable<0 || p->iRightJoinTable==iTable) ){ 395 + ExprClearProperty(p, EP_FromJoin); 396 + } 397 + if( p->op==TK_FUNCTION && p->x.pList ){ 398 + int i; 399 + for(i=0; i<p->x.pList->nExpr; i++){ 400 + unsetJoinExpr(p->x.pList->a[i].pExpr, iTable); 401 + } 402 + } 403 + unsetJoinExpr(p->pLeft, iTable); 404 + p = p->pRight; 405 + } 406 +} 385 407 386 408 /* 387 409 ** This routine processes the join information for a SELECT statement. 388 410 ** ON and USING clauses are converted into extra terms of the WHERE clause. 389 411 ** NATURAL joins also create extra WHERE clause terms. 390 412 ** 391 413 ** The terms of a FROM clause are contained in the Select.pSrc structure. ................................................................................ 3747 3769 ** (the only way this can happen is if the compound sub-query is 3748 3770 ** currently part of pSub->pSrc). See ticket [d11a6e908f]. */ 3749 3771 ExprList *pOrderBy = pSub->pOrderBy; 3750 3772 for(i=0; i<pOrderBy->nExpr; i++){ 3751 3773 pOrderBy->a[i].u.x.iOrderByCol = 0; 3752 3774 } 3753 3775 assert( pParent->pOrderBy==0 ); 3754 - assert( pSub->pPrior==0 ); 3755 3776 pParent->pOrderBy = pOrderBy; 3756 3777 pSub->pOrderBy = 0; 3757 3778 } 3758 3779 pWhere = sqlite3ExprDup(db, pSub->pWhere, 0); 3759 3780 if( isLeftJoin>0 ){ 3760 3781 setJoinExpr(pWhere, iNewParent); 3761 3782 } ................................................................................ 3831 3852 ** to suppress it. **) 3832 3853 ** 3833 3854 ** (2) The inner query is the recursive part of a common table expression. 3834 3855 ** 3835 3856 ** (3) The inner query has a LIMIT clause (since the changes to the WHERE 3836 3857 ** close would change the meaning of the LIMIT). 3837 3858 ** 3838 -** (4) The inner query is the right operand of a LEFT JOIN. (The caller 3839 -** enforces this restriction since this routine does not have enough 3840 -** information to know.) 3859 +** (4) The inner query is the right operand of a LEFT JOIN and the 3860 +** expression to be pushed down does not come from the ON clause 3861 +** on that LEFT JOIN. 3841 3862 ** 3842 3863 ** (5) The WHERE clause expression originates in the ON or USING clause 3843 -** of a LEFT JOIN. 3864 +** of a LEFT JOIN where iCursor is not the right-hand table of that 3865 +** left join. An example: 3866 +** 3867 +** SELECT * 3868 +** FROM (SELECT 1 AS a1 UNION ALL SELECT 2) AS aa 3869 +** JOIN (SELECT 1 AS b2 UNION ALL SELECT 2) AS bb ON (a1=b2) 3870 +** LEFT JOIN (SELECT 8 AS c3 UNION ALL SELECT 9) AS cc ON (b2=2); 3871 +** 3872 +** The correct answer is three rows: (1,1,NULL),(2,2,8),(2,2,9). 3873 +** But if the (b2=2) term were to be pushed down into the bb subquery, 3874 +** then the (1,1,NULL) row would be suppressed. 3844 3875 ** 3845 3876 ** Return 0 if no changes are made and non-zero if one or more WHERE clause 3846 3877 ** terms are duplicated into the subquery. 3847 3878 */ 3848 3879 static int pushDownWhereTerms( 3849 3880 Parse *pParse, /* Parse context (for malloc() and error reporting) */ 3850 3881 Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ 3851 3882 Expr *pWhere, /* The WHERE clause of the outer query */ 3852 - int iCursor /* Cursor number of the subquery */ 3883 + int iCursor, /* Cursor number of the subquery */ 3884 + int isLeftJoin /* True if pSubq is the right term of a LEFT JOIN */ 3853 3885 ){ 3854 3886 Expr *pNew; 3855 3887 int nChng = 0; 3856 3888 if( pWhere==0 ) return 0; 3857 3889 if( pSubq->selFlags & SF_Recursive ) return 0; /* restriction (2) */ 3858 3890 3859 3891 #ifdef SQLITE_DEBUG ................................................................................ 3869 3901 } 3870 3902 #endif 3871 3903 3872 3904 if( pSubq->pLimit!=0 ){ 3873 3905 return 0; /* restriction (3) */ 3874 3906 } 3875 3907 while( pWhere->op==TK_AND ){ 3876 - nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, iCursor); 3908 + nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, 3909 + iCursor, isLeftJoin); 3877 3910 pWhere = pWhere->pLeft; 3878 3911 } 3879 - if( ExprHasProperty(pWhere,EP_FromJoin) ) return 0; /* restriction (5) */ 3912 + if( isLeftJoin 3913 + && (ExprHasProperty(pWhere,EP_FromJoin)==0 3914 + || pWhere->iRightJoinTable!=iCursor) 3915 + ){ 3916 + return 0; /* restriction (4) */ 3917 + } 3918 + if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){ 3919 + return 0; /* restriction (5) */ 3920 + } 3880 3921 if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ 3881 3922 nChng++; 3882 3923 while( pSubq ){ 3883 3924 SubstContext x; 3884 3925 pNew = sqlite3ExprDup(pParse->db, pWhere, 0); 3926 + unsetJoinExpr(pNew, -1); 3885 3927 x.pParse = pParse; 3886 3928 x.iTable = iCursor; 3887 3929 x.iNewTable = iCursor; 3888 3930 x.isLeftJoin = 0; 3889 3931 x.pEList = pSubq->pEList; 3890 3932 pNew = substExpr(&x, pNew); 3891 3933 if( pSubq->selFlags & SF_Aggregate ){ ................................................................................ 4332 4374 } 4333 4375 assert( p->pSrc!=0 ); 4334 4376 if( (selFlags & SF_Expanded)!=0 ){ 4335 4377 return WRC_Prune; 4336 4378 } 4337 4379 pTabList = p->pSrc; 4338 4380 pEList = p->pEList; 4339 - if( OK_IF_ALWAYS_TRUE(p->pWith) ){ 4340 - sqlite3WithPush(pParse, p->pWith, 0); 4341 - } 4381 + sqlite3WithPush(pParse, p->pWith, 0); 4342 4382 4343 4383 /* Make sure cursor numbers have been assigned to all entries in 4344 4384 ** the FROM clause of the SELECT statement. 4345 4385 */ 4346 4386 sqlite3SrcListAssignCursors(pParse, pTabList); 4347 4387 4348 4388 /* Look up every table named in the FROM clause of the select. If ................................................................................ 4909 4949 ); 4910 4950 } 4911 4951 } 4912 4952 #else 4913 4953 # define explainSimpleCount(a,b,c) 4914 4954 #endif 4915 4955 4916 -/* 4917 -** Context object for havingToWhereExprCb(). 4918 -*/ 4919 -struct HavingToWhereCtx { 4920 - Expr **ppWhere; 4921 - ExprList *pGroupBy; 4922 -}; 4923 - 4924 4956 /* 4925 4957 ** sqlite3WalkExpr() callback used by havingToWhere(). 4926 4958 ** 4927 4959 ** If the node passed to the callback is a TK_AND node, return 4928 4960 ** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes. 4929 4961 ** 4930 4962 ** Otherwise, return WRC_Prune. In this case, also check if the 4931 4963 ** sub-expression matches the criteria for being moved to the WHERE 4932 4964 ** clause. If so, add it to the WHERE clause and replace the sub-expression 4933 4965 ** within the HAVING expression with a constant "1". 4934 4966 */ 4935 4967 static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ 4936 4968 if( pExpr->op!=TK_AND ){ 4937 - struct HavingToWhereCtx *p = pWalker->u.pHavingCtx; 4938 - if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, p->pGroupBy) ){ 4969 + Select *pS = pWalker->u.pSelect; 4970 + if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){ 4939 4971 sqlite3 *db = pWalker->pParse->db; 4940 4972 Expr *pNew = sqlite3ExprAlloc(db, TK_INTEGER, &sqlite3IntTokens[1], 0); 4941 4973 if( pNew ){ 4942 - Expr *pWhere = *(p->ppWhere); 4974 + Expr *pWhere = pS->pWhere; 4943 4975 SWAP(Expr, *pNew, *pExpr); 4944 4976 pNew = sqlite3ExprAnd(db, pWhere, pNew); 4945 - *(p->ppWhere) = pNew; 4977 + pS->pWhere = pNew; 4978 + pWalker->eCode = 1; 4946 4979 } 4947 4980 } 4948 4981 return WRC_Prune; 4949 4982 } 4950 4983 return WRC_Continue; 4951 4984 } 4952 4985 ................................................................................ 4961 4994 ** 4962 4995 ** SELECT * FROM <tables> WHERE a=? AND b=? GROUP BY b HAVING c=? 4963 4996 ** 4964 4997 ** A term of the HAVING expression is eligible for transfer if it consists 4965 4998 ** entirely of constants and expressions that are also GROUP BY terms that 4966 4999 ** use the "BINARY" collation sequence. 4967 5000 */ 4968 -static void havingToWhere( 4969 - Parse *pParse, 4970 - ExprList *pGroupBy, 4971 - Expr *pHaving, 4972 - Expr **ppWhere 4973 -){ 4974 - struct HavingToWhereCtx sCtx; 5001 +static void havingToWhere(Parse *pParse, Select *p){ 4975 5002 Walker sWalker; 4976 - 4977 - sCtx.ppWhere = ppWhere; 4978 - sCtx.pGroupBy = pGroupBy; 4979 - 4980 5003 memset(&sWalker, 0, sizeof(sWalker)); 4981 5004 sWalker.pParse = pParse; 4982 5005 sWalker.xExprCallback = havingToWhereExprCb; 4983 - sWalker.u.pHavingCtx = &sCtx; 4984 - sqlite3WalkExpr(&sWalker, pHaving); 5006 + sWalker.u.pSelect = p; 5007 + sqlite3WalkExpr(&sWalker, p->pHaving); 5008 +#if SELECTTRACE_ENABLED 5009 + if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){ 5010 + SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); 5011 + sqlite3TreeViewSelect(0, p, 0); 5012 + } 5013 +#endif 4985 5014 } 4986 5015 4987 5016 /* 4988 5017 ** Check to see if the pThis entry of pTabList is a self-join of a prior view. 4989 5018 ** If it is, then return the SrcList_item for the prior view. If it is not, 4990 5019 ** then return 0. 4991 5020 */ ................................................................................ 5138 5167 db = pParse->db; 5139 5168 if( p==0 || db->mallocFailed || pParse->nErr ){ 5140 5169 return 1; 5141 5170 } 5142 5171 if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; 5143 5172 memset(&sAggInfo, 0, sizeof(sAggInfo)); 5144 5173 #if SELECTTRACE_ENABLED 5145 - pParse->nSelectIndent++; 5146 5174 SELECTTRACE(1,pParse,p, ("begin processing:\n")); 5147 5175 if( sqlite3SelectTrace & 0x100 ){ 5148 5176 sqlite3TreeViewSelect(0, p, 0); 5149 5177 } 5150 5178 #endif 5151 5179 5152 5180 assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo ); ................................................................................ 5184 5212 ** does not already exist */ 5185 5213 v = sqlite3GetVdbe(pParse); 5186 5214 if( v==0 ) goto select_end; 5187 5215 if( pDest->eDest==SRT_Output ){ 5188 5216 generateColumnNames(pParse, p); 5189 5217 } 5190 5218 5191 - /* Try to flatten subqueries in the FROM clause up into the main query 5219 + /* Try to various optimizations (flattening subqueries, and strength 5220 + ** reduction of join operators) in the FROM clause up into the main query 5192 5221 */ 5193 5222 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) 5194 5223 for(i=0; !p->pPrior && i<pTabList->nSrc; i++){ 5195 5224 struct SrcList_item *pItem = &pTabList->a[i]; 5196 5225 Select *pSub = pItem->pSelect; 5197 5226 Table *pTab = pItem->pTab; 5227 + 5228 + /* Convert LEFT JOIN into JOIN if there are terms of the right table 5229 + ** of the LEFT JOIN used in the WHERE clause. 5230 + */ 5231 + if( (pItem->fg.jointype & JT_LEFT)!=0 5232 + && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor) 5233 + && OptimizationEnabled(db, SQLITE_SimplifyJoin) 5234 + ){ 5235 + SELECTTRACE(0x100,pParse,p, 5236 + ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); 5237 + pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); 5238 + unsetJoinExpr(p->pWhere, pItem->iCursor); 5239 + } 5240 + 5241 + /* No futher action if this term of the FROM clause is no a subquery */ 5198 5242 if( pSub==0 ) continue; 5199 5243 5200 5244 /* Catch mismatch in the declared columns of a view and the number of 5201 5245 ** columns in the SELECT on the RHS */ 5202 5246 if( pTab->nCol!=pSub->pEList->nExpr ){ 5203 5247 sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d", 5204 5248 pTab->nCol, pTab->zName, pSub->pEList->nExpr); ................................................................................ 5259 5303 ** procedure. 5260 5304 */ 5261 5305 if( p->pPrior ){ 5262 5306 rc = multiSelect(pParse, p, pDest); 5263 5307 explainSetInteger(pParse->iSelectId, iRestoreSelectId); 5264 5308 #if SELECTTRACE_ENABLED 5265 5309 SELECTTRACE(1,pParse,p,("end compound-select processing\n")); 5266 - pParse->nSelectIndent--; 5267 5310 #endif 5268 5311 return rc; 5269 5312 } 5270 5313 #endif 5271 5314 5272 5315 /* For each term in the FROM clause, do two things: 5273 5316 ** (1) Authorized unreferenced tables ................................................................................ 5332 5375 ** an exact limit. 5333 5376 */ 5334 5377 pParse->nHeight += sqlite3SelectExprHeight(p); 5335 5378 5336 5379 /* Make copies of constant WHERE-clause terms in the outer query down 5337 5380 ** inside the subquery. This can help the subquery to run more efficiently. 5338 5381 */ 5339 - if( (pItem->fg.jointype & JT_OUTER)==0 5340 - && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor) 5382 + if( OptimizationEnabled(db, SQLITE_PushDown) 5383 + && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, 5384 + (pItem->fg.jointype & JT_OUTER)!=0) 5341 5385 ){ 5342 5386 #if SELECTTRACE_ENABLED 5343 5387 if( sqlite3SelectTrace & 0x100 ){ 5344 5388 SELECTTRACE(0x100,pParse,p,("After WHERE-clause push-down:\n")); 5345 5389 sqlite3TreeViewSelect(0, p, 0); 5346 5390 } 5347 5391 #endif 5392 + }else{ 5393 + SELECTTRACE(0x100,pParse,p,("Push-down not possible\n")); 5348 5394 } 5349 5395 5350 5396 zSavedAuthContext = pParse->zAuthContext; 5351 5397 pParse->zAuthContext = pItem->zName; 5352 5398 5353 5399 /* Generate code to implement the subquery 5354 5400 ** ................................................................................ 5543 5589 if( !isAgg && pGroupBy==0 ){ 5544 5590 /* No aggregate functions and no GROUP BY clause */ 5545 5591 u16 wctrlFlags = (sDistinct.isTnct ? WHERE_WANT_DISTINCT : 0); 5546 5592 assert( WHERE_USE_LIMIT==SF_FixedLimit ); 5547 5593 wctrlFlags |= p->selFlags & SF_FixedLimit; 5548 5594 5549 5595 /* Begin the database scan. */ 5596 + SELECTTRACE(1,pParse,p,("WhereBegin\n")); 5550 5597 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, 5551 5598 p->pEList, wctrlFlags, p->nSelectRow); 5552 5599 if( pWInfo==0 ) goto select_end; 5553 5600 if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ 5554 5601 p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); 5555 5602 } 5556 5603 if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ ................................................................................ 5644 5691 sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; 5645 5692 sAggInfo.pGroupBy = pGroupBy; 5646 5693 sqlite3ExprAnalyzeAggList(&sNC, pEList); 5647 5694 sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); 5648 5695 if( pHaving ){ 5649 5696 if( pGroupBy ){ 5650 5697 assert( pWhere==p->pWhere ); 5651 - havingToWhere(pParse, pGroupBy, pHaving, &p->pWhere); 5698 + assert( pHaving==p->pHaving ); 5699 + assert( pGroupBy==p->pGroupBy ); 5700 + havingToWhere(pParse, p); 5652 5701 pWhere = p->pWhere; 5653 5702 } 5654 5703 sqlite3ExprAnalyzeAggregates(&sNC, pHaving); 5655 5704 } 5656 5705 sAggInfo.nAccumulator = sAggInfo.nColumn; 5657 5706 if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){ 5658 5707 minMaxFlag = minMaxQuery(db, sAggInfo.aFunc[0].pExpr, &pMinMaxOrderBy); ................................................................................ 5731 5780 5732 5781 /* Begin a loop that will extract all source rows in GROUP BY order. 5733 5782 ** This might involve two separate loops with an OP_Sort in between, or 5734 5783 ** it might be a single loop that uses an index to extract information 5735 5784 ** in the right order to begin with. 5736 5785 */ 5737 5786 sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); 5787 + SELECTTRACE(1,pParse,p,("WhereBegin\n")); 5738 5788 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, 5739 5789 WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 5740 5790 ); 5741 5791 if( pWInfo==0 ) goto select_end; 5742 5792 if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ 5743 5793 /* The optimizer is able to deliver rows in group by order so 5744 5794 ** we do not have to sort. The OP_OpenEphemeral table will be ................................................................................ 5986 6036 ** minMaxFlag will have been previously set to either 5987 6037 ** WHERE_ORDERBY_MIN or WHERE_ORDERBY_MAX and pMinMaxOrderBy will 5988 6038 ** be an appropriate ORDER BY expression for the optimization. 5989 6039 */ 5990 6040 assert( minMaxFlag==WHERE_ORDERBY_NORMAL || pMinMaxOrderBy!=0 ); 5991 6041 assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); 5992 6042 6043 + SELECTTRACE(1,pParse,p,("WhereBegin\n")); 5993 6044 pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, 5994 6045 0, minMaxFlag, 0); 5995 6046 if( pWInfo==0 ){ 5996 6047 goto select_end; 5997 6048 } 5998 6049 updateAccumulator(pParse, &sAggInfo); 5999 6050 if( sqlite3WhereIsOrdered(pWInfo)>0 ){ ................................................................................ 6041 6092 select_end: 6042 6093 explainSetInteger(pParse->iSelectId, iRestoreSelectId); 6043 6094 sqlite3ExprListDelete(db, pMinMaxOrderBy); 6044 6095 sqlite3DbFree(db, sAggInfo.aCol); 6045 6096 sqlite3DbFree(db, sAggInfo.aFunc); 6046 6097 #if SELECTTRACE_ENABLED 6047 6098 SELECTTRACE(1,pParse,p,("end processing\n")); 6048 - pParse->nSelectIndent--; 6049 6099 #endif 6050 6100 return rc; 6051 6101 }
Changes to src/shell.c.in.
128 128 #if defined(_WIN32) || defined(WIN32) 129 129 # include <io.h> 130 130 # include <fcntl.h> 131 131 # define isatty(h) _isatty(h) 132 132 # ifndef access 133 133 # define access(f,m) _access((f),(m)) 134 134 # endif 135 +# ifndef unlink 136 +# define unlink _unlink 137 +# endif 135 138 # undef popen 136 139 # define popen _popen 137 140 # undef pclose 138 141 # define pclose _pclose 139 142 #else 140 143 /* Make sure isatty() has a prototype. */ 141 144 extern int isatty(int); ................................................................................ 2282 2285 sqlite3_stmt *pStmt = pArg->pStmt; 2283 2286 char z[100]; 2284 2287 nCol = sqlite3_column_count(pStmt); 2285 2288 raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol); 2286 2289 for(i=0; i<nCol; i++){ 2287 2290 sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x); 2288 2291 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i)); 2292 +#ifndef SQLITE_OMIT_DECLTYPE 2289 2293 sqlite3_snprintf(30, z+x, "declared type:"); 2290 2294 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_decltype(pStmt, i)); 2291 - #ifdef SQLITE_ENABLE_COLUMN_METADATA 2295 +#endif 2296 +#ifdef SQLITE_ENABLE_COLUMN_METADATA 2292 2297 sqlite3_snprintf(30, z+x, "database name:"); 2293 2298 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_database_name(pStmt,i)); 2294 2299 sqlite3_snprintf(30, z+x, "table name:"); 2295 2300 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_table_name(pStmt,i)); 2296 2301 sqlite3_snprintf(30, z+x, "origin name:"); 2297 2302 utf8_printf(out, "%-36s %s\n", z, sqlite3_column_origin_name(pStmt,i)); 2298 - #endif 2303 +#endif 2299 2304 } 2300 - } 2305 + } 2301 2306 2302 2307 displayStatLine(pArg, "Memory Used:", 2303 2308 "%lld (max %lld) bytes", SQLITE_STATUS_MEMORY_USED, bReset); 2304 2309 displayStatLine(pArg, "Number of Outstanding Allocations:", 2305 2310 "%lld (max %lld)", SQLITE_STATUS_MALLOC_COUNT, bReset); 2306 2311 if( pArg->shellFlgs & SHFLG_Pagecache ){ 2307 2312 displayStatLine(pArg, "Number of Pcache Pages Used:", ................................................................................ 2873 2878 explain_data_prepare(pArg, pExplain); 2874 2879 exec_prepared_stmt(pArg, pExplain); 2875 2880 explain_data_delete(pArg); 2876 2881 } 2877 2882 sqlite3_finalize(pExplain); 2878 2883 sqlite3_free(zEQP); 2879 2884 } 2880 - sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, triggerEQP, 0); 2885 + if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){ 2886 + sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0); 2887 + /* Reprepare pStmt before reactiving trace modes */ 2888 + sqlite3_finalize(pStmt); 2889 + sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); 2890 + } 2881 2891 restore_debug_trace_modes(); 2882 2892 } 2883 2893 2884 2894 if( pArg ){ 2885 2895 pArg->cMode = pArg->mode; 2886 2896 if( pArg->autoExplain 2887 2897 && sqlite3_column_count(pStmt)==8 ................................................................................ 3719 3729 if( f==0 ){ 3720 3730 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile); 3721 3731 } 3722 3732 } 3723 3733 return f; 3724 3734 } 3725 3735 3726 -#if !defined(SQLITE_UNTESTABLE) 3727 3736 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) 3728 3737 /* 3729 3738 ** A routine for handling output from sqlite3_trace(). 3730 3739 */ 3731 3740 static int sql_trace_callback( 3732 3741 unsigned mType, 3733 3742 void *pArg, ................................................................................ 3741 3750 const char *z = (const char*)pX; 3742 3751 int i = strlen30(z); 3743 3752 while( i>0 && z[i-1]==';' ){ i--; } 3744 3753 utf8_printf(f, "%.*s;\n", i, z); 3745 3754 } 3746 3755 return 0; 3747 3756 } 3748 -#endif 3749 3757 #endif 3750 3758 3751 3759 /* 3752 3760 ** A no-op routine that runs with the ".breakpoint" doc-command. This is 3753 3761 ** a useful spot to set a debugger breakpoint. 3754 3762 */ 3755 3763 static void test_breakpoint(void){ ................................................................................ 5325 5333 if( bUpdate==0 ){ 5326 5334 rc = arExecSql(pAr, zDrop); 5327 5335 if( rc!=SQLITE_OK ) goto end_ar_transaction; 5328 5336 } 5329 5337 rc = arExecSql(pAr, zCreate); 5330 5338 } 5331 5339 for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){ 5332 - char *zSql = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab, 5340 + char *zSql2 = sqlite3_mprintf(zInsertFmt[pAr->bZip], zTab, 5333 5341 pAr->bVerbose ? "shell_putsnl(name)" : "name", 5334 5342 pAr->azArg[i], pAr->zDir); 5335 - rc = arExecSql(pAr, zSql); 5336 - sqlite3_free(zSql); 5343 + rc = arExecSql(pAr, zSql2); 5344 + sqlite3_free(zSql2); 5337 5345 } 5338 5346 end_ar_transaction: 5339 5347 if( rc!=SQLITE_OK ){ 5340 5348 arExecSql(pAr, "ROLLBACK TO ar; RELEASE ar;"); 5341 5349 }else{ 5342 5350 rc = arExecSql(pAr, "RELEASE ar;"); 5343 5351 if( pAr->bZip && pAr->zFile ){ ................................................................................ 6607 6615 }else{ 6608 6616 raw_printf(stderr, "Usage: .schema ?--indent? ?LIKE-PATTERN?\n"); 6609 6617 rc = 1; 6610 6618 goto meta_command_exit; 6611 6619 } 6612 6620 } 6613 6621 if( zName!=0 ){ 6614 - int isMaster = sqlite3_strlike(zName, "sqlite_master", 0)==0; 6615 - if( isMaster || sqlite3_strlike(zName,"sqlite_temp_master",0)==0 ){ 6622 + int isMaster = sqlite3_strlike(zName, "sqlite_master", '\\')==0; 6623 + if( isMaster || sqlite3_strlike(zName,"sqlite_temp_master", '\\')==0 ){ 6616 6624 char *new_argv[2], *new_colv[2]; 6617 6625 new_argv[0] = sqlite3_mprintf( 6618 6626 "CREATE TABLE %s (\n" 6619 6627 " type text,\n" 6620 6628 " name text,\n" 6621 6629 " tbl_name text,\n" 6622 6630 " rootpage integer,\n" ................................................................................ 6668 6676 " UNION ALL SELECT shell_module_schema(name)," 6669 6677 " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0); 6670 6678 } 6671 6679 #endif 6672 6680 appendText(&sSelect, ") WHERE ", 0); 6673 6681 if( zName ){ 6674 6682 char *zQarg = sqlite3_mprintf("%Q", zName); 6683 + int bGlob = strchr(zName, '*') != 0 || strchr(zName, '?') != 0 || 6684 + strchr(zName, '[') != 0; 6675 6685 if( strchr(zName, '.') ){ 6676 6686 appendText(&sSelect, "lower(printf('%s.%s',sname,tbl_name))", 0); 6677 6687 }else{ 6678 6688 appendText(&sSelect, "lower(tbl_name)", 0); 6679 6689 } 6680 - appendText(&sSelect, strchr(zName, '*') ? " GLOB " : " LIKE ", 0); 6690 + appendText(&sSelect, bGlob ? " GLOB " : " LIKE ", 0); 6681 6691 appendText(&sSelect, zQarg, 0); 6692 + if( !bGlob ){ 6693 + appendText(&sSelect, " ESCAPE '\\' ", 0); 6694 + } 6682 6695 appendText(&sSelect, " AND ", 0); 6683 6696 sqlite3_free(zQarg); 6684 6697 } 6685 6698 appendText(&sSelect, "type!='meta' AND sql IS NOT NULL" 6686 6699 " ORDER BY snum, rowid", 0); 6687 6700 if( bDebug ){ 6688 6701 utf8_printf(p->out, "SQL: %s;\n", sSelect.z); ................................................................................ 7089 7102 }else if( zLike ){ 7090 7103 raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n"); 7091 7104 rc = 1; 7092 7105 goto meta_command_exit; 7093 7106 }else{ 7094 7107 zLike = z; 7095 7108 bSeparate = 1; 7096 - if( sqlite3_strlike("sqlite_%", zLike, 0)==0 ) bSchema = 1; 7109 + if( sqlite3_strlike("sqlite\\_%", zLike, '\\')==0 ) bSchema = 1; 7097 7110 } 7098 7111 } 7099 7112 if( bSchema ){ 7100 7113 zSql = "SELECT lower(name) FROM sqlite_master" 7101 7114 " WHERE type='table' AND coalesce(rootpage,0)>1" 7102 7115 " UNION ALL SELECT 'sqlite_master'" 7103 7116 " ORDER BY 1 collate nocase"; ................................................................................ 8395 8408 memcpy(data.colSeparator,",",2); 8396 8409 #ifdef SQLITE_HAVE_ZLIB 8397 8410 }else if( strcmp(z,"-zip")==0 ){ 8398 8411 data.openMode = SHELL_OPEN_ZIPFILE; 8399 8412 #endif 8400 8413 }else if( strcmp(z,"-append")==0 ){ 8401 8414 data.openMode = SHELL_OPEN_APPENDVFS; 8415 + }else if( strcmp(z,"-readonly")==0 ){ 8416 + data.openMode = SHELL_OPEN_READONLY; 8402 8417 }else if( strcmp(z,"-ascii")==0 ){ 8403 8418 data.mode = MODE_Ascii; 8404 8419 sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator, 8405 8420 SEP_Unit); 8406 8421 sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator, 8407 8422 SEP_Record); 8408 8423 }else if( strcmp(z,"-separator")==0 ){
Changes to src/sqlite.h.in.
1061 1061 ** The [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE] opcode causes all write 1062 1062 ** operations since the previous successful call to 1063 1063 ** [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE] to be rolled back. 1064 1064 ** ^This file control takes the file descriptor out of batch write mode 1065 1065 ** so that all subsequent write operations are independent. 1066 1066 ** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without 1067 1067 ** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE]. 1068 +** 1069 +** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]] 1070 +** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain 1071 +** a file lock using the xLock or xShmLock methods of the VFS to wait 1072 +** for up to M milliseconds before failing, where M is the single 1073 +** unsigned integer parameter. 1068 1074 ** </ul> 1069 1075 */ 1070 1076 #define SQLITE_FCNTL_LOCKSTATE 1 1071 1077 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 1072 1078 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 1073 1079 #define SQLITE_FCNTL_LAST_ERRNO 4 1074 1080 #define SQLITE_FCNTL_SIZE_HINT 5 ................................................................................ 1095 1101 #define SQLITE_FCNTL_VFS_POINTER 27 1096 1102 #define SQLITE_FCNTL_JOURNAL_POINTER 28 1097 1103 #define SQLITE_FCNTL_WIN32_GET_HANDLE 29 1098 1104 #define SQLITE_FCNTL_PDB 30 1099 1105 #define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31 1100 1106 #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 1101 1107 #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33 1108 +#define SQLITE_FCNTL_LOCK_TIMEOUT 34 1102 1109 1103 1110 /* deprecated names */ 1104 1111 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE 1105 1112 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE 1106 1113 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO 1107 1114 1108 1115 ................................................................................ 2051 2058 ** 2052 2059 ** <dt>SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE</dt> 2053 2060 ** <dd> Usually, when a database in wal mode is closed or detached from a 2054 2061 ** database handle, SQLite checks if this will mean that there are now no 2055 2062 ** connections at all to the database. If so, it performs a checkpoint 2056 2063 ** operation before closing the connection. This option may be used to 2057 2064 ** override this behaviour. The first parameter passed to this operation 2058 -** is an integer - non-zero to disable checkpoints-on-close, or zero (the 2059 -** default) to enable them. The second parameter is a pointer to an integer 2065 +** is an integer - positive to disable checkpoints-on-close, or zero (the 2066 +** default) to enable them, and negative to leave the setting unchanged. 2067 +** The second parameter is a pointer to an integer 2060 2068 ** into which is written 0 or 1 to indicate whether checkpoints-on-close 2061 2069 ** have been disabled - 0 if they are not disabled, 1 if they are. 2062 2070 ** </dd> 2071 +** 2063 2072 ** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt> 2064 2073 ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates 2065 2074 ** the [query planner stability guarantee] (QPSG). When the QPSG is active, 2066 2075 ** a single SQL query statement will always use the same algorithm regardless 2067 2076 ** of values of [bound parameters].)^ The QPSG disables some query optimizations 2068 2077 ** that look at the values of bound parameters, which can make some queries 2069 2078 ** slower. But the QPSG has the advantage of more predictable behavior. With 2070 2079 ** the QPSG active, SQLite will always use the same query plan in the field as 2071 2080 ** was used during testing in the lab. 2081 +** The first argument to this setting is an integer which is 0 to disable 2082 +** the QPSG, positive to enable QPSG, or negative to leave the setting 2083 +** unchanged. The second parameter is a pointer to an integer into which 2084 +** is written 0 or 1 to indicate whether the QPSG is disabled or enabled 2085 +** following this call. 2072 2086 ** </dd> 2087 +** 2073 2088 ** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt> 2074 2089 ** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not 2075 2090 ** include output for any operations performed by trigger programs. This 2076 2091 ** option is used to set or clear (the default) a flag that governs this 2077 2092 ** behavior. The first parameter passed to this operation is an integer - 2078 -** non-zero to enable output for trigger programs, or zero to disable it. 2093 +** positive to enable output for trigger programs, or zero to disable it, 2094 +** or negative to leave the setting unchanged. 2079 2095 ** The second parameter is a pointer to an integer into which is written 2080 2096 ** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if 2081 2097 ** it is not disabled, 1 if it is. 2082 2098 ** </dd> 2083 2099 ** </dl> 2084 2100 */ 2085 2101 #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ ................................................................................ 8799 8815 */ 8800 8816 #define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */ 8801 8817 8802 8818 /* 8803 8819 ** CAPI3REF: Deserialize a database 8804 8820 ** 8805 8821 ** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the 8806 -** [database connection] D to disconnection from database S and then 8822 +** [database connection] D to disconnect from database S and then 8807 8823 ** reopen S as an in-memory database based on the serialization contained 8808 8824 ** in P. The serialized database P is N bytes in size. M is the size of 8809 8825 ** the buffer P, which might be larger than N. If M is larger than N, and 8810 8826 ** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is 8811 8827 ** permitted to add content to the in-memory database as long as the total 8812 8828 ** size does not exceed M bytes. 8813 8829 ** ................................................................................ 8846 8862 ** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization 8847 8863 ** in the P argument is held in memory obtained from [sqlite3_malloc64()] 8848 8864 ** and that SQLite should take ownership of this memory and automatically 8849 8865 ** free it when it has finished using it. Without this flag, the caller 8850 8866 ** is resposible for freeing any dynamically allocated memory. 8851 8867 ** 8852 8868 ** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to 8853 -** grow the size of the database usign calls to [sqlite3_realloc64()]. This 8869 +** grow the size of the database using calls to [sqlite3_realloc64()]. This 8854 8870 ** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used. 8855 8871 ** Without this flag, the deserialized database cannot increase in size beyond 8856 8872 ** the number of bytes specified by the M parameter. 8857 8873 ** 8858 8874 ** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database 8859 8875 ** should be treated as read-only. 8860 8876 */
Changes to src/sqliteInt.h.
957 957 ** The sqlite.busyHandler member of the sqlite struct contains the busy 958 958 ** callback for the database handle. Each pager opened via the sqlite 959 959 ** handle is passed a pointer to sqlite.busyHandler. The busy-handler 960 960 ** callback is currently invoked only from within pager.c. 961 961 */ 962 962 typedef struct BusyHandler BusyHandler; 963 963 struct BusyHandler { 964 - int (*xFunc)(void *,int); /* The busy callback */ 965 - void *pArg; /* First arg to busy callback */ 966 - int nBusy; /* Incremented with each busy call */ 964 + int (*xBusyHandler)(void *,int); /* The busy callback */ 965 + void *pBusyArg; /* First arg to busy callback */ 966 + int nBusy; /* Incremented with each busy call */ 967 + u8 bExtraFileArg; /* Include sqlite3_file as callback arg */ 967 968 }; 968 969 969 970 /* 970 971 ** Name of the master database table. The master database table 971 972 ** is a special table that holds the names and attributes of all 972 973 ** user tables and indices. 973 974 */ ................................................................................ 1528 1529 #define SQLITE_OrderByIdxJoin 0x0040 /* ORDER BY of joins via index */ 1529 1530 #define SQLITE_Transitive 0x0080 /* Transitive constraints */ 1530 1531 #define SQLITE_OmitNoopJoin 0x0100 /* Omit unused tables in joins */ 1531 1532 #define SQLITE_CountOfView 0x0200 /* The count-of-view optimization */ 1532 1533 #define SQLITE_CursorHints 0x0400 /* Add OP_CursorHint opcodes */ 1533 1534 #define SQLITE_Stat34 0x0800 /* Use STAT3 or STAT4 data */ 1534 1535 /* TH3 expects the Stat34 ^^^^^^ value to be 0x0800. Don't change it */ 1536 +#define SQLITE_PushDown 0x1000 /* The push-down optimization */ 1537 +#define SQLITE_SimplifyJoin 0x2000 /* Convert LEFT JOIN to JOIN */ 1535 1538 #define SQLITE_AllOpts 0xffff /* All optimizations */ 1536 1539 1537 1540 /* 1538 1541 ** Macros for testing whether or not optimizations are enabled or disabled. 1539 1542 */ 1540 1543 #define OptimizationDisabled(db, mask) (((db)->dbOptFlags&(mask))!=0) 1541 1544 #define OptimizationEnabled(db, mask) (((db)->dbOptFlags&(mask))==0) ................................................................................ 2989 2992 yDbMask writeMask; /* Start a write transaction on these databases */ 2990 2993 yDbMask cookieMask; /* Bitmask of schema verified databases */ 2991 2994 int regRowid; /* Register holding rowid of CREATE TABLE entry */ 2992 2995 int regRoot; /* Register holding root page number for new objects */ 2993 2996 int nMaxArg; /* Max args passed to user function by sub-program */ 2994 2997 #if SELECTTRACE_ENABLED 2995 2998 int nSelect; /* Number of SELECT statements seen */ 2996 - int nSelectIndent; /* How far to indent SELECTTRACE() output */ 2997 2999 #endif 2998 3000 #ifndef SQLITE_OMIT_SHARED_CACHE 2999 3001 int nTableLock; /* Number of locks in aTableLock */ 3000 3002 TableLock *aTableLock; /* Required table locks for shared-cache mode */ 3001 3003 #endif 3002 3004 AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ 3003 3005 Parse *pToplevel; /* Parse structure for main program (or NULL) */ ................................................................................ 3353 3355 int n; /* A counter */ 3354 3356 int iCur; /* A cursor number */ 3355 3357 SrcList *pSrcList; /* FROM clause */ 3356 3358 struct SrcCount *pSrcCount; /* Counting column references */ 3357 3359 struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ 3358 3360 int *aiCol; /* array of column indexes */ 3359 3361 struct IdxCover *pIdxCover; /* Check for index coverage */ 3360 - struct IdxExprTrans *pIdxTrans; /* Convert indexed expr to column */ 3362 + struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */ 3361 3363 ExprList *pGroupBy; /* GROUP BY clause */ 3362 - struct HavingToWhereCtx *pHavingCtx; /* HAVING to WHERE clause ctx */ 3364 + Select *pSelect; /* HAVING to WHERE clause ctx */ 3363 3365 } u; 3364 3366 }; 3365 3367 3366 3368 /* Forward declarations */ 3367 3369 int sqlite3WalkExpr(Walker*, Expr*); 3368 3370 int sqlite3WalkExprList(Walker*, ExprList*); 3369 3371 int sqlite3WalkSelect(Walker*, Select*); ................................................................................ 3819 3821 void sqlite3Vacuum(Parse*,Token*); 3820 3822 int sqlite3RunVacuum(char**, sqlite3*, int); 3821 3823 char *sqlite3NameFromToken(sqlite3*, Token*); 3822 3824 int sqlite3ExprCompare(Parse*,Expr*, Expr*, int); 3823 3825 int sqlite3ExprCompareSkip(Expr*, Expr*, int); 3824 3826 int sqlite3ExprListCompare(ExprList*, ExprList*, int); 3825 3827 int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int); 3828 +int sqlite3ExprImpliesNonNullRow(Expr*,int); 3826 3829 void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); 3827 3830 void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); 3828 3831 int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); 3829 3832 int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); 3830 3833 Vdbe *sqlite3GetVdbe(Parse*); 3831 3834 #ifndef SQLITE_UNTESTABLE 3832 3835 void sqlite3PrngSaveState(void); ................................................................................ 4097 4100 int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); 4098 4101 void sqlite3ColumnDefault(Vdbe *, Table *, int, int); 4099 4102 void sqlite3AlterFinishAddColumn(Parse *, Token *); 4100 4103 void sqlite3AlterBeginAddColumn(Parse *, SrcList *); 4101 4104 CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); 4102 4105 char sqlite3AffinityType(const char*, u8*); 4103 4106 void sqlite3Analyze(Parse*, Token*, Token*); 4104 -int sqlite3InvokeBusyHandler(BusyHandler*); 4107 +int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*); 4105 4108 int sqlite3FindDb(sqlite3*, Token*); 4106 4109 int sqlite3FindDbName(sqlite3 *, const char *); 4107 4110 int sqlite3AnalysisLoad(sqlite3*,int iDB); 4108 4111 void sqlite3DeleteIndexSamples(sqlite3*,Index*); 4109 4112 void sqlite3DefaultRowEst(Index*); 4110 4113 void sqlite3RegisterLikeFunctions(sqlite3*, int); 4111 4114 int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
Changes to src/treeview.c.
133 133 pView = sqlite3TreeViewPush(pView, moreToFollow); 134 134 if( p->pWith ){ 135 135 sqlite3TreeViewWith(pView, p->pWith, 1); 136 136 cnt = 1; 137 137 sqlite3TreeViewPush(pView, 1); 138 138 } 139 139 do{ 140 +#if SELECTTRACE_ENABLED 141 + sqlite3TreeViewLine(pView, 142 + "SELECT%s%s (%s/%p) selFlags=0x%x nSelectRow=%d", 143 + ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), 144 + ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), 145 + p->zSelName, p, p->selFlags, 146 + (int)p->nSelectRow 147 + ); 148 +#else 140 149 sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x nSelectRow=%d", 141 150 ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), 142 151 ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags, 143 152 (int)p->nSelectRow 144 153 ); 154 +#endif 145 155 if( cnt++ ) sqlite3TreeViewPop(pView); 146 156 if( p->pPrior ){ 147 157 n = 1000; 148 158 }else{ 149 159 n = 0; 150 160 if( p->pSrc && p->pSrc->nSrc ) n++; 151 161 if( p->pWhere ) n++;
Changes to src/update.c.
392 392 assert( pPk!=0 ); 393 393 nPk = pPk->nKeyCol; 394 394 iPk = pParse->nMem+1; 395 395 pParse->nMem += nPk; 396 396 regKey = ++pParse->nMem; 397 397 iEph = pParse->nTab++; 398 398 399 - sqlite3VdbeAddOp2(v, OP_Null, 0, iPk); 399 + sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1); 400 400 addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); 401 401 sqlite3VdbeSetP4KeyInfo(pParse, pPk); 402 402 } 403 403 404 404 /* Begin the database scan. 405 405 ** 406 406 ** Do not consider a single-pass strategy for a multi-row update if
Changes to src/vdbe.c.
4284 4284 VdbeFrame *pFrame; /* Root frame of VDBE */ 4285 4285 4286 4286 v = 0; 4287 4287 res = 0; 4288 4288 pOut = out2Prerelease(p, pOp); 4289 4289 assert( pOp->p1>=0 && pOp->p1<p->nCursor ); 4290 4290 pC = p->apCsr[pOp->p1]; 4291 + if( !pC->isTable ){ 4292 + rc = SQLITE_CORRUPT_BKPT; 4293 + goto abort_due_to_error; 4294 + } 4291 4295 assert( pC!=0 ); 4292 4296 assert( pC->eCurType==CURTYPE_BTREE ); 4293 4297 assert( pC->uc.pCursor!=0 ); 4294 4298 { 4295 4299 /* The next rowid or record number (different terms for the same 4296 4300 ** thing) is obtained in a two-step algorithm. 4297 4301 **
Changes to src/where.c.
2369 2369 int rc = SQLITE_OK; /* Return code */ 2370 2370 LogEst rSize; /* Number of rows in the table */ 2371 2371 LogEst rLogSize; /* Logarithm of table size */ 2372 2372 WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */ 2373 2373 2374 2374 pNew = pBuilder->pNew; 2375 2375 if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; 2376 - WHERETRACE(0x800, ("BEGIN addBtreeIdx(%s), nEq=%d\n", 2377 - pProbe->zName, pNew->u.btree.nEq)); 2376 + WHERETRACE(0x800, ("BEGIN %s.addBtreeIdx(%s), nEq=%d\n", 2377 + pProbe->pTable->zName,pProbe->zName, pNew->u.btree.nEq)); 2378 2378 2379 2379 assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 ); 2380 2380 assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 ); 2381 2381 if( pNew->wsFlags & WHERE_BTM_LIMIT ){ 2382 2382 opMask = WO_LT|WO_LE; 2383 2383 }else{ 2384 2384 assert( pNew->u.btree.nBtm==0 ); ................................................................................ 2656 2656 whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul); 2657 2657 pNew->nOut = saved_nOut; 2658 2658 pNew->u.btree.nEq = saved_nEq; 2659 2659 pNew->nSkip = saved_nSkip; 2660 2660 pNew->wsFlags = saved_wsFlags; 2661 2661 } 2662 2662 2663 - WHERETRACE(0x800, ("END addBtreeIdx(%s), nEq=%d, rc=%d\n", 2664 - pProbe->zName, saved_nEq, rc)); 2663 + WHERETRACE(0x800, ("END %s.addBtreeIdx(%s), nEq=%d, rc=%d\n", 2664 + pProbe->pTable->zName, pProbe->zName, saved_nEq, rc)); 2665 2665 return rc; 2666 2666 } 2667 2667 2668 2668 /* 2669 2669 ** Return True if it is possible that pIndex might be useful in 2670 2670 ** implementing the ORDER BY clause in pBuilder. 2671 2671 ** ................................................................................ 3095 3095 int j = pIdxCons->iTermOffset; 3096 3096 if( iTerm>=nConstraint 3097 3097 || j<0 3098 3098 || j>=pWC->nTerm 3099 3099 || pNew->aLTerm[iTerm]!=0 3100 3100 || pIdxCons->usable==0 3101 3101 ){ 3102 - rc = SQLITE_ERROR; 3103 3102 sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); 3104 - return rc; 3103 + testcase( pIdxInfo->needToFreeIdxStr ); 3104 + return SQLITE_ERROR; 3105 3105 } 3106 3106 testcase( iTerm==nConstraint-1 ); 3107 3107 testcase( j==0 ); 3108 3108 testcase( j==pWC->nTerm-1 ); 3109 3109 pTerm = &pWC->a[j]; 3110 3110 pNew->prereq |= pTerm->prereqRight; 3111 3111 assert( iTerm<pNew->nLSlot ); ................................................................................ 3125 3125 *pbIn = 1; assert( (mExclude & WO_IN)==0 ); 3126 3126 } 3127 3127 } 3128 3128 } 3129 3129 pNew->u.vtab.omitMask &= ~mNoOmit; 3130 3130 3131 3131 pNew->nLTerm = mxTerm+1; 3132 + for(i=0; i<=mxTerm; i++){ 3133 + if( pNew->aLTerm[i]==0 ){ 3134 + /* The non-zero argvIdx values must be contiguous. Raise an 3135 + ** error if they are not */ 3136 + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); 3137 + testcase( pIdxInfo->needToFreeIdxStr ); 3138 + return SQLITE_ERROR; 3139 + } 3140 + } 3132 3141 assert( pNew->nLTerm<=pNew->nLSlot ); 3133 3142 pNew->u.vtab.idxNum = pIdxInfo->idxNum; 3134 3143 pNew->u.vtab.needFree = pIdxInfo->needToFreeIdxStr; 3135 3144 pIdxInfo->needToFreeIdxStr = 0; 3136 3145 pNew->u.vtab.idxStr = pIdxInfo->idxStr; 3137 3146 pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? 3138 3147 pIdxInfo->nOrderBy : 0); ................................................................................ 3240 3249 nConstraint = p->nConstraint; 3241 3250 if( whereLoopResize(pParse->db, pNew, nConstraint) ){ 3242 3251 sqlite3DbFree(pParse->db, p); 3243 3252 return SQLITE_NOMEM_BKPT; 3244 3253 } 3245 3254 3246 3255 /* First call xBestIndex() with all constraints usable. */ 3256 + WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); 3247 3257 WHERETRACE(0x40, (" VirtualOne: all usable\n")); 3248 3258 rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn); 3249 3259 3250 3260 /* If the call to xBestIndex() with all terms enabled produced a plan 3251 3261 ** that does not require any source tables (IOW: a plan with mBest==0), 3252 3262 ** then there is no point in making any further calls to xBestIndex() 3253 3263 ** since they will all return the same result (if the xBestIndex() ................................................................................ 3315 3325 rc = whereLoopAddVirtualOne( 3316 3326 pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn); 3317 3327 } 3318 3328 } 3319 3329 3320 3330 if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); 3321 3331 sqlite3DbFreeNN(pParse->db, p); 3332 + WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc)); 3322 3333 return rc; 3323 3334 } 3324 3335 #endif /* SQLITE_OMIT_VIRTUALTABLE */ 3325 3336 3326 3337 /* 3327 3338 ** Add WhereLoop entries to handle OR terms. This works for either 3328 3339 ** btrees or virtual tables.
Changes to src/whereInt.h.
15 15 ** a separate source file for easier editing. 16 16 */ 17 17 18 18 /* 19 19 ** Trace output macros 20 20 */ 21 21 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) 22 -/***/ int sqlite3WhereTrace; 22 +/***/ extern int sqlite3WhereTrace; 23 23 #endif 24 24 #if defined(SQLITE_DEBUG) \ 25 25 && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) 26 26 # define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X 27 27 # define WHERETRACE_ENABLED 1 28 28 #else 29 29 # define WHERETRACE(K,X)
Changes to src/wherecode.c.
2123 2123 continue; 2124 2124 } 2125 2125 if( iLoop<3 && (pTerm->wtFlags & TERM_VARSELECT) ){ 2126 2126 if( iNext==0 ) iNext = 3; 2127 2127 continue; 2128 2128 } 2129 2129 2130 - if( pTerm->wtFlags & TERM_LIKECOND ){ 2130 + if( (pTerm->wtFlags & TERM_LIKECOND)!=0 ){ 2131 2131 /* If the TERM_LIKECOND flag is set, that means that the range search 2132 2132 ** is sufficient to guarantee that the LIKE operator is true, so we 2133 2133 ** can skip the call to the like(A,B) function. But this only works 2134 2134 ** for strings. So do not skip the call to the function on the pass 2135 2135 ** that compares BLOBs. */ 2136 2136 #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS 2137 2137 continue; 2138 2138 #else 2139 2139 u32 x = pLevel->iLikeRepCntr; 2140 - assert( x>0 ); 2141 - skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If, (int)(x>>1)); 2140 + if( x>0 ){ 2141 + skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1)); 2142 + } 2142 2143 VdbeCoverage(v); 2143 2144 #endif 2144 2145 } 2145 2146 #ifdef WHERETRACE_ENABLED /* 0xffff */ 2146 2147 if( sqlite3WhereTrace ){ 2147 2148 VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d", 2148 2149 pWC->nTerm-j, pTerm, iLoop));
Changes to test/analyze.test.
345 345 " 346 346 } {t4i1 t4i2 t4} 347 347 } 348 348 349 349 # This test corrupts the database file so it must be the last test 350 350 # in the series. 351 351 # 352 -do_test analyze-99.1 { 352 +do_test analyze-5.99 { 353 353 execsql { 354 354 PRAGMA writable_schema=on; 355 355 UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1'; 356 356 } 357 357 db close 358 358 catch { sqlite3 db test.db } 359 359 catchsql { 360 360 ANALYZE 361 361 } 362 362 } {1 {malformed database schema (sqlite_stat1)}} 363 + 364 +# Verify that tables whose names begin with "sqlite" but not 365 +# "sqlite_" are analyzed. 366 +# 367 +db close 368 +sqlite3 db :memory: 369 +do_execsql_test analyze-6.1 { 370 + CREATE TABLE sqliteDemo(a); 371 + INSERT INTO sqliteDemo(a) VALUES(1),(2),(3),(4),(5); 372 + CREATE TABLE SQLiteDemo2(a INTEGER PRIMARY KEY AUTOINCREMENT); 373 + INSERT INTO SQLiteDemo2 SELECT * FROM sqliteDemo; 374 + CREATE TABLE t1(b); 375 + INSERT INTO t1(b) SELECT a FROM sqliteDemo; 376 + ANALYZE; 377 + SELECT tbl FROM sqlite_stat1 WHERE idx IS NULL ORDER BY tbl; 378 +} {SQLiteDemo2 sqliteDemo t1} 363 379 364 380 finish_test
Changes to test/avtrans.test.
18 18 set testdir [file dirname $argv0] 19 19 source $testdir/tester.tcl 20 20 21 21 22 22 # Create several tables to work with. 23 23 # 24 24 do_test avtrans-1.0 { 25 - execsql { PRAGMA auto_vacuum=ON } 25 + execsql { PRAGMA auto_vacuum=full } 26 26 wal_set_journal_mode 27 27 execsql { 28 28 CREATE TABLE one(a int PRIMARY KEY, b text); 29 29 INSERT INTO one VALUES(1,'one'); 30 30 INSERT INTO one VALUES(2,'two'); 31 31 INSERT INTO one VALUES(3,'three'); 32 32 SELECT b FROM one ORDER BY a; 33 33 } 34 34 } {one two three} 35 +do_test avtrans-1.0.1 { execsql { PRAGMA auto_vacuum } } 1 35 36 do_test avtrans-1.1 { 36 37 execsql { 37 38 CREATE TABLE two(a int PRIMARY KEY, b text); 38 39 INSERT INTO two VALUES(1,'I'); 39 40 INSERT INTO two VALUES(5,'V'); 40 41 INSERT INTO two VALUES(10,'X'); 41 42 SELECT b FROM two ORDER BY a;
Changes to test/cursorhint2.test.
132 132 133 133 do_extract_hints_test 2.5 { 134 134 SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 1 = coalesce(b, 1) 135 135 } { 136 136 x2 {EQ(c0,r[2])} 137 137 } 138 138 139 -do_extract_hints_test 2.6 { 140 - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT NULL) 141 -} { 142 - x2 {EQ(c0,r[2])} 143 -} 144 - 145 -do_extract_hints_test 2.7 { 146 - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT +NULL) 147 -} { 148 - x2 {EQ(c0,r[2])} 149 -} 150 - 151 -do_extract_hints_test 2.8 { 152 - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NOT +NULL 153 -} { 154 - x2 {EQ(c0,r[2])} 155 -} 156 - 157 -do_extract_hints_test 2.9 { 158 - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE CASE b WHEN 0 THEN 0 ELSE 1 END; 159 -} { 160 - x2 {EQ(c0,r[2])} 161 -} 162 - 163 -do_extract_hints_test 2.10 { 164 - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b = 32+32 165 -} { 166 - x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))} 167 -} 168 - 169 -ifcapable !icu { 170 - # This test only works using the built-in LIKE, not the ICU LIKE extension. 171 - do_extract_hints_test 2.11 { 172 - SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%' 139 +if {0} { 140 + # These tests no longer work due to the LEFT-JOIN strength reduction 141 + # optimization 142 + do_extract_hints_test 2.6 { 143 + SELECT * FROM x1 CROSS JOIN x2 ON (a=x) WHERE 0 = (b IS NOT NULL) 144 + } { 145 + x2 {EQ(c0,r[2])} 146 + } 147 + 148 + do_extract_hints_test 2.7 { 149 + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE 0 = (b IS NOT +NULL) 150 + } { 151 + x2 {EQ(c0,r[2])} 152 + } 153 + 154 + do_extract_hints_test 2.8 { 155 + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE b IS NOT +NULL 156 + } { 157 + x2 {EQ(c0,r[2])} 158 + } 159 + 160 + do_extract_hints_test 2.9 { 161 + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) 162 + WHERE CASE b WHEN 0 THEN 0 ELSE 1 END; 163 + } { 164 + x2 {EQ(c0,r[2])} 165 + } 166 + 167 + do_extract_hints_test 2.10 { 168 + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b = 32+32 173 169 } { 174 - x2 {AND(expr,EQ(c0,r[2]))} 170 + x2 {AND(EQ(c1,ADD(32,32)),EQ(c0,r[2]))} 171 + } 172 + 173 + ifcapable !icu { 174 + # This test only works using the built-in LIKE, not the ICU LIKE extension. 175 + do_extract_hints_test 2.11 { 176 + SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE x2.b LIKE 'abc%' 177 + } { 178 + x2 {AND(expr,EQ(c0,r[2]))} 179 + } 175 180 } 176 181 } 177 - 182 + 178 183 do_extract_hints_test 2.12 { 179 184 SELECT * FROM x1 LEFT JOIN x2 ON (a=x) WHERE coalesce(x2.b, 1) 180 185 } { 181 186 x2 {EQ(c0,r[2])} 182 187 } 183 188 184 189 finish_test
Changes to test/dbstatus2.test.
109 109 do_test 3.0 { db_spill db 1 } {0 0 0} 110 110 do_test 3.1 { db_spill db 0 } {0 0 0} 111 111 do_execsql_test 3.2 { 112 112 PRAGMA journal_mode=DELETE; 113 113 PRAGMA cache_size=3; 114 114 UPDATE t1 SET b=randomblob(1000); 115 115 } {delete} 116 -do_test 3.2 { db_spill db 0 } {0 8 0} 116 +do_test 3.3 { db_spill db 0 } {0 8 0} 117 117 118 118 finish_test
Changes to test/e_select.test.
744 744 do_execsql_test e_select-3.1.5 { SELECT k FROM x1 WHERE x IS NULL } {4 5} 745 745 do_execsql_test e_select-3.1.6 { SELECT k FROM x1 WHERE z - 78.43 } {2 4 6} 746 746 747 747 do_execsql_test e_select-3.2.1a { 748 748 SELECT k FROM x1 LEFT JOIN x2 USING(k) 749 749 } {1 2 3 4 5 6} 750 750 do_execsql_test e_select-3.2.1b { 751 - SELECT k FROM x1 LEFT JOIN x2 USING(k) WHERE x2.k 751 + SELECT k FROM x1 LEFT JOIN x2 USING(k) WHERE x2.k ORDER BY +k 752 752 } {1 3 5} 753 753 do_execsql_test e_select-3.2.2 { 754 754 SELECT k FROM x1 LEFT JOIN x2 USING(k) WHERE x2.k IS NULL 755 755 } {2 4 6} 756 756 757 757 do_execsql_test e_select-3.2.3 { 758 758 SELECT k FROM x1 NATURAL JOIN x2 WHERE x2.k
Changes to test/istrue.test.
118 118 } {1 {CHECK constraint failed: t2}} 119 119 do_catchsql_test istrue-523 { 120 120 INSERT INTO t2 VALUES(2,true,false,true,null); 121 121 } {1 {CHECK constraint failed: t2}} 122 122 do_catchsql_test istrue-524 { 123 123 INSERT INTO t2 VALUES(2,true,false,null,false); 124 124 } {1 {CHECK constraint failed: t2}} 125 + 126 +foreach {tn val} [list 1 NaN 2 -NaN 3 NaN0 4 -NaN0 5 Inf 6 -Inf] { 127 + do_execsql_test istrue-600.$tn.1 { 128 + DROP TABLE IF EXISTS t1; 129 + CREATE TABLE t1(x); 130 + } 131 + do_test istrue-600.$tn.2 { 132 + set ::STMT [sqlite3_prepare db "INSERT INTO t1 VALUES(?)" -1 TAIL] 133 + sqlite3_bind_double $::STMT 1 $val 134 + sqlite3_step $::STMT 135 + sqlite3_reset $::STMT 136 + sqlite3_finalize $::STMT 137 + } {SQLITE_OK} 138 + do_execsql_test istrue-600.$tn.3 { 139 + SELECT x IS TRUE FROM t1; 140 + } [expr {$tn in [list 5 6] ? {1} : {0}}] 141 + do_execsql_test istrue-600.$tn.4 { 142 + SELECT x IS FALSE FROM t1; 143 + } {0} 144 +} 125 145 126 146 finish_test
Changes to test/join.test.
776 776 INSERT INTO t3(id) VALUES(1),(2); 777 777 SELECT t1.id, x2.id, x3.id 778 778 FROM t1 779 779 LEFT JOIN (SELECT * FROM t2) AS x2 ON t1.id=x2.c2 780 780 LEFT JOIN t3 AS x3 ON x2.id=x3.c3; 781 781 } {456 {} {}} 782 782 783 +# 2018-03-24. 784 +# E.Pasma discovered that the LEFT JOIN strength reduction optimization 785 +# was misbehaving. The problem turned out to be that the 786 +# sqlite3ExprImpliesNotNull() routine was saying that CASE expressions 787 +# like 788 +# 789 +# CASE WHEN true THEN true ELSE x=0 END 790 +# 791 +# could never be true if x is NULL. The following test cases verify 792 +# that this error has been resolved. 793 +# 794 +db close 795 +sqlite3 db :memory: 796 +do_execsql_test join-15.100 { 797 + CREATE TABLE t1(a INT, b INT); 798 + INSERT INTO t1 VALUES(1,2),(3,4); 799 + CREATE TABLE t2(x INT, y INT); 800 + SELECT *, 'x' 801 + FROM t1 LEFT JOIN t2 802 + WHERE CASE WHEN FALSE THEN a=x ELSE 1 END; 803 +} {1 2 {} {} x 3 4 {} {} x} 804 +do_execsql_test join-15.105 { 805 + SELECT *, 'x' 806 + FROM t1 LEFT JOIN t2 807 + WHERE a IN (1,3,x,y); 808 +} {1 2 {} {} x 3 4 {} {} x} 809 +do_execsql_test join-15.106 { 810 + SELECT *, 'x' 811 + FROM t1 LEFT JOIN t2 812 + WHERE NOT ( 'x'='y' AND t2.y=1 ); 813 +} {1 2 {} {} x 3 4 {} {} x} 814 +do_execsql_test join-15.107 { 815 + SELECT *, 'x' 816 + FROM t1 LEFT JOIN t2 817 + WHERE t2.y IS NOT 'abc' 818 +} {1 2 {} {} x 3 4 {} {} x} 819 +do_execsql_test join-15.110 { 820 + DROP TABLE t1; 821 + DROP TABLE t2; 822 + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER); 823 + INSERT INTO t1(a,b) VALUES(1,0),(11,1),(12,1),(13,1),(121,12); 824 + CREATE INDEX t1b ON t1(b); 825 + CREATE TABLE t2(x INTEGER PRIMARY KEY); 826 + INSERT INTO t2(x) VALUES(0),(1); 827 + SELECT a1, a2, a3, a4, a5 828 + FROM (SELECT a AS a1 FROM t1 WHERE b=0) 829 + JOIN (SELECT x AS x1 FROM t2) 830 + LEFT JOIN (SELECT a AS a2, b AS b2 FROM t1) 831 + ON x1 IS TRUE AND b2=a1 832 + JOIN (SELECT x AS x2 FROM t2) 833 + ON x2<=CASE WHEN x1 THEN CASE WHEN a2 THEN 1 ELSE -1 END ELSE 0 END 834 + LEFT JOIN (SELECT a AS a3, b AS b3 FROM t1) 835 + ON x2 IS TRUE AND b3=a2 836 + JOIN (SELECT x AS x3 FROM t2) 837 + ON x3<=CASE WHEN x2 THEN CASE WHEN a3 THEN 1 ELSE -1 END ELSE 0 END 838 + LEFT JOIN (SELECT a AS a4, b AS b4 FROM t1) 839 + ON x3 IS TRUE AND b4=a3 840 + JOIN (SELECT x AS x4 FROM t2) 841 + ON x4<=CASE WHEN x3 THEN CASE WHEN a4 THEN 1 ELSE -1 END ELSE 0 END 842 + LEFT JOIN (SELECT a AS a5, b AS b5 FROM t1) 843 + ON x4 IS TRUE AND b5=a4 844 + ORDER BY a1, a2, a3, a4, a5; 845 +} {1 {} {} {} {} 1 11 {} {} {} 1 12 {} {} {} 1 12 121 {} {} 1 13 {} {} {}} 846 + 783 847 finish_test
Changes to test/join2.test.
82 82 CREATE TABLE cc(c); 83 83 INSERT INTO aa VALUES('one'); 84 84 INSERT INTO bb VALUES('one'); 85 85 INSERT INTO cc VALUES('one'); 86 86 } 87 87 88 88 do_catchsql_test 2.1 { 89 - SELECT * FROM aa LEFT JOIN cc ON (a=b) JOIN bb ON (b=c); 89 + SELECT * FROM aa LEFT JOIN cc ON (a=b) JOIN bb ON (b=coalesce(c,1)); 90 90 } {1 {ON clause references tables to its right}} 91 91 do_catchsql_test 2.2 { 92 92 SELECT * FROM aa JOIN cc ON (a=b) JOIN bb ON (b=c); 93 93 } {0 {one one one}} 94 94 95 95 #------------------------------------------------------------------------- 96 96 # Test that a problem causing where.c to overlook opportunities to ................................................................................ 260 260 CREATE INDEX u1ab ON u1(b, c); 261 261 } 262 262 do_eqp_test 6.1 { 263 263 SELECT u2.* FROM u2 LEFT JOIN u1 ON( u1.a=u2.a AND u1.b=u2.b AND u1.c=u2.c ); 264 264 } { 265 265 0 0 0 {SCAN TABLE u2} 266 266 } 267 + 268 +db close 269 +sqlite3 db :memory: 270 +do_execsql_test 7.0 { 271 + CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,2),(3,4),(5,6); 272 + CREATE TABLE t2(c,d); INSERT INTO t2 VALUES(2,4),(3,6); 273 + CREATE TABLE t3(x); INSERT INTO t3 VALUES(9); 274 + CREATE VIEW test AS 275 + SELECT *, 'x' 276 + FROM t1 LEFT JOIN (SELECT * FROM t2, t3) ON (c=b AND x=9) 277 + WHERE c IS NULL; 278 + SELECT * FROM test; 279 +} {3 4 {} {} {} x 5 6 {} {} {} x} 280 + 267 281 268 282 finish_test
Changes to test/join5.test.
160 160 INSERT INTO x3 VALUES('c', NULL); 161 161 SELECT * FROM x1 LEFT JOIN x2 JOIN x3 WHERE x3.d = x2.b; 162 162 } {} 163 163 164 164 # Ticket https://www.sqlite.org/src/tktview/c2a19d81652f40568c770c43 on 165 165 # 2015-08-20. LEFT JOIN and the push-down optimization. 166 166 # 167 -do_execsql_test join6-4.1 { 167 +do_execsql_test join5-4.1 { 168 168 SELECT * 169 169 FROM ( 170 170 SELECT 'apple' fruit 171 171 UNION ALL SELECT 'banana' 172 172 ) a 173 173 JOIN ( 174 174 SELECT 'apple' fruit 175 175 UNION ALL SELECT 'banana' 176 176 ) b ON a.fruit=b.fruit 177 177 LEFT JOIN ( 178 178 SELECT 1 isyellow 179 179 ) c ON b.fruit='banana'; 180 180 } {apple apple {} banana banana 1} 181 -do_execsql_test join6-4.2 { 181 +do_execsql_test join5-4.2 { 182 182 SELECT * 183 183 FROM (SELECT 'apple' fruit UNION ALL SELECT 'banana') 184 184 LEFT JOIN (SELECT 1) ON fruit='banana'; 185 185 } {apple {} banana 1} 186 186 187 187 #------------------------------------------------------------------------- 188 188 do_execsql_test 5.0 {
Changes to test/kvtest.c.
558 558 sqlite3_snprintf(20, zTail, "%02d/%02d/%02d", 559 559 iKey/10000, (iKey/100)%100, iKey%100); 560 560 } 561 561 out = fopen(zFN, "wb"); 562 562 nWrote = fwrite(pData, 1, (size_t)nData, out); 563 563 fclose(out); 564 564 printf("\r%s ", zTail); fflush(stdout); 565 - if( nWrote!=nData ){ 565 + if( nWrote!=(size_t)nData ){ 566 566 fatalError("Wrote only %d of %d bytes to %s\n", 567 567 (int)nWrote, nData, zFN); 568 568 } 569 569 } 570 570 sqlite3_finalize(pStmt); 571 571 sqlite3_close(db); 572 572 sqlite3_free(zFN);
Changes to test/memdb1.test.
53 53 do_execsql_test 110 { 54 54 SELECT * FROM t1; 55 55 } {1 2} 56 56 57 57 # What happens when we try to VACUUM a MEMDB database? 58 58 # 59 59 do_execsql_test 120 { 60 + PRAGMA auto_vacuum = off; 60 61 VACUUM; 61 62 } {} 62 63 do_execsql_test 130 { 63 64 CREATE TABLE t2(x, y); 64 65 WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) 65 66 INSERT INTO t2(x, y) SELECT x, randomblob(1000) FROM c; 66 67 DROP TABLE t2;
Changes to test/misc8.test.
53 53 BEGIN; 54 54 CREATE TABLE t2(x); 55 55 SELECT a, coalesce(b, eval('ROLLBACK; SELECT ''bam''')), c 56 56 FROM t1 57 57 ORDER BY rowid; 58 58 } {1 {abort due to ROLLBACK}} 59 59 60 +do_catchsql_test misc8-1.8 { 61 + PRAGMA empty_result_callbacks = 1; 62 + SELECT eval('SELECT * FROM t1 WHERE 1 = 0;'); 63 +} {0 {{}}} 60 64 61 65 reset_db 62 66 63 67 proc dbeval {sql} { db eval $sql } 64 68 db func eval dbeval 65 69 66 70 do_execsql_test misc8-2.1 {
Added test/optfuzz-db01.c.
1 +/* content of file testdb01.db */ 2 +unsigned char data001[] = { 3 + 83, 81, 76,105,116,101, 32,102,111,114,109, 97,116, 32, 51, 0, 2, 0, 1, 4 + 1, 0, 64, 32, 32, 0, 0, 0, 2, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 5 + 0, 0, 0, 0, 0, 31, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6 + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8 + 2, 0, 46, 32,152, 5, 0, 0, 0, 7, 1,221, 0, 0, 0, 0, 35, 1,251, 9 + 1,246, 1,241, 1,236, 1,231, 1,226, 1,221, 84, 4, 7, 23, 17, 17, 1, 10 + 129, 19,116, 97, 98,108,101,116, 52,116, 52, 5, 67, 82, 69, 65, 84, 69, 32, 11 + 84, 65, 66, 76, 69, 32,116, 52, 40, 97, 32, 73, 78, 84, 32, 85, 78, 73, 81, 12 + 85, 69, 32, 78, 79, 84, 32, 78, 85, 76, 76, 44, 32, 98, 32, 73, 78, 84, 32, 13 + 85, 78, 73, 81, 85, 69, 32, 78, 79, 84, 32, 78, 85, 76, 76, 44, 99, 44,100, 14 + 44,101, 41, 35, 6, 6, 23, 55, 17, 1, 0,105,110,100,101,120,115,113,108, 15 + 105,116,101, 95, 97,117,116,111,105,110,100,101,120, 95,116, 52, 95, 50,116, 16 + 52, 7, 35, 5, 6, 23, 55, 17, 1, 0,105,110,100,101,120,115,113,108,105, 17 + 116,101, 95, 97,117,116,111,105,110,100,101,120, 95,116, 52, 95, 49,116, 52, 18 + 6, 42, 3, 6, 23, 17, 17, 1, 65,116, 97, 98,108,101,116, 51,116, 51, 4, 19 + 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 51, 40, 97, 44, 98, 20 + 44, 99, 44,100, 44,101, 41, 95, 2, 7, 23, 17, 17, 1,129, 41,116, 97, 98, 21 + 108,101,116, 50,116, 50, 3, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 22 + 32,116, 50, 40, 97, 32, 73, 78, 84, 44, 32, 98, 32, 73, 78, 84, 44, 32, 99, 23 + 32, 73, 78, 84, 44,100, 32, 73, 78, 84, 44,101, 32, 73, 78, 84, 44, 80, 82, 24 + 73, 77, 65, 82, 89, 32, 75, 69, 89, 40, 98, 44, 97, 41, 41, 87, 73, 84, 72, 25 + 79, 85, 84, 32, 82, 79, 87, 73, 68, 83, 1, 7, 23, 17, 17, 1,129, 17,116, 26 + 97, 98,108,101,116, 49,116, 49, 2, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 27 + 76, 69, 32,116, 49, 40, 97, 32, 73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73, 28 + 77, 65, 0, 0, 0, 34, 32, 0, 0, 0, 33, 29, 0, 0, 0, 32, 26, 0, 0, 29 + 0, 31, 23, 0, 0, 0, 30, 19, 0, 0, 0, 11, 14, 0, 0, 0, 9, 7, 5, 30 + 0, 0, 0, 1, 1,251, 0, 0, 0, 0, 16, 1,251, 1,195, 1,180, 1,166, 31 + 1,151, 1,136, 1,121, 1,105, 1, 91, 1, 76, 1, 61, 1, 46, 1, 29, 1, 32 + 14, 0,252, 0,238, 0,224, 0,209, 0,194, 0,177, 0,157, 0,143, 0,128, 33 + 0,110, 0, 94, 0, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34 + 0, 14, 28, 6, 0, 1, 1, 1, 23, 17, 67, 31,119,111,114,107,115, 14, 27, 35 + 6, 0, 1, 1, 1, 23, 22, 71, 3, 97,110,103,101,108, 16, 26, 6, 0, 1, 36 + 1, 1, 27, 40, 98, 17,109,111,114,110,105,110,103, 13, 25, 6, 0, 1, 1, 37 + 1, 21, 10, 7, 19,103,111,110,101, 12, 24, 6, 0, 1, 1, 9, 21, 43, 46, 38 + 119, 97,121,115, 18, 23, 6, 0, 1, 1, 1, 31, 6, 37, 31,115, 97, 99,114, 39 + 105,102,105, 99,101, 15, 22, 6, 0, 1, 1, 1, 25, 45, 71, 28,116,104,111, 40 + 117,103,104, 13, 21, 6, 0, 1, 1, 1, 21, 22, 92, 18,115,111,109,101, 13, 41 + 20, 6, 0, 9, 1, 1, 23, 2, 45, 97, 98,111,118,101, 12, 19, 6, 0, 1, 42 + 1, 8, 21, 4, 58,119, 97,121,115, 12, 18, 6, 0, 1, 1, 1, 19, 44, 19, 43 + 43,119, 97,114, 16, 17, 6, 0, 1, 1, 1, 27, 29, 74, 36, 98,101,116,119, 44 + 101,101,110, 13, 16, 6, 0, 1, 1, 1, 21, 44, 52, 19,112,111,111,114, 15, 45 + 15, 6, 0, 1, 1, 1, 25, 6, 3, 11,116,101,109,112,108,101, 13, 14, 6, 46 + 0, 1, 1, 1, 21, 35, 48, 27,100,105,101,100, 13, 13, 6, 0, 1, 1, 1, 47 + 21, 4, 21, 39,100,111,116,104, 13, 12, 6, 0, 1, 1, 1, 21, 4, 38, 36, 48 + 115,101,110,100, 12, 11, 6, 0, 1, 1, 1, 19, 13, 48, 22,115,105,120, 14, 49 + 10, 6, 0, 1, 1, 1, 23, 41, 89, 14,115,101,114,118,101, 13, 9, 6, 0, 50 + 8, 1, 1, 23, 16, 50, 98,101,103, 97,116, 13, 8, 6, 0, 1, 1, 1, 21, 51 + 42, 49, 34,115,101,110,100, 13, 7, 6, 0, 1, 1, 1, 21, 21, 91, 38,110, 52 + 101, 97,114, 12, 6, 6, 0, 1, 1, 1, 19, 2, 37, 11, 99, 97,110, 13, 5, 53 + 6, 0, 1, 1, 1, 21, 25, 27, 28,103,111,110,101, 13, 4, 6, 0, 1, 1, 54 + 1, 21, 41, 32, 35,110,101, 97,114, 14, 3, 6, 0, 1, 1, 1, 23, 32, 24, 55 + 26,115,101,114,118,101, 13, 2, 6, 0, 1, 1, 1, 21, 45, 14, 39,115, 97, 56 + 118,101, 13, 1, 6, 0, 1, 1, 1, 21, 40, 68, 0, 0, 0, 15, 28, 2, 0, 57 + 0, 0, 1, 1,238, 0, 0, 0, 0, 22, 1,238, 1,197, 1,181, 1,166, 1, 58 + 151, 1,137, 1,121, 1,104, 1, 84, 1, 73, 1, 59, 1, 41, 1, 26, 1, 11, 59 + 0,253, 0,238, 0,223, 0,207, 0,191, 0,175, 0,159, 0,144, 0,129, 0, 60 + 113, 0, 97, 0, 82, 0, 68, 0, 0, 13, 6, 1, 1, 1, 1, 19, 26, 34, 15, 61 + 20, 97,114,107, 14, 6, 1, 1, 1, 1, 21, 25, 5, 27, 28,103,111,110,101, 62 + 15, 6, 1, 1, 1, 1, 23, 22, 47, 16, 40, 97,110,103,101,114, 15, 6, 1, 63 + 1, 1, 1, 23, 22, 27, 71, 3, 97,110,103,101,108, 14, 6, 1, 1, 1, 1, 64 + 21, 22, 21, 92, 18,115,111,109,101, 14, 6, 1, 1, 1, 1, 21, 21, 7, 91, 65 + 38,110,101, 97,114, 15, 6, 1, 1, 1, 1, 23, 20, 42, 18, 5, 98,101,103, 66 + 97,116, 15, 6, 1, 1, 1, 1, 23, 17, 37, 66, 18,100,119,101,108,116, 15, 67 + 6, 1, 1, 1, 1, 23, 17, 28, 67, 31,119,111,114,107,115, 15, 6, 1, 1, 68 + 1, 8, 25, 16, 32, 7,112,108, 97, 99,101,115, 14, 6, 1, 1, 1, 1, 21, 69 + 16, 30, 81, 25,119, 97,108,107, 14, 6, 1, 1, 1, 1, 21, 14, 40, 30, 26, 70 + 115,101,110,100, 13, 6, 1, 1, 1, 1, 19, 13, 11, 48, 22,115,105,120, 14, 71 + 6, 1, 1, 1, 1, 21, 10, 38, 97, 34,115,104,101,119, 14, 6, 1, 1, 1, 72 + 1, 21, 10, 25, 7, 19,103,111,110,101, 17, 6, 1, 1, 1, 1, 27, 9, 50, 73 + 92, 29,116,104,101,114,101,105,110, 13, 6, 1, 1, 1, 1, 19, 9, 49, 51, 74 + 38,111,105,108, 10, 6, 1, 1, 1, 1, 0, 7, 33, 72, 31, 19, 6, 1, 1, 75 + 1, 1, 31, 6, 23, 37, 31,115, 97, 99,114,105,102,105, 99,101, 16, 6, 1, 76 + 1, 1, 1, 25, 6, 15, 3, 11,116,101,109,112,108,101, 15, 6, 1, 1, 1, 77 + 1, 23, 5, 43, 23, 41, 98,101,103, 97,116, 13, 6, 1, 1, 1, 8, 21, 4, 78 + 19, 58,119, 97,121,115, 14, 6, 1, 1, 1, 1, 21, 4, 13, 21, 39,100,111, 79 + 116,104, 14, 6, 1, 1, 1, 1, 21, 4, 12, 38, 36,115,101,110,100, 15, 6, 80 + 1, 1, 1, 1, 23, 3, 39, 21, 45, 98,101,103, 97,116, 13, 6, 1, 1, 1, 81 + 1, 19, 2, 6, 37, 11, 99, 97,110, 14, 6, 9, 1, 1, 1, 23, 20, 2, 45, 82 + 97, 98,111,118,101, 14, 6, 8, 1, 1, 1, 23, 36, 52, 17, 99,104, 0, 0, 83 + 0, 21, 13, 6, 1, 1, 1, 1, 19, 26, 34, 15, 20, 97,114,107, 13, 0, 0, 84 + 0, 35, 0, 92, 0, 1,244, 1,232, 1,216, 1,204, 1,186, 1,171, 1,160, 85 + 1,149, 1,138, 1,128, 1,117, 1,106, 1, 92, 1, 76, 1, 65, 1, 49, 1, 86 + 32, 1, 21, 1, 10, 0,255, 0,241, 0,225, 0,214, 0,203, 0,192, 0,180, 87 + 0,168, 0,156, 0,144, 0,132, 0,124, 0,116, 0,108, 0,100, 0, 92, 0, 88 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 35, 6, 0, 0, 0, 89 + 0, 0, 6, 34, 6, 0, 0, 0, 0, 0, 6, 33, 6, 0, 0, 0, 0, 0, 6, 90 + 32, 6, 0, 0, 0, 0, 0, 6, 31, 6, 0, 0, 0, 0, 0, 10, 30, 6, 1, 91 + 1, 1, 1, 0, 48, 37, 93, 7, 10, 29, 6, 1, 1, 1, 1, 0, 28, 17, 67, 92 + 31, 10, 28, 6, 1, 1, 1, 1, 0, 22, 45, 71, 28, 10, 27, 6, 1, 1, 1, 93 + 1, 0, 12, 4, 38, 36, 10, 26, 6, 1, 1, 1, 1, 0, 49, 9, 51, 38, 9, 94 + 25, 6, 1, 1, 1, 0, 0, 17, 29, 74, 9, 24, 6, 1, 1, 1, 0, 0, 47, 95 + 22, 16, 9, 23, 6, 1, 1, 1, 0, 0, 32, 16, 7, 14, 22, 6, 1, 1, 1, 96 + 0, 23, 42, 20, 18, 98,101,103, 97,116, 12, 21, 6, 1, 1, 1, 0, 19, 34, 97 + 26, 15, 97,114,107, 9, 20, 6, 1, 1, 0, 1, 0, 49, 9, 38, 9, 19, 6, 98 + 1, 1, 0, 1, 0, 44, 48, 9, 9, 18, 6, 1, 1, 0, 1, 0, 21, 22, 18, 99 + 15, 17, 6, 1, 1, 0, 1, 25, 35, 38, 22, 99,117, 98,105,116,115, 14, 16, 100 + 6, 1, 1, 0, 1, 23, 37, 17, 18,100,119,101,108,116, 9, 15, 6, 1, 0, 101 + 1, 1, 0, 49, 51, 38, 14, 14, 6, 1, 0, 1, 1, 23, 10, 89, 14,115,101, 102 + 114,118,101, 12, 13, 6, 9, 0, 1, 1, 21, 68, 32,100,111,116,104, 9, 12, 103 + 6, 1, 0, 1, 1, 0, 47, 16, 40, 9, 11, 6, 1, 0, 1, 1, 0, 25, 7, 104 + 19, 8, 10, 6, 0, 1, 1, 8, 0, 16, 7, 9, 9, 6, 0, 1, 1, 1, 0, 105 + 16, 81, 25, 9, 8, 6, 0, 1, 1, 1, 0, 7, 72, 31, 9, 7, 6, 0, 1, 106 + 1, 1, 0, 6, 37, 31, 13, 6, 6, 0, 1, 1, 1, 21, 21, 91, 38,110,101, 107 + 97,114, 16, 5, 6, 1, 1, 1, 1, 25, 15, 6, 3, 11,116,101,109,112,108, 108 + 101, 10, 4, 6, 1, 1, 1, 1, 0, 21, 22, 92, 18, 14, 3, 6, 1, 1, 1, 109 + 1, 21, 4, 41, 32, 35,110,101, 97,114, 10, 2, 6, 1, 1, 1, 1, 0, 46, 110 + 28, 88, 22, 10, 1, 6, 1, 1, 1, 1, 0, 17, 29, 74, 36, 13, 0, 0, 0, 111 + 15, 1, 71, 0, 1,243, 1,230, 1,217, 1,204, 1,191, 1,179, 1,167, 1, 112 + 155, 1,143, 1,131, 1,119, 1,107, 1, 95, 1, 83, 1, 71, 0, 0, 0, 0, 113 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 114 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 119 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 125 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128 + 10, 15, 6, 1, 1, 1, 1, 0, 48, 37, 93, 7, 10, 14, 6, 1, 1, 1, 1, 129 + 0, 22, 45, 71, 28, 10, 13, 6, 1, 1, 1, 1, 0, 12, 4, 38, 36, 10, 12, 130 + 6, 1, 1, 1, 0, 1, 32, 16, 7, 79, 10, 11, 6, 1, 1, 1, 0, 1, 42, 131 + 20, 18, 19, 10, 10, 6, 1, 1, 1, 0, 1, 34, 26, 15, 13, 10, 9, 6, 1, 132 + 1, 0, 1, 1, 49, 9, 38, 97, 10, 8, 6, 1, 1, 0, 1, 1, 44, 48, 9, 133 + 90, 10, 7, 6, 1, 1, 0, 1, 1, 35, 38, 22, 33, 10, 6, 6, 1, 1, 0, 134 + 1, 1, 37, 17, 18, 18, 11, 5, 6, 1, 1, 1, 1, 1, 15, 6, 3, 11, 43, 135 + 11, 4, 6, 1, 1, 1, 1, 1, 21, 22, 92, 18, 62, 11, 3, 6, 1, 1, 1, 136 + 1, 1, 4, 41, 32, 35, 36, 11, 2, 6, 1, 1, 1, 1, 1, 46, 28, 88, 22, 137 + 77, 11, 1, 6, 1, 1, 1, 1, 1, 17, 29, 74, 36, 61, 10, 0, 0, 0, 15, 138 + 1,167, 0, 1,250, 1,244, 1,238, 1,233, 1,227, 1,221, 1,215, 1,209, 139 + 1,203, 1,197, 1,191, 1,185, 1,179, 1,173, 1,167, 0, 0, 0, 0, 0, 140 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 141 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 142 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 143 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 146 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 149 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 150 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 151 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 152 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 153 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 158 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 159 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160 + 5, 3, 1, 1, 49, 9, 5, 3, 1, 1, 48, 15, 5, 3, 1, 1, 46, 2, 5, 161 + 3, 1, 1, 44, 8, 5, 3, 1, 1, 42, 11, 5, 3, 1, 1, 37, 6, 5, 3, 162 + 1, 1, 35, 7, 5, 3, 1, 1, 34, 10, 5, 3, 1, 1, 32, 12, 5, 3, 1, 163 + 1, 22, 14, 5, 3, 1, 1, 21, 4, 4, 3, 1, 9, 17, 5, 3, 1, 1, 15, 164 + 5, 5, 3, 1, 1, 12, 13, 5, 3, 1, 1, 4, 3, 10, 0, 0, 0, 15, 1, 165 + 167, 0, 1,250, 1,244, 1,238, 1,232, 1,226, 1,220, 1,214, 1,208, 1, 166 + 202, 1,197, 1,191, 1,185, 1,179, 1,173, 1,167, 0, 0, 0, 0, 0, 0, 167 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 169 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 171 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 174 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 175 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 176 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 178 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 179 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 182 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 185 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 186 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 187 + 3, 1, 1, 48, 8, 5, 3, 1, 1, 45, 14, 5, 3, 1, 1, 41, 3, 5, 3, 188 + 1, 1, 38, 7, 5, 3, 1, 1, 37, 15, 4, 3, 1, 9, 29, 5, 3, 1, 1, 189 + 28, 2, 5, 3, 1, 1, 26, 10, 5, 3, 1, 1, 22, 4, 5, 3, 1, 1, 20, 190 + 11, 5, 3, 1, 1, 17, 6, 5, 3, 1, 1, 16, 12, 5, 3, 1, 1, 9, 9, 191 + 5, 3, 1, 1, 6, 5, 5, 3, 1, 1, 4, 13, 5, 0, 0, 0, 2, 1,246, 192 + 0, 0, 0, 0, 27, 1,251, 1,246, 1,168, 1,148, 1,130, 1,107, 1, 86, 193 + 1, 65, 1, 44, 1, 27, 1, 14, 0,250, 0,224, 0,205, 0,184, 0,165, 0, 194 + 145, 0,123, 0,106, 0, 86, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195 + 0, 0, 0, 17, 23, 6, 0, 23, 1, 1, 21,107,110,111,119,110, 52, 19,112, 196 + 111,111,114, 18, 22, 6, 0, 23, 1, 1, 23, 97, 98,111,118,101, 24, 26,115, 197 + 101,114,118,101, 15, 21, 6, 0, 19, 1, 1, 21,119, 97,114, 52, 19,112,111, 198 + 111,114, 20, 20, 6, 0, 27, 1, 8, 25,110,111,116,104,105,110,103, 7,112, 199 + 108, 97, 99,101,115, 18, 19, 6, 0, 23, 1, 1, 23, 98,101,103, 97,116, 90, 200 + 27,116,114,117,116,104, 17, 18, 6, 0, 23, 1, 1, 21,100,119,101,108,116, 201 + 21, 39,100,111,116,104, 19, 17, 6, 0, 27, 1, 1, 21,109,111,114,110,105, 202 + 110,103, 52, 19,112,111,111,114, 17, 16, 6, 0, 21, 1, 1, 23,115,104,101, 203 + 119, 90, 27,116,114,117,116,104, 24, 15, 6, 0, 27, 1, 1, 31,116,104,101, 204 + 114,101,105,110, 37, 31,115, 97, 99,114,105,102,105, 99,101, 18, 14, 6, 0, 205 + 23, 1, 8, 25,115,109,111,116,101, 7,112,108, 97, 99,101,115, 11, 13, 6, 206 + 0, 19, 1, 1, 0, 97,114,107, 72, 31, 15, 12, 6, 0, 21, 1, 8, 21,119, 207 + 105,110,101, 58,119, 97,121,115, 19, 11, 6, 0, 21, 1, 1, 27,115,111,109, 208 + 101, 98, 17,109,111,114,110,105,110,103, 19, 10, 6, 0, 27, 1, 1, 21, 98, 209 + 101,116,119,101,101,110, 92, 18,115,111,109,101, 19, 9, 6, 0, 21, 1, 1, 210 + 27,115, 97,118,101, 74, 36, 98,101,116,119,101,101,110, 21, 8, 6, 0, 25, 211 + 1, 1, 27,116,104,111,117,103,104, 98, 17,109,111,114,110,105,110,103, 16, 212 + 7, 6, 0, 21, 1, 1, 21,115,101,110,100, 49, 34,115,101,110,100, 18, 6, 213 + 6, 0, 25, 1, 1, 21,119,105,115,100,111,109, 38, 36,115,101,110,100, 16, 214 + 5, 6, 0, 23, 1, 9, 21, 97,110,103,101,114, 46,119, 97,121,115, 14, 4, 215 + 6, 0, 19, 1, 1, 19, 99, 97,110, 19, 43,119, 97,114, 16, 3, 6, 0, 23, 216 + 1, 1, 19,111,102,102,101,114, 48, 22,115,105,120, 16, 2, 6, 0, 23, 1, 217 + 8, 21,119,111,114,107,115, 58,119, 97,121,115, 16, 1, 6, 0, 23, 1, 1, 218 + 19, 0, 0, 0, 26, 45, 0, 0, 0, 25, 23, 13, 0, 0, 0, 7, 0, 48, 0, 219 + 1,171, 1, 74, 1, 30, 0,126, 0,249, 0,212, 0, 48, 0, 81, 0, 0, 84, 220 + 4, 7, 23, 17, 17, 1,129, 19,116, 97, 98,108,101,116, 52,116, 52, 5, 67, 221 + 82, 69, 76, 7, 7, 23, 17, 17, 1,129, 3,116, 97, 98,108,101,116, 53,116, 222 + 53, 8, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 53, 40, 97, 223 + 32, 73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73, 77, 65, 82, 89, 32, 75, 69, 224 + 89, 44, 32, 98, 32, 84, 69, 88, 84, 32, 85, 78, 73, 81, 85, 69, 44, 99, 44, 225 + 100, 44,101, 41, 84, 4, 7, 23, 17, 17, 1,129, 19,116, 97, 98,108,101,116, 226 + 52,116, 52, 5, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 52, 227 + 40, 97, 32, 73, 78, 84, 32, 85, 78, 73, 81, 85, 69, 32, 78, 79, 84, 32, 78, 228 + 85, 76, 76, 44, 32, 98, 32, 73, 78, 84, 32, 85, 78, 73, 81, 85, 69, 32, 78, 229 + 79, 84, 32, 78, 85, 76, 76, 44, 99, 44,100, 44,101, 41, 35, 6, 6, 23, 55, 230 + 17, 1, 0,105,110,100,101,120,115,113,108,105,116,101, 95, 97,117,116,111, 231 + 105,110,100,101,120, 95,116, 52, 95, 50,116, 52, 7, 35, 5, 6, 23, 55, 17, 232 + 1, 0,105,110,100,101,120,115,113,108,105,116,101, 95, 97,117,116,111,105, 233 + 110,100,101,120, 95,116, 52, 95, 49,116, 52, 6, 42, 3, 6, 23, 17, 17, 1, 234 + 65,116, 97, 98,108,101,116, 51,116, 51, 4, 67, 82, 69, 65, 84, 69, 32, 84, 235 + 65, 66, 76, 69, 32,116, 51, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 95, 236 + 2, 7, 23, 17, 17, 1,129, 41,116, 97, 98,108,101,116, 50,116, 50, 3, 67, 237 + 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 50, 40, 97, 32, 73, 78, 238 + 84, 44, 32, 98, 32, 73, 78, 84, 44, 32, 99, 32, 73, 78, 84, 44,100, 32, 73, 239 + 78, 84, 44,101, 32, 73, 78, 84, 44, 80, 82, 73, 77, 65, 82, 89, 32, 75, 69, 240 + 89, 40, 98, 44, 97, 41, 41, 87, 73, 84, 72, 79, 85, 84, 32, 82, 79, 87, 73, 241 + 68, 83, 1, 7, 23, 17, 17, 1,129, 17,116, 97, 98,108,101,116, 49,116, 49, 242 + 2, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 69, 32,116, 49, 40, 97, 32, 243 + 73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73, 77, 65, 82, 89, 32, 75, 69, 89, 244 + 44, 32, 98, 32, 73, 78, 84, 44, 32, 99, 32, 73, 78, 84, 44, 32,100, 32, 73, 245 + 78, 84, 44, 32,101, 32, 73, 78, 84, 41, 2, 0, 0, 0, 1, 1,243, 0, 0, 246 + 0, 0, 29, 1,243, 1,218, 1,209, 1,199, 1,187, 1,179, 1,169, 1,158, 247 + 1,145, 1,136, 1,127, 1,117, 1,107, 1, 98, 1, 82, 1, 72, 1, 63, 1, 248 + 51, 1, 42, 1, 30, 1, 20, 1, 12, 1, 3, 0,248, 0,239, 0,225, 0,216, 249 + 0,207, 0,197, 0,188, 0,180, 0,170, 0,161, 0,152, 0,141, 0,129, 0, 250 + 118, 0,106, 0, 97, 0, 0, 0, 0, 0, 0, 0, 8, 3, 21, 1,116,114,101, 251 + 101, 49, 11, 3, 27, 1,116,104,121,115,101,108,102, 27, 10, 3, 25, 1,116, 252 + 104,111,117,103,104, 8, 11, 3, 27, 1,116,104,101,114,101,105,110, 15, 10, 253 + 3, 25, 1,116,101,109,112,108,101, 43, 8, 3, 21, 1,116,101,108,108, 25, 254 + 8, 3, 21, 1,115,111,109,101, 11, 9, 3, 23, 1,115,109,111,116,101, 14, 255 + 7, 3, 19, 1,115,105,120, 48, 8, 3, 21, 1,115,104,101,119, 16, 9, 3, 256 + 23, 1,115,101,114,118,101, 37, 8, 3, 21, 1,115,101,110,100, 7, 8, 3, 257 + 21, 1,115, 97,118,101, 9, 13, 3, 31, 1,115, 97, 99,114,105,102,105, 99, 258 + 101, 24, 8, 3, 21, 1,112,111,111,114, 40, 10, 3, 25, 1,112,108, 97, 99, 259 + 101,115, 28, 8, 3, 21, 1,112, 97,114,116, 30, 7, 3, 19, 1,111,105,108, 260 + 46, 9, 3, 23, 1,111,102,102,101,114, 3, 11, 3, 27, 1,110,111,116,104, 261 + 105,110,103, 20, 8, 3, 21, 1,110,101, 97,114, 36, 11, 3, 27, 1,109,111, 262 + 114,110,105,110,103, 17, 8, 3, 21, 1,108,111,110,103, 35, 9, 3, 23, 1, 263 + 107,110,111,119,110, 23, 15, 3, 35, 1,105,110,104, 97, 98,105,116, 97,110, 264 + 116,115, 45, 8, 3, 21, 1,103,111,110,101, 32, 9, 3, 23, 1,102,114,117, 265 + 105,116, 38, 9, 3, 23, 1,100,119,101,108,116, 18, 8, 3, 21, 1,100,111, 266 + 116,104, 39, 8, 3, 21, 1,100,105,101,100, 47, 12, 3, 29, 1,100,101,112, 267 + 97,114,116,101,100, 26, 10, 3, 25, 1, 99,117, 98,105,116,115, 33, 9, 3, 268 + 23, 1, 99,104,105,108,100, 42, 7, 3, 19, 1, 99, 97,110, 4, 11, 3, 27, 269 + 1, 98,101,116,119,101,101,110, 10, 9, 3, 23, 1, 98,101,103, 97,116, 19, 270 + 8, 3, 21, 1, 98,101, 97,114, 29, 7, 3, 19, 1, 97,114,107, 13, 9, 3, 271 + 23, 1, 97,110,103,101,114, 5, 9, 3, 23, 1, 97,110,103, 0, 0, 0, 28, 272 + 8, 3, 21, 1,116,114,101,101, 49, 13, 1,104, 0, 7, 0, 24, 0, 1, 67, 273 + 1, 13, 0,225, 0,177, 0,109, 1,171, 0, 24, 0, 0, 83, 14, 7, 21, 19, 274 + 19, 8,129, 17,118,105,101,119,118, 50, 48,118, 50, 48, 67, 82, 69, 65, 84, 275 + 69, 32, 86, 73, 69, 87, 32,118, 50, 48, 40, 97, 44, 98, 44, 99, 44,100, 44, 276 + 101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44, 277 + 100, 44,101, 32, 70, 82, 79, 77, 32,116, 50, 32, 87, 72, 69, 82, 69, 32, 97, 278 + 60, 62, 50, 53, 66, 12, 6, 21, 19, 19, 8,113,118,105,101,119,118, 48, 48, 279 + 118, 48, 48, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 48, 48, 40, 280 + 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 281 + 84, 32, 49, 44, 49, 44, 49, 44, 49, 44, 39,111,110,101, 39, 46, 11, 6, 23, 282 + 21, 17, 1, 69,105,110,100,101,120,116, 50,101,100,116, 50, 14, 67, 82, 69, 283 + 65, 84, 69, 32, 73, 78, 68, 69, 88, 32,116, 50,101,100, 32, 79, 78, 32,116, 284 + 50, 40,101, 44,100, 41, 42, 10, 6, 23, 19, 17, 1, 63,105,110,100,101,120, 285 + 116, 49,101,116, 49, 13, 67, 82, 69, 65, 84, 69, 32, 73, 78, 68, 69, 88, 32, 286 + 116, 49,101, 32, 79, 78, 32,116, 49, 40,101, 41, 52, 9, 6, 23, 21, 17, 1, 287 + 81,105,110,100,101,120,116, 51,120, 49,116, 51, 12, 67, 82, 69, 65, 84, 69, 288 + 32, 73, 78, 68, 69, 88, 32,116, 51,120, 49, 32, 79, 78, 32,116, 51, 40, 97, 289 + 44, 98, 44, 99, 44,100, 44,101, 41, 35, 8, 6, 23, 55, 17, 1, 0,105,110, 290 + 100,101,120,115,113,108,105,116,101, 95, 97,117,116,111,105,110,100,101,120, 291 + 95,116, 53, 95, 49,116, 53, 10, 0, 0, 0, 67, 17, 17, 1,129, 3,116, 97, 292 + 98,108,101,116, 53,116, 53, 8, 67, 82, 69, 65, 84, 69, 32, 84, 65, 66, 76, 293 + 69, 32,116, 53, 40, 97, 32, 73, 78, 84, 69, 71, 69, 82, 32, 80, 82, 73, 77, 294 + 65, 82, 89, 32, 75, 69, 89, 44, 32, 98, 32, 84, 69, 88, 84, 32, 85, 78, 83, 295 + 13, 7, 21, 19, 19, 8,129, 17,118,105,101,119,118, 49, 48,118, 49, 48, 67, 296 + 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 49, 48, 40, 97, 44, 98, 44, 297 + 99, 44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 298 + 98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 32, 87, 72, 69, 299 + 82, 69, 32, 97, 60, 62, 50, 53, 2, 0, 0, 0, 1, 1,240, 0, 0, 0, 0, 300 + 24, 1,240, 1,220, 1,211, 1,199, 1,187, 1,176, 1,164, 1,148, 1,133, 301 + 1,116, 1, 99, 1, 86, 1, 67, 1, 55, 1, 43, 1, 31, 1, 18, 1, 5, 0, 302 + 249, 0,236, 0,224, 0,209, 0,191, 0,174, 0,157, 0,145, 0,132, 0,120, 303 + 0,108, 0, 95, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 7, 1, 0, 304 + 1, 1, 0, 1, 49, 51, 38, 15, 12, 7, 1, 1, 1, 1, 0, 1, 48, 37, 93, 305 + 7, 30, 11, 7, 1, 1, 1, 0, 0, 1, 47, 22, 16, 24, 11, 7, 1, 0, 1, 306 + 1, 0, 1, 47, 16, 40, 12, 12, 7, 1, 1, 1, 1, 0, 1, 46, 28, 88, 22, 307 + 2, 11, 7, 1, 1, 0, 1, 0, 1, 44, 48, 9, 19, 16, 7, 1, 1, 1, 0, 308 + 23, 1, 42, 20, 18, 98,101,103, 97,116, 22, 16, 7, 1, 1, 0, 1, 23, 1, 309 + 37, 17, 18,100,119,101,108,116, 16, 17, 7, 1, 1, 0, 1, 25, 1, 35, 38, 310 + 22, 99,117, 98,105,116,115, 17, 14, 7, 1, 1, 1, 0, 19, 1, 34, 26, 15, 311 + 97,114,107, 21, 11, 7, 1, 1, 1, 0, 0, 1, 32, 16, 7, 23, 12, 7, 1, 312 + 1, 1, 1, 0, 1, 28, 17, 67, 31, 29, 11, 7, 1, 0, 1, 1, 0, 1, 25, 313 + 7, 19, 11, 12, 7, 1, 1, 1, 1, 0, 1, 22, 45, 71, 28, 28, 12, 7, 1, 314 + 1, 1, 1, 0, 1, 21, 22, 92, 18, 4, 11, 7, 1, 1, 0, 1, 0, 1, 21, 315 + 22, 18, 18, 11, 7, 1, 1, 1, 1, 0, 9, 17, 29, 74, 36, 11, 7, 1, 1, 316 + 1, 0, 0, 1, 17, 29, 74, 25, 18, 7, 1, 1, 1, 1, 25, 1, 15, 6, 3, 317 + 11,116,101,109,112,108,101, 5, 12, 7, 1, 1, 1, 1, 0, 1, 12, 4, 38, 318 + 36, 27, 16, 7, 1, 0, 1, 1, 23, 1, 10, 89, 14,115,101,114,118,101, 14, 319 + 16, 7, 1, 1, 1, 1, 21, 1, 4, 41, 32, 35,110,101, 97,114, 3, 14, 7, 320 + 9, 0, 1, 1, 21, 1, 68, 32,100,111,116,104, 13, 15, 7, 0, 1, 1, 1, 321 + 21, 1, 21, 91, 38,110,101, 97,114, 6, 11, 7, 0, 1, 1, 1, 0, 1, 16, 322 + 81, 25, 9, 10, 7, 0, 1, 1, 8, 0, 1, 16, 7, 10, 11, 7, 0, 1, 1, 323 + 1, 0, 1, 7, 72, 31, 8, 11, 7, 0, 1, 1, 1, 0, 1, 6, 37, 31, 7, 324 + 8, 7, 0, 0, 0, 0, 0, 1, 35, 8, 7, 0, 0, 0, 0, 0, 1, 34, 8, 325 + 7, 0, 0, 0, 0, 0, 1, 33, 8, 7, 0, 0, 0, 23, 11, 7, 1, 0, 1, 326 + 1, 0, 1, 49, 51, 38, 15, 2, 0, 0, 0, 1, 1,241, 0, 0, 0, 0, 18, 327 + 1,241, 1,221, 1,211, 1,203, 1,193, 1,183, 1,173, 1,163, 1,151, 1, 328 + 143, 1,133, 1,122, 1,109, 1,100, 1, 92, 1, 83, 1, 74, 1, 64, 1, 55, 329 + 1, 46, 1, 34, 1, 22, 1, 13, 1, 4, 0,252, 0,241, 0,232, 0,218, 0, 330 + 209, 0,200, 0,191, 0,182, 0,173, 0,163, 0,153, 0,144, 0,136, 0,127, 331 + 0,116, 0,105, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 332 + 25, 1,116,101,109,112,108,101, 48, 10, 3, 25, 1,116,101,109,112,108,101, 333 + 15, 8, 3, 21, 1,115,111,109,101, 21, 7, 3, 19, 1,115,105,120, 11, 8, 334 + 3, 21, 1,115,104,101,119, 38, 9, 3, 23, 1,115,101,114,118,101, 10, 9, 335 + 3, 23, 1,115,101,114,118,101, 3, 8, 3, 21, 1,115,101,110,100, 40, 8, 336 + 3, 21, 1,115,101,110,100, 29, 8, 3, 21, 1,115,101,110,100, 12, 8, 3, 337 + 21, 1,115,101,110,100, 8, 8, 3, 21, 1,115, 97,118,101, 2, 13, 3, 31, 338 + 1,115, 97, 99,114,105,102,105, 99,101, 23, 8, 3, 21, 1,112,111,111,114, 339 + 16, 10, 3, 25, 1,112,108, 97, 99,101,115, 32, 7, 3, 19, 1,111,105,108, 340 + 49, 8, 3, 21, 1,110,101, 97,114, 7, 8, 3, 21, 1,110,101, 97,114, 4, 341 + 11, 3, 27, 1,109,111,114,110,105,110,103, 41, 11, 3, 27, 1,109,111,114, 342 + 110,105,110,103, 26, 8, 3, 21, 1,103,111,110,101, 25, 8, 3, 21, 1,103, 343 + 111,110,101, 5, 9, 3, 23, 1,100,119,101,108,116, 37, 8, 3, 21, 1,100, 344 + 111,116,104, 44, 8, 3, 21, 1,100,111,116,104, 13, 7, 3, 21, 9,100,111, 345 + 116,104, 8, 3, 21, 1,100,105,101,100, 14, 12, 3, 29, 1,100,101,112, 97, 346 + 114,116,101,100, 46, 10, 3, 25, 1, 99,117, 98,105,116,115, 35, 9, 3, 23, 347 + 1, 99,104,105,108,100, 36, 7, 3, 19, 1, 99, 97,110, 6, 11, 3, 27, 1, 348 + 98,101,116,119,101,101,110, 17, 9, 3, 23, 1, 98,101,103, 97,116, 43, 9, 349 + 3, 23, 1, 98,101,103, 97,116, 42, 9, 3, 23, 1, 98,101,103, 97,116, 39, 350 + 9, 3, 23, 1, 98,101,103, 97,116, 9, 7, 3, 19, 1, 97,114,107, 34, 9, 351 + 3, 23, 1, 97,110,103,101,114, 47, 9, 3, 23, 1, 97,110,103,101,108, 27, 352 + 9, 3, 23, 1, 97, 98,111,118,101, 45, 0, 0, 0, 17, 10, 3, 25, 1,116, 353 + 101,109,112,108,101, 48, 2, 0, 0, 0, 1, 1,239, 0, 0, 0, 0, 20, 1, 354 + 239, 1,206, 1,192, 1,180, 1,166, 1,152, 1,138, 1,125, 1,109, 1, 97, 355 + 1, 84, 1, 69, 1, 52, 1, 39, 1, 26, 1, 14, 1, 1, 0,243, 0,230, 0, 356 + 217, 0,201, 0,185, 0,172, 0,159, 0,147, 0,133, 0,120, 0,102, 0, 89, 357 + 0, 76, 0, 0, 0, 0, 12, 5, 21, 1, 1, 1,115,101,110,100, 26, 14, 40, 358 + 12, 5, 21, 1, 1, 1,115, 97,118,101, 39, 45, 2, 17, 5, 31, 1, 1, 1, 359 + 115, 97, 99,114,105,102,105, 99,101, 31, 6, 23, 12, 5, 21, 1, 1, 1,112, 360 + 111,111,114, 19, 44, 16, 13, 5, 25, 8, 1, 1,112,108, 97, 99,101,115, 16, 361 + 32, 11, 5, 19, 1, 1, 1,111,105,108, 38, 9, 49, 12, 5, 21, 1, 1, 1, 362 + 110,101, 97,114, 38, 21, 7, 12, 5, 21, 1, 1, 1,110,101, 97,114, 35, 41, 363 + 4, 15, 5, 27, 1, 1, 1,109,111,114,110,105,110,103, 17, 40, 26, 15, 5, 364 + 27, 1, 1, 1,109,111,114,110,105,110,103, 13, 46, 41, 12, 5, 21, 1, 1, 365 + 1,103,111,110,101, 28, 25, 5, 12, 5, 21, 1, 1, 1,103,111,110,101, 19, 366 + 10, 25, 13, 5, 23, 1, 1, 1,100,119,101,108,116, 18, 17, 37, 12, 5, 21, 367 + 1, 1, 1,100,111,116,104, 39, 4, 13, 11, 5, 21, 1, 1, 9,100,111,116, 368 + 104, 32, 40, 12, 5, 21, 1, 1, 1,100,111,116,104, 9, 48, 44, 12, 5, 21, 369 + 1, 1, 1,100,105,101,100, 27, 35, 14, 16, 5, 29, 1, 1, 1,100,101,112, 370 + 97,114,116,101,100, 22, 28, 46, 14, 5, 25, 1, 1, 1, 99,117, 98,105,116, 371 + 115, 22, 38, 35, 12, 5, 23, 1, 8, 1, 99,104,105,108,100, 17, 36, 11, 5, 372 + 19, 1, 1, 1, 99, 97,110, 11, 2, 6, 15, 5, 27, 1, 1, 1, 98,101,116, 373 + 119,101,101,110, 36, 29, 17, 12, 5, 23, 1, 8, 1, 98,101,103, 97,116, 50, 374 + 9, 13, 5, 23, 1, 1, 1, 98,101,103, 97,116, 45, 3, 39, 13, 5, 23, 1, 375 + 1, 1, 98,101,103, 97,116, 41, 5, 43, 13, 5, 23, 1, 1, 1, 98,101,103, 376 + 97,116, 5, 20, 42, 11, 5, 19, 1, 1, 1, 97,114,107, 20, 26, 34, 13, 5, 377 + 23, 1, 1, 1, 97,110,103,101,114, 40, 22, 47, 13, 5, 23, 1, 1, 1, 97, 378 + 110,103,101,108, 3, 22, 27, 12, 5, 23, 1, 9, 1, 97, 98,111,118,101, 45, 379 + 20, 13, 5, 23, 1, 1, 1, 0, 0, 0, 19, 12, 5, 21, 1, 1, 1,115,101, 380 + 110,100, 26, 14, 40, 13, 0, 0, 0, 28, 0, 78, 0, 1,241, 1,226, 1,210, 381 + 1,195, 1,180, 1,166, 1,151, 1,136, 1,121, 1,105, 1, 91, 1, 76, 1, 382 + 61, 1, 46, 1, 29, 1, 14, 0,252, 0,238, 0,224, 0,209, 0,194, 0,177, 383 + 0,157, 0,143, 0,128, 0,110, 0, 94, 0, 78, 0, 0, 0, 0, 0, 0, 0, 384 + 0, 0, 0, 0, 0, 0, 0, 14, 28, 6, 0, 1, 1, 1, 23, 17, 67, 31,119, 385 + 111,114,107,115, 14, 27, 6, 0, 1, 1, 1, 23, 22, 71, 3, 97,110,103,101, 386 + 108, 16, 26, 6, 0, 1, 1, 1, 27, 40, 98, 17,109,111,114,110,105,110,103, 387 + 13, 25, 6, 0, 1, 1, 1, 21, 10, 7, 19,103,111,110,101, 12, 24, 6, 0, 388 + 1, 1, 9, 21, 43, 46,119, 97,121,115, 18, 23, 6, 0, 1, 1, 1, 31, 6, 389 + 37, 31,115, 97, 99,114,105,102,105, 99,101, 15, 22, 6, 0, 1, 1, 1, 25, 390 + 45, 71, 28,116,104,111,117,103,104, 13, 21, 6, 0, 1, 1, 1, 21, 22, 92, 391 + 18,115,111,109,101, 13, 20, 6, 0, 9, 1, 1, 23, 2, 45, 97, 98,111,118, 392 + 101, 12, 19, 6, 0, 1, 1, 8, 21, 4, 58,119, 97,121,115, 12, 18, 6, 0, 393 + 1, 1, 1, 19, 44, 19, 43,119, 97,114, 16, 17, 6, 0, 1, 1, 1, 27, 29, 394 + 74, 36, 98,101,116,119,101,101,110, 13, 16, 6, 0, 1, 1, 1, 21, 44, 52, 395 + 19,112,111,111,114, 15, 15, 6, 0, 1, 1, 1, 25, 6, 3, 11,116,101,109, 396 + 112,108,101, 13, 14, 6, 0, 1, 1, 1, 21, 35, 48, 27,100,105,101,100, 13, 397 + 13, 6, 0, 1, 1, 1, 21, 4, 21, 39,100,111,116,104, 13, 12, 6, 0, 1, 398 + 1, 1, 21, 4, 38, 36,115,101,110,100, 12, 11, 6, 0, 1, 1, 1, 19, 13, 399 + 48, 22,115,105,120, 14, 10, 6, 0, 1, 1, 1, 23, 41, 89, 14,115,101,114, 400 + 118,101, 13, 9, 6, 0, 8, 1, 1, 23, 16, 50, 98,101,103, 97,116, 13, 8, 401 + 6, 0, 1, 1, 1, 21, 42, 49, 34,115,101,110,100, 13, 7, 6, 0, 1, 1, 402 + 1, 21, 21, 91, 38,110,101, 97,114, 12, 6, 6, 0, 1, 1, 1, 19, 2, 37, 403 + 11, 99, 97,110, 13, 5, 6, 0, 1, 1, 1, 21, 25, 27, 28,103,111,110,101, 404 + 13, 4, 6, 0, 1, 1, 1, 21, 41, 32, 35,110,101, 97,114, 14, 3, 6, 0, 405 + 1, 1, 1, 23, 32, 24, 26,115,101,114,118,101, 13, 2, 6, 0, 1, 1, 1, 406 + 21, 45, 14, 39,115, 97,118,101, 13, 1, 6, 0, 1, 1, 1, 21, 40, 68, 32, 407 + 100,111,116,104, 13, 0, 0, 0, 22, 0,166, 0, 1,241, 1,226, 1,210, 1, 408 + 194, 1,183, 1,169, 1,152, 1,137, 1,121, 1,106, 1, 90, 1, 75, 1, 57, 409 + 1, 41, 1, 25, 1, 10, 0,250, 0,231, 0,215, 0,198, 0,184, 0,166, 0, 410 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 411 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 413 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 414 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 415 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 416 + 50, 6, 0, 1, 1, 1, 27, 9, 92, 29,116,104,101,114,101,105,110, 12, 49, 417 + 6, 0, 1, 1, 1, 19, 9, 51, 38,111,105,108, 15, 48, 6, 0, 1, 1, 1, 418 + 25, 37, 93, 7,116,101,109,112,108,101, 14, 47, 6, 0, 1, 1, 1, 23, 22, 419 + 16, 40, 97,110,103,101,114, 17, 46, 6, 0, 1, 1, 1, 29, 28, 88, 22,100, 420 + 101,112, 97,114,116,101,100, 14, 45, 6, 0, 1, 1, 1, 23, 47, 54, 12, 97, 421 + 98,111,118,101, 13, 44, 6, 0, 1, 1, 1, 21, 48, 15, 9,100,111,116,104, 422 + 14, 43, 6, 0, 1, 1, 1, 23, 5, 23, 41, 98,101,103, 97,116, 14, 42, 6, 423 + 0, 1, 1, 1, 23, 20, 18, 5, 98,101,103, 97,116, 16, 41, 6, 0, 1, 1, 424 + 1, 27, 46, 92, 13,109,111,114,110,105,110,103, 13, 40, 6, 0, 1, 1, 1, 425 + 21, 14, 30, 26,115,101,110,100, 14, 39, 6, 0, 1, 1, 1, 23, 3, 21, 45, 426 + 98,101,103, 97,116, 13, 38, 6, 0, 1, 1, 1, 21, 10, 97, 34,115,104,101, 427 + 119, 14, 37, 6, 0, 1, 1, 1, 23, 17, 66, 18,100,119,101,108,116, 13, 36, 428 + 6, 0, 8, 1, 1, 23, 52, 17, 99,104,105,108,100, 15, 35, 6, 0, 1, 1, 429 + 1, 25, 38, 34, 22, 99,117, 98,105,116,115, 12, 34, 6, 0, 1, 1, 1, 19, 430 + 26, 15, 20, 97,114,107, 9, 33, 6, 0, 1, 1, 1, 0, 7, 72, 31, 14, 32, 431 + 6, 0, 1, 1, 8, 25, 16, 7,112,108, 97, 99,101,115, 14, 31, 6, 0, 1, 432 + 1, 1, 23, 39, 90, 27,116,114,117,116,104, 13, 30, 6, 0, 1, 1, 1, 21, 433 + 16, 81, 25,119, 97,108,107, 13, 29, 6, 0, 1, 1, 1, 21, 34, 62, 27,115, 434 + 101,110,100, 10, 0, 0, 0, 41, 0,116, 0, 1,251, 1,241, 1,231, 1,221, 435 + 1,211, 1,203, 1,193, 1,183, 1,173, 1,163, 1,151, 1,143, 1,133, 1, 436 + 122, 1,109, 1,100, 1, 92, 1, 83, 1, 74, 1, 64, 1, 55, 1, 46, 1, 34, 437 + 1, 22, 1, 13, 1, 4, 0,252, 0,241, 0,232, 0,218, 0,209, 0,200, 0, 438 + 191, 0,182, 0,173, 0,163, 0,153, 0,144, 0,136, 0,127, 0,116, 0,105, 439 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11,116,101, 440 + 109,112,108,101, 48, 10, 3, 25, 1,116,101,109,112,108,101, 15, 8, 3, 21, 441 + 1,115,111,109,101, 21, 7, 3, 19, 1,115,105,120, 11, 8, 3, 21, 1,115, 442 + 104,101,119, 38, 9, 3, 23, 1,115,101,114,118,101, 10, 9, 3, 23, 1,115, 443 + 101,114,118,101, 3, 8, 3, 21, 1,115,101,110,100, 40, 8, 3, 21, 1,115, 444 + 101,110,100, 29, 8, 3, 21, 1,115,101,110,100, 12, 8, 3, 21, 1,115,101, 445 + 110,100, 8, 8, 3, 21, 1,115, 97,118,101, 2, 13, 3, 31, 1,115, 97, 99, 446 + 114,105,102,105, 99,101, 23, 8, 3, 21, 1,112,111,111,114, 16, 10, 3, 25, 447 + 1,112,108, 97, 99,101,115, 32, 7, 3, 19, 1,111,105,108, 49, 8, 3, 21, 448 + 1,110,101, 97,114, 7, 8, 3, 21, 1,110,101, 97,114, 4, 11, 3, 27, 1, 449 + 109,111,114,110,105,110,103, 41, 11, 3, 27, 1,109,111,114,110,105,110,103, 450 + 26, 8, 3, 21, 1,103,111,110,101, 25, 8, 3, 21, 1,103,111,110,101, 5, 451 + 9, 3, 23, 1,100,119,101,108,116, 37, 8, 3, 21, 1,100,111,116,104, 44, 452 + 8, 3, 21, 1,100,111,116,104, 13, 7, 3, 21, 9,100,111,116,104, 8, 3, 453 + 21, 1,100,105,101,100, 14, 12, 3, 29, 1,100,101,112, 97,114,116,101,100, 454 + 46, 10, 3, 25, 1, 99,117, 98,105,116,115, 35, 9, 3, 23, 1, 99,104,105, 455 + 108,100, 36, 7, 3, 19, 1, 99, 97,110, 6, 11, 3, 27, 1, 98,101,116,119, 456 + 101,101,110, 17, 9, 3, 23, 1, 98,101,103, 97,116, 43, 9, 3, 23, 1, 98, 457 + 101,103, 97,116, 42, 9, 3, 23, 1, 98,101,103, 97,116, 39, 9, 3, 23, 1, 458 + 98,101,103, 97,116, 9, 7, 3, 19, 1, 97,114,107, 34, 9, 3, 23, 1, 97, 459 + 110,103,101,114, 47, 9, 3, 23, 1, 97,110,103,101,108, 27, 9, 3, 23, 1, 460 + 97, 98,111,118,101, 45, 9, 3, 23, 1, 97, 98,111,118,101, 20, 4, 3, 0, 461 + 1, 33, 10, 0, 0, 0, 8, 1,178, 0, 1,244, 1,233, 1,223, 1,214, 1, 462 + 206, 1,197, 1,188, 1,178, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 463 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 464 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 465 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 466 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 467 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 468 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 469 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 470 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 471 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 472 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 473 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 474 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 475 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 476 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 477 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 478 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 479 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 480 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 481 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 482 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 483 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 484 + 3, 23, 1,119,111,114,107,115, 28, 8, 3, 21, 1,119, 97,121,115, 24, 8, 485 + 3, 21, 1,119, 97,121,115, 19, 7, 3, 19, 1,119, 97,114, 18, 8, 3, 21, 486 + 1,119, 97,108,107, 30, 9, 3, 23, 1,116,114,117,116,104, 31, 10, 3, 25, 487 + 1,116,104,111,117,103,104, 22, 11, 3, 27, 1,116,104,101,114,101,105,110, 488 + 50, 10, 0, 0, 0, 31, 0, 89, 0, 1,247, 1,233, 1,220, 1,206, 1,192, 489 + 1,180, 1,166, 1,152, 1,138, 1,125, 1,109, 1, 97, 1, 84, 1, 69, 1, 490 + 52, 1, 39, 1, 26, 1, 14, 1, 1, 0,243, 0,230, 0,217, 0,201, 0,185, 491 + 0,172, 0,159, 0,147, 0,133, 0,120, 0,102, 0, 89, 0, 76, 0, 0, 0, 492 + 0, 0, 0, 0, 13, 1, 1,115,101,110,100, 26, 14, 40, 12, 5, 21, 1, 1, 493 + 1,115, 97,118,101, 39, 45, 2, 17, 5, 31, 1, 1, 1,115, 97, 99,114,105, 494 + 102,105, 99,101, 31, 6, 23, 12, 5, 21, 1, 1, 1,112,111,111,114, 19, 44, 495 + 16, 13, 5, 25, 8, 1, 1,112,108, 97, 99,101,115, 16, 32, 11, 5, 19, 1, 496 + 1, 1,111,105,108, 38, 9, 49, 12, 5, 21, 1, 1, 1,110,101, 97,114, 38, 497 + 21, 7, 12, 5, 21, 1, 1, 1,110,101, 97,114, 35, 41, 4, 15, 5, 27, 1, 498 + 1, 1,109,111,114,110,105,110,103, 17, 40, 26, 15, 5, 27, 1, 1, 1,109, 499 + 111,114,110,105,110,103, 13, 46, 41, 12, 5, 21, 1, 1, 1,103,111,110,101, 500 + 28, 25, 5, 12, 5, 21, 1, 1, 1,103,111,110,101, 19, 10, 25, 13, 5, 23, 501 + 1, 1, 1,100,119,101,108,116, 18, 17, 37, 12, 5, 21, 1, 1, 1,100,111, 502 + 116,104, 39, 4, 13, 11, 5, 21, 1, 1, 9,100,111,116,104, 32, 40, 12, 5, 503 + 21, 1, 1, 1,100,111,116,104, 9, 48, 44, 12, 5, 21, 1, 1, 1,100,105, 504 + 101,100, 27, 35, 14, 16, 5, 29, 1, 1, 1,100,101,112, 97,114,116,101,100, 505 + 22, 28, 46, 14, 5, 25, 1, 1, 1, 99,117, 98,105,116,115, 22, 38, 35, 12, 506 + 5, 23, 1, 8, 1, 99,104,105,108,100, 17, 36, 11, 5, 19, 1, 1, 1, 99, 507 + 97,110, 11, 2, 6, 15, 5, 27, 1, 1, 1, 98,101,116,119,101,101,110, 36, 508 + 29, 17, 12, 5, 23, 1, 8, 1, 98,101,103, 97,116, 50, 9, 13, 5, 23, 1, 509 + 1, 1, 98,101,103, 97,116, 45, 3, 39, 13, 5, 23, 1, 1, 1, 98,101,103, 510 + 97,116, 41, 5, 43, 13, 5, 23, 1, 1, 1, 98,101,103, 97,116, 5, 20, 42, 511 + 11, 5, 19, 1, 1, 1, 97,114,107, 20, 26, 34, 13, 5, 23, 1, 1, 1, 97, 512 + 110,103,101,114, 40, 22, 47, 13, 5, 23, 1, 1, 1, 97,110,103,101,108, 3, 513 + 22, 27, 12, 5, 23, 1, 9, 1, 97, 98,111,118,101, 45, 20, 13, 5, 23, 1, 514 + 1, 1, 97, 98,111,118,101, 12, 47, 45, 8, 5, 0, 1, 1, 1, 31, 7, 33, 515 + 10, 0, 0, 0, 18, 1, 13, 0, 1,243, 1,230, 1,217, 1,203, 1,189, 1, 516 + 176, 1,164, 1,151, 1,136, 1,121, 1,105, 1, 90, 1, 76, 1, 63, 1, 51, 517 + 1, 39, 1, 27, 1, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 518 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 519 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 520 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 521 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 522 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 523 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 524 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 525 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 526 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 527 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 528 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 529 + 0, 0, 0, 13, 5, 23, 1, 1, 1,119,111,114,107,115, 31, 17, 28, 11, 5, 530 + 21, 9, 1, 1,119, 97,121,115, 43, 24, 11, 5, 21, 8, 1, 1,119, 97,121, 531 + 115, 4, 19, 11, 5, 19, 1, 1, 1,119, 97,114, 43, 44, 18, 12, 5, 21, 1, 532 + 1, 1,119, 97,108,107, 25, 16, 30, 13, 5, 23, 1, 1, 1,116,114,117,116, 533 + 104, 27, 39, 31, 14, 5, 25, 1, 1, 1,116,104,111,117,103,104, 28, 45, 22, 534 + 15, 5, 27, 1, 1, 1,116,104,101,114,101,105,110, 29, 9, 50, 14, 5, 25, 535 + 1, 1, 1,116,101,109,112,108,101, 11, 6, 15, 14, 5, 25, 1, 1, 1,116, 536 + 101,109,112,108,101, 7, 37, 48, 12, 5, 21, 1, 1, 1,115,111,109,101, 18, 537 + 22, 21, 11, 5, 19, 1, 1, 1,115,105,120, 22, 13, 11, 12, 5, 21, 1, 1, 538 + 1,115,104,101,119, 34, 10, 38, 13, 5, 23, 1, 1, 1,115,101,114,118,101, 539 + 26, 32, 3, 13, 5, 23, 1, 1, 1,115,101,114,118,101, 14, 41, 10, 12, 5, 540 + 21, 1, 1, 1,115,101,110,100, 36, 4, 12, 12, 5, 21, 1, 1, 1,115,101, 541 + 110,100, 34, 42, 8, 12, 5, 21, 1, 1, 1,115,101,110,100, 27, 34, 29, 10, 542 + 0, 0, 0, 28, 0, 82, 0, 1,241, 1,226, 1,211, 1,197, 1,181, 1,166, 543 + 1,151, 1,137, 1,121, 1,104, 1, 84, 1, 73, 1, 59, 1, 41, 1, 26, 1, 544 + 11, 0,253, 0,238, 0,223, 0,207, 0,191, 0,175, 0,159, 0,144, 0,129, 545 + 0,113, 0, 97, 0, 82, 0, 68, 0, 0, 0, 0, 0, 14, 1, 1, 19, 26, 34, 546 + 15, 20, 97,114,107, 14, 6, 1, 1, 1, 1, 21, 25, 5, 27, 28,103,111,110, 547 + 101, 15, 6, 1, 1, 1, 1, 23, 22, 47, 16, 40, 97,110,103,101,114, 15, 6, 548 + 1, 1, 1, 1, 23, 22, 27, 71, 3, 97,110,103,101,108, 14, 6, 1, 1, 1, 549 + 1, 21, 22, 21, 92, 18,115,111,109,101, 14, 6, 1, 1, 1, 1, 21, 21, 7, 550 + 91, 38,110,101, 97,114, 15, 6, 1, 1, 1, 1, 23, 20, 42, 18, 5, 98,101, 551 + 103, 97,116, 15, 6, 1, 1, 1, 1, 23, 17, 37, 66, 18,100,119,101,108,116, 552 + 15, 6, 1, 1, 1, 1, 23, 17, 28, 67, 31,119,111,114,107,115, 15, 6, 1, 553 + 1, 1, 8, 25, 16, 32, 7,112,108, 97, 99,101,115, 14, 6, 1, 1, 1, 1, 554 + 21, 16, 30, 81, 25,119, 97,108,107, 14, 6, 1, 1, 1, 1, 21, 14, 40, 30, 555 + 26,115,101,110,100, 13, 6, 1, 1, 1, 1, 19, 13, 11, 48, 22,115,105,120, 556 + 14, 6, 1, 1, 1, 1, 21, 10, 38, 97, 34,115,104,101,119, 14, 6, 1, 1, 557 + 1, 1, 21, 10, 25, 7, 19,103,111,110,101, 17, 6, 1, 1, 1, 1, 27, 9, 558 + 50, 92, 29,116,104,101,114,101,105,110, 13, 6, 1, 1, 1, 1, 19, 9, 49, 559 + 51, 38,111,105,108, 10, 6, 1, 1, 1, 1, 0, 7, 33, 72, 31, 19, 6, 1, 560 + 1, 1, 1, 31, 6, 23, 37, 31,115, 97, 99,114,105,102,105, 99,101, 16, 6, 561 + 1, 1, 1, 1, 25, 6, 15, 3, 11,116,101,109,112,108,101, 15, 6, 1, 1, 562 + 1, 1, 23, 5, 43, 23, 41, 98,101,103, 97,116, 13, 6, 1, 1, 1, 8, 21, 563 + 4, 19, 58,119, 97,121,115, 14, 6, 1, 1, 1, 1, 21, 4, 13, 21, 39,100, 564 + 111,116,104, 14, 6, 1, 1, 1, 1, 21, 4, 12, 38, 36,115,101,110,100, 15, 565 + 6, 1, 1, 1, 1, 23, 3, 39, 21, 45, 98,101,103, 97,116, 13, 6, 1, 1, 566 + 1, 1, 19, 2, 6, 37, 11, 99, 97,110, 14, 6, 9, 1, 1, 1, 23, 20, 2, 567 + 45, 97, 98,111,118,101, 14, 6, 8, 1, 1, 1, 23, 36, 52, 17, 99,104,105, 568 + 108,100, 14, 6, 8, 1, 1, 1, 23, 9, 16, 50, 98,101,103, 97,116, 10, 0, 569 + 0, 0, 21, 0,177, 0, 1,237, 1,219, 1,203, 1,188, 1,173, 1,156, 1, 570 + 139, 1,123, 1,109, 1, 91, 1, 76, 1, 60, 1, 45, 1, 31, 1, 16, 1, 2, 571 + 0,243, 0,226, 0,208, 0,192, 0,177, 0, 0, 0, 0, 0, 0, 0, 0, 0, 572 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 573 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 574 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 575 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 576 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 577 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 578 + 0, 0, 0, 0, 14, 6, 1, 1, 1, 1, 21, 48, 44, 15, 9,100,111,116,104, 579 + 15, 6, 1, 1, 1, 1, 23, 47, 45, 54, 12, 97, 98,111,118,101, 17, 6, 1, 580 + 1, 1, 1, 27, 46, 41, 92, 13,109,111,114,110,105,110,103, 16, 6, 1, 1, 581 + 1, 1, 25, 45, 22, 71, 28,116,104,111,117,103,104, 14, 6, 1, 1, 1, 1, 582 + 21, 45, 2, 14, 39,115, 97,118,101, 13, 6, 1, 1, 1, 1, 19, 44, 18, 19, 583 + 43,119, 97,114, 14, 6, 1, 1, 1, 1, 21, 44, 16, 52, 19,112,111,111,114, 584 + 13, 6, 1, 1, 1, 9, 21, 43, 24, 46,119, 97,121,115, 14, 6, 1, 1, 1, 585 + 1, 21, 42, 8, 49, 34,115,101,110,100, 15, 6, 1, 1, 1, 1, 23, 41, 10, 586 + 89, 14,115,101,114,118,101, 14, 6, 1, 1, 1, 1, 21, 41, 4, 32, 35,110, 587 + 101, 97,114, 17, 6, 1, 1, 1, 1, 27, 40, 26, 98, 17,109,111,114,110,105, 588 + 110,103, 13, 6, 1, 9, 1, 1, 21, 40, 68, 32,100,111,116,104, 15, 6, 1, 589 + 1, 1, 1, 23, 39, 31, 90, 27,116,114,117,116,104, 16, 6, 1, 1, 1, 1, 590 + 25, 38, 35, 34, 22, 99,117, 98,105,116,115, 16, 6, 1, 1, 1, 1, 25, 37, 591 + 48, 93, 7,116,101,109,112,108,101, 14, 6, 1, 1, 1, 1, 21, 35, 14, 48, 592 + 27,100,105,101,100, 14, 6, 1, 1, 1, 1, 21, 34, 29, 62, 27,115,101,110, 593 + 100, 15, 6, 1, 1, 1, 1, 23, 32, 3, 24, 26,115,101,114,118,101, 17, 6, 594 + 1, 1, 1, 1, 27, 29, 17, 74, 36, 98,101,116,119,101,101,110, 18, 6, 1, 595 + 1, 1, 1, 29, 28, 46, 88, 22,100,101,112, 97,114,116,101,100, 10, 0, 0, 596 + 0, 32, 0, 95, 0, 1,247, 1,238, 1,229, 1,220, 1,211, 1,199, 1,187, 597 + 1,176, 1,164, 1,148, 1,133, 1,116, 1, 99, 1, 86, 1, 67, 1, 55, 1, 598 + 43, 1, 31, 1, 18, 1, 5, 0,249, 0,236, 0,224, 0,209, 0,191, 0,174, 599 + 0,157, 0,145, 0,132, 0,120, 0,108, 0, 95, 0, 83, 0, 0, 0, 0, 0, 600 + 0, 0, 0, 0, 0, 0, 0, 12, 1, 1, 0, 1, 49, 51, 38, 15, 12, 7, 1, 601 + 1, 1, 1, 0, 1, 48, 37, 93, 7, 30, 11, 7, 1, 1, 1, 0, 0, 1, 47, 602 + 22, 16, 24, 11, 7, 1, 0, 1, 1, 0, 1, 47, 16, 40, 12, 12, 7, 1, 1, 603 + 1, 1, 0, 1, 46, 28, 88, 22, 2, 11, 7, 1, 1, 0, 1, 0, 1, 44, 48, 604 + 9, 19, 16, 7, 1, 1, 1, 0, 23, 1, 42, 20, 18, 98,101,103, 97,116, 22, 605 + 16, 7, 1, 1, 0, 1, 23, 1, 37, 17, 18,100,119,101,108,116, 16, 17, 7, 606 + 1, 1, 0, 1, 25, 1, 35, 38, 22, 99,117, 98,105,116,115, 17, 14, 7, 1, 607 + 1, 1, 0, 19, 1, 34, 26, 15, 97,114,107, 21, 11, 7, 1, 1, 1, 0, 0, 608 + 1, 32, 16, 7, 23, 12, 7, 1, 1, 1, 1, 0, 1, 28, 17, 67, 31, 29, 11, 609 + 7, 1, 0, 1, 1, 0, 1, 25, 7, 19, 11, 12, 7, 1, 1, 1, 1, 0, 1, 610 + 22, 45, 71, 28, 28, 12, 7, 1, 1, 1, 1, 0, 1, 21, 22, 92, 18, 4, 11, 611 + 7, 1, 1, 0, 1, 0, 1, 21, 22, 18, 18, 11, 7, 1, 1, 1, 1, 0, 9, 612 + 17, 29, 74, 36, 11, 7, 1, 1, 1, 0, 0, 1, 17, 29, 74, 25, 18, 7, 1, 613 + 1, 1, 1, 25, 1, 15, 6, 3, 11,116,101,109,112,108,101, 5, 12, 7, 1, 614 + 1, 1, 1, 0, 1, 12, 4, 38, 36, 27, 16, 7, 1, 0, 1, 1, 23, 1, 10, 615 + 89, 14,115,101,114,118,101, 14, 16, 7, 1, 1, 1, 1, 21, 1, 4, 41, 32, 616 + 35,110,101, 97,114, 3, 14, 7, 9, 0, 1, 1, 21, 1, 68, 32,100,111,116, 617 + 104, 13, 15, 7, 0, 1, 1, 1, 21, 1, 21, 91, 38,110,101, 97,114, 6, 11, 618 + 7, 0, 1, 1, 1, 0, 1, 16, 81, 25, 9, 10, 7, 0, 1, 1, 8, 0, 1, 619 + 16, 7, 10, 11, 7, 0, 1, 1, 1, 0, 1, 7, 72, 31, 8, 11, 7, 0, 1, 620 + 1, 1, 0, 1, 6, 37, 31, 7, 8, 7, 0, 0, 0, 0, 0, 1, 35, 8, 7, 621 + 0, 0, 0, 0, 0, 1, 34, 8, 7, 0, 0, 0, 0, 0, 1, 33, 8, 7, 0, 622 + 0, 0, 0, 0, 1, 32, 8, 7, 0, 0, 0, 0, 0, 1, 31, 10, 0, 0, 0, 623 + 2, 1,231, 0, 1,244, 1,231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 624 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 625 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 626 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 627 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 628 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 629 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 630 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 631 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 632 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 633 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 634 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 635 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 636 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 637 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 638 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 639 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 640 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 641 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 642 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 643 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 644 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 645 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 646 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 647 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 648 + 0, 0, 0, 0, 0, 0, 0, 0, 12, 7, 1, 1, 1, 1, 0, 1, 49, 9, 51, 649 + 38, 26, 11, 7, 1, 1, 0, 1, 0, 1, 49, 9, 38, 20, 13, 0, 0, 0, 23, 650 + 0, 67, 0, 1,238, 1,220, 1,202, 1,186, 1,168, 1,148, 1,130, 1,107, 651 + 1, 86, 1, 65, 1, 44, 1, 27, 1, 14, 0,250, 0,224, 0,205, 0,184, 0, 652 + 165, 0,145, 0,123, 0,106, 0, 86, 0, 67, 0, 0, 0, 0, 0, 0, 0, 0, 653 + 0, 0, 0, 0, 0, 17, 23, 6, 0, 23, 1, 1, 21,107,110,111,119,110, 52, 654 + 19,112,111,111,114, 18, 22, 6, 0, 23, 1, 1, 23, 97, 98,111,118,101, 24, 655 + 26,115,101,114,118,101, 15, 21, 6, 0, 19, 1, 1, 21,119, 97,114, 52, 19, 656 + 112,111,111,114, 20, 20, 6, 0, 27, 1, 8, 25,110,111,116,104,105,110,103, 657 + 7,112,108, 97, 99,101,115, 18, 19, 6, 0, 23, 1, 1, 23, 98,101,103, 97, 658 + 116, 90, 27,116,114,117,116,104, 17, 18, 6, 0, 23, 1, 1, 21,100,119,101, 659 + 108,116, 21, 39,100,111,116,104, 19, 17, 6, 0, 27, 1, 1, 21,109,111,114, 660 + 110,105,110,103, 52, 19,112,111,111,114, 17, 16, 6, 0, 21, 1, 1, 23,115, 661 + 104,101,119, 90, 27,116,114,117,116,104, 24, 15, 6, 0, 27, 1, 1, 31,116, 662 + 104,101,114,101,105,110, 37, 31,115, 97, 99,114,105,102,105, 99,101, 18, 14, 663 + 6, 0, 23, 1, 8, 25,115,109,111,116,101, 7,112,108, 97, 99,101,115, 11, 664 + 13, 6, 0, 19, 1, 1, 0, 97,114,107, 72, 31, 15, 12, 6, 0, 21, 1, 8, 665 + 21,119,105,110,101, 58,119, 97,121,115, 19, 11, 6, 0, 21, 1, 1, 27,115, 666 + 111,109,101, 98, 17,109,111,114,110,105,110,103, 19, 10, 6, 0, 27, 1, 1, 667 + 21, 98,101,116,119,101,101,110, 92, 18,115,111,109,101, 19, 9, 6, 0, 21, 668 + 1, 1, 27,115, 97,118,101, 74, 36, 98,101,116,119,101,101,110, 21, 8, 6, 669 + 0, 25, 1, 1, 27,116,104,111,117,103,104, 98, 17,109,111,114,110,105,110, 670 + 103, 16, 7, 6, 0, 21, 1, 1, 21,115,101,110,100, 49, 34,115,101,110,100, 671 + 18, 6, 6, 0, 25, 1, 1, 21,119,105,115,100,111,109, 38, 36,115,101,110, 672 + 100, 16, 5, 6, 0, 23, 1, 9, 21, 97,110,103,101,114, 46,119, 97,121,115, 673 + 14, 4, 6, 0, 19, 1, 1, 19, 99, 97,110, 19, 43,119, 97,114, 16, 3, 6, 674 + 0, 23, 1, 1, 19,111,102,102,101,114, 48, 22,115,105,120, 16, 2, 6, 0, 675 + 23, 1, 8, 21,119,111,114,107,115, 58,119, 97,121,115, 16, 1, 6, 0, 23, 676 + 1, 1, 19,116,114,117,116,104, 37, 11, 99, 97,110, 13, 0, 0, 0, 22, 0, 677 + 64, 0, 1,230, 1,213, 1,191, 1,169, 1,148, 1,130, 1,108, 1, 89, 1, 678 + 70, 1, 51, 1, 34, 1, 16, 0,253, 0,233, 0,214, 0,194, 0,174, 0,151, 679 + 0,132, 0,109, 0, 90, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 680 + 0, 24, 45, 6, 0, 35, 1, 1, 23,105,110,104, 97, 98,105,116, 97,110,116, 681 + 115, 23, 41, 98,101,103, 97,116, 17, 44, 6, 0, 23, 1, 1, 21, 97,110,103, 682 + 101,108, 48, 27,100,105,101,100, 21, 43, 6, 0, 25, 1, 1, 27,116,101,109, 683 + 112,108,101, 74, 36, 98,101,116,119,101,101,110, 17, 42, 6, 0, 23, 1, 1, 684 + 21, 99,104,105,108,100, 81, 25,119, 97,108,107, 21, 41, 6, 0, 21, 1, 1, 685 + 31,119, 97,121,115, 37, 31,115, 97, 99,114,105,102,105, 99,101, 18, 40, 6, 686 + 0, 21, 1, 1, 25,112,111,111,114, 93, 7,116,101,109,112,108,101, 18, 39, 687 + 6, 0, 21, 1, 1, 25,100,111,116,104, 3, 11,116,101,109,112,108,101, 17, 688 + 38, 6, 0, 23, 1, 1, 21,102,114,117,105,116, 62, 27,115,101,110,100, 18, 689 + 37, 6, 0, 23, 1, 1, 23,115,101,114,118,101, 90, 27,116,114,117,116,104, 690 + 17, 36, 6, 0, 21, 1, 1, 23,110,101, 97,114, 90, 27,116,114,117,116,104, 691 + 16, 35, 6, 0, 21, 1, 1, 21,108,111,110,103, 14, 39,115, 97,118,101, 15, 692 + 34, 6, 0, 21, 1, 1, 19,119, 97,108,107, 15, 20, 97,114,107, 17, 33, 6, 693 + 0, 25, 1, 9, 21, 99,117, 98,105,116,115, 46,119, 97,121,115, 17, 32, 6, 694 + 0, 21, 1, 1, 23,103,111,110,101, 23, 41, 98,101,103, 97,116, 17, 31, 6, 695 + 0, 23, 1, 1, 21,119,104,105,108,101, 49, 34,115,101,110,100, 20, 30, 6, 696 + 0, 21, 1, 1, 29,112, 97,114,116, 88, 22,100,101,112, 97,114,116,101,100, 697 + 16, 29, 6, 0, 21, 1, 1, 21, 98,101, 97,114, 92, 18,115,111,109,101, 19, 698 + 28, 6, 0, 25, 1, 1, 23,112,108, 97, 99,101,115, 23, 41, 98,101,103, 97, 699 + 116, 20, 27, 6, 0, 27, 1, 1, 23,116,104,121,115,101,108,102, 54, 12, 97, 700 + 98,111,118,101, 20, 26, 6, 0, 29, 1, 1, 21,100,101,112, 97,114,116,101, 701 + 100, 92, 18,115,111,109,101, 15, 25, 6, 0, 21, 1, 1, 19,116,101,108,108, 702 + 19, 43,119, 97,114, 24, 24, 6, 0, 31, 1, 1, 27,115, 97, 99,114,105,102, 703 + 105, 99,101, 92, 13,109,111,114,110,105,110,103, 13, 0, 0, 0, 5, 1,162, 704 + 0, 1,239, 1,221, 1,203, 1,182, 1,162, 0, 0, 0, 0, 0, 0, 0, 0, 705 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 706 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 707 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 708 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 709 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 710 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 711 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 712 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 713 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 714 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 715 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 716 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 717 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 718 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 719 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 720 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 721 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 722 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 723 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 724 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 725 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 50, 6, 0, 23, 1, 1, 726 + 23,119,114, 97,116,104, 21, 45, 98,101,103, 97,116, 19, 49, 6, 0, 21, 1, 727 + 1, 27,116,114,101,101, 98, 17,109,111,114,110,105,110,103, 16, 48, 6, 0, 728 + 19, 1, 1, 23,115,105,120, 71, 3, 97,110,103,101,108, 16, 47, 6, 0, 21, 729 + 1, 1, 21,100,105,101,100, 7, 19,103,111,110,101, 15, 46, 6, 0, 19, 1, 730 + 1, 21,111,105,108, 81, 25,119, 97,108,107, 10, 0, 0, 0, 40, 0,106, 0, 731 + 1,246, 1,236, 1,226, 1,218, 1,209, 1,199, 1,187, 1,179, 1,169, 1, 732 + 158, 1,145, 1,136, 1,127, 1,117, 1,107, 1, 98, 1, 82, 1, 72, 1, 63, 733 + 1, 51, 1, 42, 1, 30, 1, 20, 1, 12, 1, 3, 0,248, 0,239, 0,225, 0, 734 + 216, 0,207, 0,197, 0,188, 0,180, 0,170, 0,161, 0,152, 0,141, 0,129, 735 + 0,118, 0,106, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,116,114, 736 + 101,101, 49, 11, 3, 27, 1,116,104,121,115,101,108,102, 27, 10, 3, 25, 1, 737 + 116,104,111,117,103,104, 8, 11, 3, 27, 1,116,104,101,114,101,105,110, 15, 738 + 10, 3, 25, 1,116,101,109,112,108,101, 43, 8, 3, 21, 1,116,101,108,108, 739 + 25, 8, 3, 21, 1,115,111,109,101, 11, 9, 3, 23, 1,115,109,111,116,101, 740 + 14, 7, 3, 19, 1,115,105,120, 48, 8, 3, 21, 1,115,104,101,119, 16, 9, 741 + 3, 23, 1,115,101,114,118,101, 37, 8, 3, 21, 1,115,101,110,100, 7, 8, 742 + 3, 21, 1,115, 97,118,101, 9, 13, 3, 31, 1,115, 97, 99,114,105,102,105, 743 + 99,101, 24, 8, 3, 21, 1,112,111,111,114, 40, 10, 3, 25, 1,112,108, 97, 744 + 99,101,115, 28, 8, 3, 21, 1,112, 97,114,116, 30, 7, 3, 19, 1,111,105, 745 + 108, 46, 9, 3, 23, 1,111,102,102,101,114, 3, 11, 3, 27, 1,110,111,116, 746 + 104,105,110,103, 20, 8, 3, 21, 1,110,101, 97,114, 36, 11, 3, 27, 1,109, 747 + 111,114,110,105,110,103, 17, 8, 3, 21, 1,108,111,110,103, 35, 9, 3, 23, 748 + 1,107,110,111,119,110, 23, 15, 3, 35, 1,105,110,104, 97, 98,105,116, 97, 749 + 110,116,115, 45, 8, 3, 21, 1,103,111,110,101, 32, 9, 3, 23, 1,102,114, 750 + 117,105,116, 38, 9, 3, 23, 1,100,119,101,108,116, 18, 8, 3, 21, 1,100, 751 + 111,116,104, 39, 8, 3, 21, 1,100,105,101,100, 47, 12, 3, 29, 1,100,101, 752 + 112, 97,114,116,101,100, 26, 10, 3, 25, 1, 99,117, 98,105,116,115, 33, 9, 753 + 3, 23, 1, 99,104,105,108,100, 42, 7, 3, 19, 1, 99, 97,110, 4, 11, 3, 754 + 27, 1, 98,101,116,119,101,101,110, 10, 9, 3, 23, 1, 98,101,103, 97,116, 755 + 19, 8, 3, 21, 1, 98,101, 97,114, 29, 7, 3, 19, 1, 97,114,107, 13, 9, 756 + 3, 23, 1, 97,110,103,101,114, 5, 9, 3, 23, 1, 97,110,103,101,108, 44, 757 + 9, 3, 23, 1, 97, 98,111,118,101, 22, 10, 0, 0, 0, 9, 1,171, 0, 1, 758 + 247, 1,238, 1,230, 1,221, 1,211, 1,202, 1,191, 1,181, 1,171, 0, 0, 759 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 760 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 761 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 762 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 763 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 764 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 765 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 766 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 767 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 768 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 769 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 770 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 771 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 772 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 773 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 774 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 775 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 776 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 777 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 778 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 779 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 780 + 9, 3, 23, 1,119,114, 97,116,104, 50, 9, 3, 23, 1,119,111,114,107,115, 781 + 2, 10, 3, 25, 1,119,105,115,100,111,109, 6, 8, 3, 21, 1,119,105,110, 782 + 101, 12, 9, 3, 23, 1,119,104,105,108,101, 31, 8, 3, 21, 1,119, 97,121, 783 + 115, 41, 7, 3, 19, 1,119, 97,114, 21, 8, 3, 21, 1,119, 97,108,107, 34, 784 + 8, 3, 23, 9,116,114,117,116,104, 13, 0, 0, 0, 5, 0, 84, 0, 1, 78, 785 + 0,249, 0,177, 1,163, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 786 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 787 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 788 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 91, 19, 789 + 7, 21, 19, 19, 8,129, 33,118,105,101,119,118, 50, 49,118, 50, 49, 67, 82, 790 + 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 50, 49, 40, 97, 44, 98, 44, 99, 791 + 44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 792 + 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 50, 32, 79, 82, 68, 69, 793 + 82, 32, 66, 89, 32, 98, 32, 76, 73, 77, 73, 84, 32, 49, 48, 70, 17, 6, 21, 794 + 19, 19, 8,121,118,105,101,119,118, 53, 48,118, 53, 48, 67, 82, 69, 65, 84, 795 + 69, 32, 86, 73, 69, 87, 32,118, 53, 48, 40, 97, 44, 98, 41, 32, 65, 83, 32, 796 + 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 32, 70, 82, 79, 77, 32,116, 53, 32, 797 + 87, 72, 69, 82, 69, 32, 97, 60, 62, 50, 53, 83, 16, 7, 21, 19, 19, 8,129, 798 + 17,118,105,101,119,118, 52, 48,118, 52, 48, 67, 82, 69, 65, 84, 69, 32, 86, 799 + 73, 69, 87, 32,118, 52, 48, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 800 + 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 801 + 32, 70, 82, 79, 77, 32,116, 52, 32, 87, 72, 69, 82, 69, 32, 97, 60, 62, 50, 802 + 53, 83, 15, 7, 21, 19, 19, 8,129, 17,118,105,101,119,118, 51, 48,118, 51, 803 + 48, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 51, 48, 40, 97, 44, 804 + 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 805 + 97, 44, 98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 51, 32, 87, 806 + 72, 69, 82, 69, 32, 97, 60, 62, 50, 53, 91, 18, 7, 21, 19, 19, 8,129, 33, 807 + 118,105,101,119,118, 49, 49,118, 49, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73, 808 + 69, 87, 32,118, 49, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 809 + 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 32, 810 + 70, 82, 79, 77, 32,116, 49, 32, 79, 82, 68, 69, 82, 32, 66, 89, 32, 98, 32, 811 + 76, 73, 77, 73, 84, 32, 49, 48, 13, 1,163, 0, 4, 0, 40, 0, 1, 70, 0, 812 + 233, 0,152, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 813 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,110, 23, 7, 21, 19, 19, 8,129, 71, 814 + 118,105,101,119,118, 49, 50,118, 49, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73, 815 + 69, 87, 32,118, 49, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 816 + 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115,117,109, 40, 97, 41, 44, 32, 817 + 97,118,103, 40, 98, 41, 44, 32, 99,111,117,110,116, 40, 42, 41, 44, 32,109, 818 + 105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79, 77, 32,116, 49, 32, 71, 82, 819 + 79, 85, 80, 32, 66, 89, 32, 53, 79, 22, 7, 21, 19, 19, 8,129, 9,118,105, 820 + 101,119,118, 53, 49,118, 53, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 821 + 32,118, 53, 49, 40, 97, 44, 98, 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 822 + 32, 97, 44, 98, 32, 70, 82, 79, 77, 32,116, 53, 32, 79, 82, 68, 69, 82, 32, 823 + 66, 89, 32, 98, 32, 76, 73, 77, 73, 84, 32, 49, 48, 91, 21, 7, 21, 19, 19, 824 + 8,129, 33,118,105,101,119,118, 52, 49,118, 52, 49, 67, 82, 69, 65, 84, 69, 825 + 32, 86, 73, 69, 87, 32,118, 52, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 826 + 41, 32, 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 827 + 44,101, 32, 70, 82, 79, 77, 32,116, 52, 32, 79, 82, 68, 69, 82, 32, 66, 89, 828 + 32, 98, 32, 76, 73, 77, 73, 84, 32, 49, 48, 91, 20, 7, 21, 19, 19, 8,129, 829 + 33,118,105,101,119,118, 51, 49,118, 51, 49, 67, 82, 69, 65, 84, 69, 32, 86, 830 + 73, 69, 87, 32,118, 51, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 831 + 65, 83, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 832 + 32, 70, 82, 79, 77, 32,116, 51, 32, 79, 82, 68, 69, 82, 32, 66, 89, 32, 98, 833 + 32, 76, 73, 77, 73, 84, 32, 49, 48, 0, 0, 0, 93, 19, 19, 8,129, 33,118, 834 + 105,101,119,118, 50, 49,118, 50, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 835 + 87, 32,118, 50, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 836 + 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 32, 70, 837 + 82, 79, 77, 32,116, 50, 32, 79, 82, 68, 69, 82, 32, 66, 89, 32, 98, 32, 76, 838 + 73, 77, 73, 84, 32, 49, 48, 13, 0, 0, 0, 3, 0, 66, 0, 1,107, 0,214, 839 + 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 840 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 841 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 17, 26, 842 + 7, 21, 19, 19, 8,130, 13,118,105,101,119,118, 52, 50,118, 52, 50, 67, 82, 843 + 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 52, 50, 40, 97, 44, 98, 44, 99, 844 + 44,100, 44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115, 845 + 117,109, 40, 97, 41, 44, 32, 97,118,103, 40, 98, 41, 44, 32, 99,111,117,110, 846 + 116, 40, 42, 41, 44, 32,109,105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79, 847 + 77, 32,116, 52, 32, 71, 82, 79, 85, 80, 32, 66, 89, 32, 53, 10, 32, 32, 32, 848 + 32, 72, 65, 86, 73, 78, 71, 32,109,105,110, 40,100, 41, 60, 51, 48, 32, 79, 849 + 82, 68, 69, 82, 32, 66, 89, 32, 51, 44, 32, 49,129, 18, 25, 7, 21, 19, 19, 850 + 8,130, 15,118,105,101,119,118, 51, 50,118, 51, 50, 67, 82, 69, 65, 84, 69, 851 + 32, 86, 73, 69, 87, 32,118, 51, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 852 + 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115,117,109, 40, 97, 853 + 41, 44, 32, 97,118,103, 40, 98, 41, 44, 32, 99,111,117,110,116, 40, 42, 41, 854 + 44, 32,109,105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79, 77, 32,116, 51, 855 + 32, 71, 82, 79, 85, 80, 32, 66, 89, 32, 53, 10, 32, 32, 32, 32, 72, 65, 86, 856 + 73, 78, 71, 32, 99,111,117,110,116, 40, 42, 41, 62, 49, 32, 79, 82, 68, 69, 857 + 82, 32, 66, 89, 32, 51, 44, 32, 49,129, 18, 24, 7, 21, 19, 19, 8,130, 15, 858 + 118,105,101,119,118, 50, 50,118, 50, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73, 859 + 69, 87, 32,118, 50, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 860 + 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,115,117,109, 40, 97, 41, 44, 32, 861 + 97,118,103, 40, 98, 41, 44, 32, 99,111,117,110,116, 40, 42, 41, 44, 32,109, 862 + 105,110, 40,100, 41, 44, 32,101, 32, 70, 82, 79, 77, 32,116, 50, 32, 71, 82, 863 + 79, 85, 80, 32, 66, 89, 32, 53, 10, 32, 32, 32, 32, 72, 65, 86, 73, 78, 71, 864 + 32, 99,111,117,110,116, 40, 42, 41, 62, 49, 32, 79, 82, 68, 69, 82, 32, 66, 865 + 89, 32, 51, 44, 32, 49, 13, 1,108, 0, 3, 0, 83, 0, 0,225, 0, 83, 1, 866 + 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 867 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 868 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 869 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 11, 28, 7, 21, 19, 870 + 19, 8,130, 1,118,105,101,119,118, 49, 51,118, 49, 51, 67, 82, 69, 65, 84, 871 + 69, 32, 86, 73, 69, 87, 32,118, 49, 51, 40, 97, 44, 98, 44, 99, 44,100, 44, 872 + 101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 873 + 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 10, 32, 32, 85, 78, 73, 874 + 79, 78, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 875 + 32, 70, 82, 79, 77, 32,116, 50, 10, 32, 32, 85, 78, 73, 79, 78, 32, 83, 69, 876 + 76, 69, 67, 84, 32, 97, 44, 98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 877 + 32,116, 51,129, 8, 27, 7, 21, 19, 19, 8,129,123,118,105,101,119,118, 53, 878 + 50,118, 53, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 53, 50, 879 + 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 880 + 76, 69, 67, 84, 32, 99,111,117,110,116, 40, 42, 41, 44, 32,109,105,110, 40, 881 + 98, 41, 44, 32,115,117, 98,115,116,114, 40, 98, 44, 49, 44, 49, 41, 44, 32, 882 + 109,105,110, 40, 97, 41, 44, 32,109, 97,120, 40, 97, 41, 32, 70, 82, 79, 77, 883 + 32,116, 53, 10, 32, 32, 32, 71, 82, 79, 85, 80, 32, 66, 89, 32, 51, 32, 79, 884 + 82, 68, 69, 82, 32, 66, 89, 32, 49, 0, 0, 0, 28, 21, 19, 19, 8,130, 13, 885 + 118,105,101,119,118, 52, 50,118, 52, 50, 67, 82, 69, 65, 84, 69, 32, 86,118, 886 + 29, 7, 21, 19, 19, 8,129, 87,118,105,101,119,118, 50, 51,118, 50, 51, 67, 887 + 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32,118, 50, 51, 40, 97, 44, 98, 44, 888 + 99, 44,100, 44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32, 889 + 97, 44, 98, 44, 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 10, 32, 890 + 32, 69, 88, 67, 69, 80, 84, 32, 83, 69, 76, 69, 67, 84, 32, 97, 44, 98, 44, 891 + 99, 44,100, 44,101, 32, 70, 82, 79, 77, 32,116, 49, 32, 87, 72, 69, 82, 69, 892 + 32, 98, 60, 50, 53, 13, 0, 0, 0, 3, 0, 40, 0, 1,134, 1, 12, 0, 40, 893 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 894 + 0, 0, 0, 0, 0, 0, 0,129, 97, 32, 7, 21, 19, 19, 8,131, 45,118,105, 895 + 101,119,118, 54, 50,118, 54, 50, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 896 + 32,118, 54, 50, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 10, 897 + 32, 32, 83, 69, 76, 69, 67, 84, 32,116, 49, 46, 97, 44,116, 50, 46, 98, 44, 898 + 116, 51, 46, 99, 44,116, 52, 46,100, 44,116, 53, 46, 98, 10, 32, 32, 32, 32, 899 + 70, 82, 79, 77, 32,116, 49, 32, 74, 79, 73, 78, 32,116, 50, 32, 79, 78, 32, 900 + 40,116, 49, 46, 97, 61,116, 50, 46, 98, 41, 10, 32, 32, 32, 32, 32, 32, 32, 901 + 32, 32, 32, 32, 32, 74, 79, 73, 78, 32,116, 51, 32, 79, 78, 32, 40,116, 49, 902 + 46, 97, 61,116, 51, 46, 97, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 903 + 32, 32, 74, 79, 73, 78, 32,116, 52, 32, 79, 78, 32, 40,116, 52, 46, 98, 61, 904 + 116, 51, 46, 98, 41, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 76, 905 + 69, 70, 84, 32, 74, 79, 73, 78, 32,116, 53, 32, 79, 78, 32, 40,116, 53, 46, 906 + 97, 61,116, 49, 46, 99, 41,120, 31, 7, 21, 19, 19, 8,129, 91,118,105,101, 907 + 119,118, 54, 49,118, 54, 49, 67, 82, 69, 65, 84, 69, 32, 86, 73, 69, 87, 32, 908 + 118, 54, 49, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 65, 83, 10, 32, 909 + 32, 83, 69, 76, 69, 67, 84, 32,116, 50, 46, 97, 44,116, 51, 46, 98, 44,116, 910 + 50, 46, 99, 44,116, 51, 46,100, 44,116, 50, 46,101, 10, 32, 32, 32, 32, 70, 911 + 82, 79, 77, 32,116, 50, 32, 76, 69, 70, 84, 32, 74, 79, 73, 78, 32,116, 51, 912 + 32, 79, 78, 32, 40,116, 50, 46, 97, 61,116, 51, 46, 97, 41,120, 30, 7, 21, 913 + 19, 19, 8,129, 91,118,105,101,119,118, 54, 48,118, 54, 48, 67, 82, 69, 65, 914 + 84, 69, 32, 86, 73, 69, 87, 32,118, 54, 48, 40, 97, 44, 98, 44, 99, 44,100, 915 + 44,101, 41, 32, 65, 83, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,116, 49, 46, 916 + 97, 44,116, 50, 46, 98, 44,116, 49, 46, 99, 44,116, 50, 46,100, 44,116, 49, 917 + 46,101, 10, 32, 32, 32, 32, 70, 82, 79, 77, 32,116, 49, 32, 76, 69, 70, 84, 918 + 32, 74, 79, 73, 78, 32,116, 50, 32, 79, 78, 32, 40,116, 49, 46, 97, 61,116, 919 + 50, 46, 98, 41, 13, 0, 0, 0, 1, 1, 73, 0, 1, 73, 0, 0, 0, 0, 0, 920 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 921 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 922 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 923 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 924 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 925 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 926 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 927 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 928 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 929 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 930 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 931 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 932 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 933 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 934 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 935 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 936 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,129, 52, 33, 7, 21, 19, 19, 8,130, 937 + 83,118,105,101,119,118, 55, 48,118, 55, 48, 67, 82, 69, 65, 84, 69, 32, 86, 938 + 73, 69, 87, 32,118, 55, 48, 40, 97, 44, 98, 44, 99, 44,100, 44,101, 41, 32, 939 + 65, 83, 10, 32, 32, 87, 73, 84, 72, 32, 82, 69, 67, 85, 82, 83, 73, 86, 69, 940 + 32, 99, 48, 40,120, 41, 32, 65, 83, 32, 40, 86, 65, 76, 85, 69, 83, 40, 49, 941 + 41, 32, 85, 78, 73, 79, 78, 32, 65, 76, 76, 32, 83, 69, 76, 69, 67, 84, 32, 942 + 120, 43, 49, 32, 70, 82, 79, 77, 32, 99, 48, 32, 87, 72, 69, 82, 69, 32,120, 943 + 60, 57, 41, 10, 32, 32, 83, 69, 76, 69, 67, 84, 32,120, 44, 32, 98, 44, 32, 944 + 99, 44, 32,100, 44, 32,101, 32, 70, 82, 79, 77, 32, 99, 48, 32, 74, 79, 73, 945 + 78, 32,116, 49, 32, 79, 78, 32, 40,116, 49, 46, 97, 61, 53, 48, 45, 99, 48, 946 + 46,120, 41, 947 +}; 948 +
Added test/optfuzz-db01.txt.
1 +-- Run this script through the sqlite3 command-line shell in order to generate 2 +-- a database file containing lots of data for testing purposes. 3 +-- 4 +-- This script assumes that the "bin2c" program is available on ones $PATH. 5 +-- The "bin2c" program reads a binary file and outputs C-code that creates 6 +-- an array of bytes holding the content of that file. 7 +-- 8 +-- This script is designed to create many tables and views all having 9 +-- 5 columns, "a" through "e", and with a variety of integers, short strings, 10 +-- and NULL values. 11 +-- 12 +.open -new testdb01.db 13 +PRAGMA page_size=512; 14 +BEGIN; 15 +CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT, d INT, e INT); 16 +WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<50) 17 +INSERT INTO t1(a,b,c,d,e) SELECT x,abs(random()%51), 18 + abs(random()%100), abs(random()%51), abs(random()%100) FROM c; 19 +CREATE TABLE t2(a INT, b INT, c INT,d INT,e INT,PRIMARY KEY(b,a))WITHOUT ROWID; 20 +INSERT INTO t2 SELECT * FROM t1; 21 +CREATE TABLE t3(a,b,c,d,e); 22 +INSERT INTO t3 SELECT a,b,c,d,e FROM t1 ORDER BY random() LIMIT 5; 23 +INSERT INTO t3 SELECT null,b,c,d,e FROM t1 ORDER BY random() LIMIT 5; 24 +INSERT INTO t3 SELECT a,null,c,d,e FROM t1 ORDER BY random() LIMIT 5; 25 +INSERT INTO t3 SELECT a,b,null,d,e FROM t1 ORDER BY random() LIMIT 5; 26 +INSERT INTO t3 SELECT a,b,c,null,e FROM t1 ORDER BY random() LIMIT 5; 27 +INSERT INTO t3 SELECT a,b,c,d,null FROM t1 ORDER BY random() LIMIT 5; 28 +INSERT INTO t3 SELECT null,null,null,null,null FROM t1 LIMIT 5; 29 +CREATE INDEX t3x1 ON t3(a,b,c,d,e); 30 +CREATE TABLE t4(a INT UNIQUE NOT NULL, b INT UNIQUE NOT NULL,c,d,e); 31 +INSERT OR IGNORE INTO t4 SELECT a,b,c,d,e FROM t3; 32 +CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT UNIQUE,c,d,e); 33 +INSERT INTO t5(b) VALUES 34 + ('truth'), 35 + ('works'), 36 + ('offer'), 37 + ('can'), 38 + ('anger'), 39 + ('wisdom'), 40 + ('send'), 41 + ('though'), 42 + ('save'), 43 + ('between'), 44 + ('some'), 45 + ('wine'), 46 + ('ark'), 47 + ('smote'), 48 + ('therein'), 49 + ('shew'), 50 + ('morning'), 51 + ('dwelt'), 52 + ('begat'), 53 + ('nothing'), 54 + ('war'), 55 + ('above'), 56 + ('known'), 57 + ('sacrifice'), 58 + ('tell'), 59 + ('departed'), 60 + ('thyself'), 61 + ('places'), 62 + ('bear'), 63 + ('part'), 64 + ('while'), 65 + ('gone'), 66 + ('cubits'), 67 + ('walk'), 68 + ('long'), 69 + ('near'), 70 + ('serve'), 71 + ('fruit'), 72 + ('doth'), 73 + ('poor'), 74 + ('ways'), 75 + ('child'), 76 + ('temple'), 77 + ('angel'), 78 + ('inhabitants'), 79 + ('oil'), 80 + ('died'), 81 + ('six'), 82 + ('tree'), 83 + ('wrath'); 84 +UPDATE t1 SET e=(SELECT b FROM t5 WHERE t5.a=(t1.e%51)); 85 +UPDATE t5 SET (c,d,e) = 86 + (SELECT c,d,e FROM t1 WHERE t1.a=abs(t5.a+random()/100)%50+1); 87 +UPDATE t2 SET e=(SELECT b FROM t5 WHERE t5.a=(t2.e%51)); 88 +UPDATE t3 SET e=(SELECT b FROM t5 WHERE t5.a=t3.e); 89 +CREATE INDEX t1e ON t1(e); 90 +CREATE INDEX t2ed ON t2(e,d); 91 +CREATE VIEW v00(a,b,c,d,e) AS SELECT 1,1,1,1,'one'; 92 +CREATE VIEW v10(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t1 WHERE a<>25; 93 +CREATE VIEW v20(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t2 WHERE a<>25; 94 +CREATE VIEW v30(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t3 WHERE a<>25; 95 +CREATE VIEW v40(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t4 WHERE a<>25; 96 +CREATE VIEW v50(a,b) AS SELECT a,b FROM t5 WHERE a<>25; 97 +CREATE VIEW v11(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t1 ORDER BY b LIMIT 10; 98 +CREATE VIEW v21(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t2 ORDER BY b LIMIT 10; 99 +CREATE VIEW v31(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t3 ORDER BY b LIMIT 10; 100 +CREATE VIEW v41(a,b,c,d,e) AS SELECT a,b,c,d,e FROM t4 ORDER BY b LIMIT 10; 101 +CREATE VIEW v51(a,b) AS SELECT a,b FROM t5 ORDER BY b LIMIT 10; 102 +CREATE VIEW v12(a,b,c,d,e) AS 103 + SELECT sum(a), avg(b), count(*), min(d), e FROM t1 GROUP BY 5; 104 +CREATE VIEW v22(a,b,c,d,e) AS 105 + SELECT sum(a), avg(b), count(*), min(d), e FROM t2 GROUP BY 5 106 + HAVING count(*)>1 ORDER BY 3, 1; 107 +CREATE VIEW v32(a,b,c,d,e) AS 108 + SELECT sum(a), avg(b), count(*), min(d), e FROM t3 GROUP BY 5 109 + HAVING count(*)>1 ORDER BY 3, 1; 110 +CREATE VIEW v42(a,b,c,d,e) AS 111 + SELECT sum(a), avg(b), count(*), min(d), e FROM t4 GROUP BY 5 112 + HAVING min(d)<30 ORDER BY 3, 1; 113 +CREATE VIEW v52(a,b,c,d,e) AS 114 + SELECT count(*), min(b), substr(b,1,1), min(a), max(a) FROM t5 115 + GROUP BY 3 ORDER BY 1; 116 + 117 +CREATE VIEW v13(a,b,c,d,e) AS 118 + SELECT a,b,c,d,e FROM t1 119 + UNION SELECT a,b,c,d,e FROM t2 120 + UNION SELECT a,b,c,d,e FROM t3; 121 +CREATE VIEW v23(a,b,c,d,e) AS 122 + SELECT a,b,c,d,e FROM t1 123 + EXCEPT SELECT a,b,c,d,e FROM t1 WHERE b<25; 124 + 125 +CREATE VIEW v60(a,b,c,d,e) AS 126 + SELECT t1.a,t2.b,t1.c,t2.d,t1.e 127 + FROM t1 LEFT JOIN t2 ON (t1.a=t2.b); 128 +CREATE VIEW v61(a,b,c,d,e) AS 129 + SELECT t2.a,t3.b,t2.c,t3.d,t2.e 130 + FROM t2 LEFT JOIN t3 ON (t2.a=t3.a); 131 +CREATE VIEW v62(a,b,c,d,e) AS 132 + SELECT t1.a,t2.b,t3.c,t4.d,t5.b 133 + FROM t1 JOIN t2 ON (t1.a=t2.b) 134 + JOIN t3 ON (t1.a=t3.a) 135 + JOIN t4 ON (t4.b=t3.b) 136 + LEFT JOIN t5 ON (t5.a=t1.c); 137 +CREATE VIEW v70(a,b,c,d,e) AS 138 + WITH RECURSIVE c0(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c0 WHERE x<9) 139 + SELECT x, b, c, d, e FROM c0 JOIN t1 ON (t1.a=50-c0.x); 140 +COMMIT; 141 +VACUUM; 142 +.shell bin2c testdb01.db
Added test/optfuzz.c.
1 +/* 2 +** 2018-03-21 3 +** 4 +** The author disclaims copyright to this source code. In place of 5 +** a legal notice, here is a blessing: 6 +** 7 +** May you do good and not evil. 8 +** May you find forgiveness for yourself and forgive others. 9 +** May you share freely, never taking more than you give. 10 +** 11 +************************************************************************* 12 +** 13 +** This program attempts to verify the correctness of the SQLite query 14 +** optimizer by fuzzing. 15 +** 16 +** The input is an SQL script, presumably generated by a fuzzer. The 17 +** argument is the name of the input. If no files are named, standard 18 +** input is read. 19 +** 20 +** The SQL script is run twice, once with optimization enabled, and again 21 +** with optimization disabled. If the output is not equivalent, an error 22 +** is printed and the program returns non-zero. 23 +*/ 24 + 25 +/* Include the SQLite amalgamation, after making appropriate #defines. 26 +*/ 27 +#define SQLITE_THREADSAFE 0 28 +#define SQLITE_OMIT_LOAD_EXTENSION 1 29 +#define SQLITE_ENABLE_DESERIALIZE 1 30 +#include "sqlite3.c" 31 + 32 +/* Content of the read-only test database */ 33 +#include "optfuzz-db01.c" 34 + 35 +/* 36 +** Prepare a single SQL statement. Panic if anything goes wrong 37 +*/ 38 +static sqlite3_stmt *prepare_sql(sqlite3 *db, const char *zFormat, ...){ 39 + char *zSql; 40 + int rc; 41 + sqlite3_stmt *pStmt = 0; 42 + va_list ap; 43 + 44 + va_start(ap, zFormat); 45 + zSql = sqlite3_vmprintf(zFormat, ap); 46 + va_end(ap); 47 + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); 48 + if( rc ){ 49 + printf("Error: %s\nSQL: %s\n", 50 + sqlite3_errmsg(db), zSql); 51 + exit(1); 52 + } 53 + sqlite3_free(zSql); 54 + return pStmt; 55 +} 56 + 57 +/* 58 +** Run SQL. Panic if anything goes wrong 59 +*/ 60 +static void run_sql(sqlite3 *db, const char *zFormat, ...){ 61 + char *zSql; 62 + int rc; 63 + char *zErr = 0; 64 + va_list ap; 65 + 66 + va_start(ap, zFormat); 67 + zSql = sqlite3_vmprintf(zFormat, ap); 68 + va_end(ap); 69 + rc = sqlite3_exec(db, zSql, 0, 0, &zErr); 70 + if( rc || zErr ){ 71 + printf("Error: %s\nsqlite3_errmsg: %s\nSQL: %s\n", 72 + zErr, sqlite3_errmsg(db), zSql); 73 + exit(1); 74 + } 75 + sqlite3_free(zSql); 76 +} 77 + 78 +/* 79 +** Run one or more SQL statements contained in zSql against database dbRun. 80 +** Store the input in database dbOut. 81 +*/ 82 +static int optfuzz_exec( 83 + sqlite3 *dbRun, /* The database on which the SQL executes */ 84 + const char *zSql, /* The SQL to be executed */ 85 + sqlite3 *dbOut, /* Store results in this database */ 86 + const char *zOutTab, /* Store results in this table of dbOut */ 87 + int *pnStmt, /* Write the number of statements here */ 88 + int *pnRow, /* Write the number of rows here */ 89 + int bTrace /* Print query results if true */ 90 +){ 91 + int rc = SQLITE_OK; /* Return code */ 92 + const char *zLeftover; /* Tail of unprocessed SQL */ 93 + sqlite3_stmt *pStmt = 0; /* The current SQL statement */ 94 + sqlite3_stmt *pIns = 0; /* Statement to insert into dbOut */ 95 + const char *zCol; /* Single column value */ 96 + int nCol; /* Number of output columns */ 97 + char zLine[4000]; /* Complete row value */ 98 + 99 + run_sql(dbOut, "BEGIN"); 100 + run_sql(dbOut, "CREATE TABLE IF NOT EXISTS staging(x TEXT)"); 101 + run_sql(dbOut, "CREATE TABLE IF NOT EXISTS \"%w\"(x TEXT)", zOutTab); 102 + pIns = prepare_sql(dbOut, "INSERT INTO staging(x) VALUES(?1)"); 103 + *pnRow = *pnStmt = 0; 104 + while( rc==SQLITE_OK && zSql && zSql[0] ){ 105 + zLeftover = 0; 106 + rc = sqlite3_prepare_v2(dbRun, zSql, -1, &pStmt, &zLeftover); 107 + zSql = zLeftover; 108 + assert( rc==SQLITE_OK || pStmt==0 ); 109 + if( rc!=SQLITE_OK ){ 110 + printf("Error with [%s]\n%s\n", zSql, sqlite3_errmsg(dbRun)); 111 + break; 112 + } 113 + if( !pStmt ) continue; 114 + (*pnStmt)++; 115 + nCol = sqlite3_column_count(pStmt); 116 + run_sql(dbOut, "DELETE FROM staging;"); 117 + while( sqlite3_step(pStmt)==SQLITE_ROW ){ 118 + int i, j; 119 + for(i=j=0; i<nCol && j<sizeof(zLine)-50; i++){ 120 + int eType = sqlite3_column_type(pStmt, i); 121 + if( eType==SQLITE_NULL ){ 122 + zCol = "NULL"; 123 + }else{ 124 + zCol = (const char*)sqlite3_column_text(pStmt, i); 125 + } 126 + if( i ) zLine[j++] = ','; 127 + if( eType==SQLITE_TEXT ){ 128 + sqlite3_snprintf(sizeof(zLine)-j, zLine+j, "'%q'", zCol); 129 + }else{ 130 + sqlite3_snprintf(sizeof(zLine)-j, zLine+j, "%s", zCol); 131 + } 132 + j += (int)strlen(zLine+j); 133 + } 134 + /* Detect if any row is too large and throw an error, because we will 135 + ** want to go back and look more closely at that case */ 136 + if( j>=sizeof(zLine)-100 ){ 137 + printf("Excessively long output line: %d bytes\n" ,j); 138 + exit(1); 139 + } 140 + if( bTrace ){ 141 + printf("%s\n", zLine); 142 + } 143 + (*pnRow)++; 144 + sqlite3_bind_text(pIns, 1, zLine, j, SQLITE_TRANSIENT); 145 + rc = sqlite3_step(pIns); 146 + assert( rc==SQLITE_DONE ); 147 + rc = sqlite3_reset(pIns); 148 + } 149 + run_sql(dbOut, 150 + "INSERT INTO \"%w\"(x) VALUES('### %q ###')", 151 + zOutTab, sqlite3_sql(pStmt) 152 + ); 153 + run_sql(dbOut, 154 + "INSERT INTO \"%w\"(x) SELECT group_concat(x,char(10))" 155 + " FROM (SELECT x FROM staging ORDER BY x)", 156 + zOutTab 157 + ); 158 + run_sql(dbOut, "COMMIT"); 159 + sqlite3_finalize(pStmt); 160 + pStmt = 0; 161 + } 162 + sqlite3_finalize(pStmt); 163 + sqlite3_finalize(pIns); 164 + return rc; 165 +} 166 + 167 +/* 168 +** Read the content of file zName into memory obtained from sqlite3_malloc64() 169 +** and return a pointer to the buffer. The caller is responsible for freeing 170 +** the memory. 171 +** 172 +** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes 173 +** read. 174 +** 175 +** For convenience, a nul-terminator byte is always appended to the data read 176 +** from the file before the buffer is returned. This byte is not included in 177 +** the final value of (*pnByte), if applicable. 178 +** 179 +** NULL is returned if any error is encountered. The final value of *pnByte 180 +** is undefined in this case. 181 +*/ 182 +static char *readFile(const char *zName, int *pnByte){ 183 + FILE *in = fopen(zName, "rb"); 184 + long nIn; 185 + size_t nRead; 186 + char *pBuf; 187 + if( in==0 ) return 0; 188 + fseek(in, 0, SEEK_END); 189 + nIn = ftell(in); 190 + rewind(in); 191 + pBuf = sqlite3_malloc64( nIn+1 ); 192 + if( pBuf==0 ) return 0; 193 + nRead = fread(pBuf, nIn, 1, in); 194 + fclose(in); 195 + if( nRead!=1 ){ 196 + sqlite3_free(pBuf); 197 + return 0; 198 + } 199 + pBuf[nIn] = 0; 200 + if( pnByte ) *pnByte = nIn; 201 + return pBuf; 202 +} 203 + 204 +int main(int argc, char **argv){ 205 + int nIn = 0; /* Number of input files */ 206 + char **azIn = 0; /* Names of input files */ 207 + sqlite3 *dbOut = 0; /* Database to hold results */ 208 + sqlite3 *dbRun = 0; /* Database used for tests */ 209 + int bTrace = 0; /* Show query results */ 210 + int bShowValid = 0; /* Just list inputs that are valid SQL */ 211 + int nRow, nStmt; /* Number of rows and statements */ 212 + int i, rc; 213 + 214 + for(i=1; i<argc; i++){ 215 + const char *z = argv[i]; 216 + if( z[0]=='-' && z[1]=='-' ) z++; 217 + if( strcmp(z,"-help")==0 ){ 218 + printf("Usage: %s [OPTIONS] FILENAME ...\n", argv[0]); 219 + printf("Options:\n"); 220 + printf(" --help Show his message\n"); 221 + printf(" --output-trace Show each line of SQL output\n"); 222 + printf(" --valid-sql List FILEs that are valid SQL\n"); 223 + return 0; 224 + } 225 + else if( strcmp(z,"-output-trace")==0 ){ 226 + bTrace = 1; 227 + } 228 + else if( strcmp(z,"-valid-sql")==0 ){ 229 + bShowValid = 1; 230 + } 231 + else if( z[0]=='-' ){ 232 + printf("unknown option \"%s\". Use --help for details\n", argv[i]); 233 + return 1; 234 + } 235 + else { 236 + nIn++; 237 + azIn = realloc(azIn, sizeof(azIn[0])*nIn); 238 + if( azIn==0 ){ 239 + printf("out of memory\n"); 240 + exit(1); 241 + } 242 + azIn[nIn-1] = argv[i]; 243 + } 244 + } 245 + 246 + sqlite3_open(":memory:", &dbOut); 247 + sqlite3_open(":memory:", &dbRun); 248 + sqlite3_deserialize(dbRun, "main", data001, sizeof(data001), 249 + sizeof(data001), SQLITE_DESERIALIZE_READONLY); 250 + for(i=0; i<nIn; i++){ 251 + char *zSql = readFile(azIn[i], 0); 252 + sqlite3_stmt *pCk; 253 + sqlite3_exec(dbRun, "ROLLBACK", 0, 0, 0); 254 + if( bShowValid ){ 255 + rc = sqlite3_exec(dbRun, zSql, 0, 0, 0); 256 + if( rc==SQLITE_OK ) printf("%s\n", azIn[i]); 257 + sqlite3_free(zSql); 258 + continue; 259 + } 260 + sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, dbRun, 0); 261 + if( bTrace ) printf("%s: Optimized\n", azIn[i]); 262 + rc = optfuzz_exec(dbRun, zSql, dbOut, "opt", &nStmt, &nRow, bTrace); 263 + if( rc ){ 264 + printf("%s: optimized run failed: %s\n", 265 + azIn[i], sqlite3_errmsg(dbRun)); 266 + }else{ 267 + sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, dbRun, 0xffff); 268 + if( bTrace ) printf("%s: Non-optimized\n", azIn[i]); 269 + rc = optfuzz_exec(dbRun, zSql, dbOut, "noopt", &nStmt, &nRow, bTrace); 270 + if( rc ){ 271 + printf("%s: non-optimized run failed: %s\n", 272 + azIn[i], sqlite3_errmsg(dbRun)); 273 + exit(1); 274 + } 275 + pCk = prepare_sql(dbOut, 276 + "SELECT (SELECT group_concat(x,char(10)) FROM opt)==" 277 + " (SELECT group_concat(x,char(10)) FROM noopt)"); 278 + rc = sqlite3_step(pCk); 279 + if( rc!=SQLITE_ROW ){ 280 + printf("%s: comparison failed\n", sqlite3_errmsg(dbOut)); 281 + exit(1); 282 + } 283 + if( !sqlite3_column_int(pCk, 0) ){ 284 + printf("%s: opt/no-opt outputs differ\n", azIn[i]); 285 + pCk = prepare_sql(dbOut, 286 + "SELECT group_concat(x,char(10)) FROM opt " 287 + "UNION ALL " 288 + "SELECT group_concat(x,char(10)) FROM noopt"); 289 + sqlite3_step(pCk); 290 + printf("opt:\n%s\n", sqlite3_column_text(pCk,0)); 291 + sqlite3_step(pCk); 292 + printf("noopt:\n%s\n", sqlite3_column_text(pCk,0)); 293 + exit(1); 294 + }else{ 295 + printf("%s: %d stmts %d rows ok\n", azIn[i], nStmt, nRow); 296 + } 297 + sqlite3_finalize(pCk); 298 + } 299 + sqlite3_free(zSql); 300 + } 301 + sqlite3_close(dbRun); 302 + sqlite3_close(dbOut); 303 + free(azIn); 304 + if( sqlite3_memory_used() ){ 305 + printf("Memory leak of %lld bytes\n", sqlite3_memory_used()); 306 + exit(1); 307 + } 308 + return 0; 309 +}
Changes to test/releasetest.tcl.
169 169 -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 170 170 -DSQLITE_ENABLE_RTREE=1 171 171 -DSQLITE_MAX_COMPOUND_SELECT=50 172 172 -DSQLITE_MAX_PAGE_SIZE=32768 173 173 -DSQLITE_OMIT_TRACE=1 174 174 -DSQLITE_TEMP_STORE=3 175 175 -DSQLITE_THREADSAFE=2 176 + -DSQLITE_ENABLE_DESERIALIZE=1 176 177 --enable-json1 --enable-fts5 --enable-session 177 178 } 178 179 "Locking-Style" { 179 180 -O2 180 181 -DSQLITE_ENABLE_LOCKING_STYLE=1 181 182 } 182 183 "Apple" {
Changes to test/shell1.test.
1091 1091 error "failed with error: $res" 1092 1092 } 1093 1093 if {$res ne "CREATE TABLE ${test}(x);"} { 1094 1094 error "failed with mismatch: $res" 1095 1095 } 1096 1096 forcedelete test3.db 1097 1097 } {} 1098 +} 1099 + 1100 +db close 1101 +forcedelete test.db test.db-journal test.db-wal 1102 +sqlite3 db test.db 1103 + 1104 +# The shell tool ".schema" command uses virtual table "pragma_database_list" 1105 +# 1106 +ifcapable vtab { 1107 + 1108 +do_test shell1-7.1.1 { 1109 + db eval { 1110 + CREATE TABLE Z (x TEXT PRIMARY KEY); 1111 + CREATE TABLE _ (x TEXT PRIMARY KEY); 1112 + CREATE TABLE YY (x TEXT PRIMARY KEY); 1113 + CREATE TABLE __ (x TEXT PRIMARY KEY); 1114 + CREATE TABLE WWW (x TEXT PRIMARY KEY); 1115 + CREATE TABLE ___ (x TEXT PRIMARY KEY); 1116 + } 1117 +} {} 1118 +do_test shell1-7.1.2 { 1119 + catchcmd "test.db" ".schema _" 1120 +} {0 {CREATE TABLE Z (x TEXT PRIMARY KEY); 1121 +CREATE TABLE _ (x TEXT PRIMARY KEY);}} 1122 +do_test shell1-7.1.3 { 1123 + catchcmd "test.db" ".schema \\\\_" 1124 +} {0 {CREATE TABLE _ (x TEXT PRIMARY KEY);}} 1125 +do_test shell1-7.1.4 { 1126 + catchcmd "test.db" ".schema __" 1127 +} {0 {CREATE TABLE YY (x TEXT PRIMARY KEY); 1128 +CREATE TABLE __ (x TEXT PRIMARY KEY);}} 1129 +do_test shell1-7.1.5 { 1130 + catchcmd "test.db" ".schema \\\\_\\\\_" 1131 +} {0 {CREATE TABLE __ (x TEXT PRIMARY KEY);}} 1132 +do_test shell1-7.1.6 { 1133 + catchcmd "test.db" ".schema ___" 1134 +} {0 {CREATE TABLE WWW (x TEXT PRIMARY KEY); 1135 +CREATE TABLE ___ (x TEXT PRIMARY KEY);}} 1136 +do_test shell1-7.1.7 { 1137 + catchcmd "test.db" ".schema \\\\_\\\\_\\\\_" 1138 +} {0 {CREATE TABLE ___ (x TEXT PRIMARY KEY);}} 1139 + 1098 1140 } 1099 1141 1100 1142 finish_test
Changes to test/sort5.test.
69 69 } 70 70 } 71 71 72 72 catch { db close } 73 73 forcedelete test.db 74 74 sqlite3 db test.db -vfs tvfs 75 75 execsql { CREATE TABLE t1(x) } 76 +execsql { PRAGMA temp_store = 1 } 76 77 77 78 # Each iteration of the following loop attempts to sort 10001 records 78 79 # each a bit over 100 bytes in size. In total a little more than 1MiB 79 80 # of data. 80 81 # 81 82 foreach {tn pgsz cachesz bTemp} { 82 83 1 4096 1000 0 ................................................................................ 84 85 85 86 3 4096 -1000 1 86 87 4 1024 -1000 1 87 88 88 89 5 4096 -9000 0 89 90 6 1024 -9000 0 90 91 } { 92 + if {$::TEMP_STORE>2} { 93 + set bTemp 0 94 + } 91 95 do_execsql_test 2.$tn.0 " 92 96 PRAGMA page_size = $pgsz; 93 97 VACUUM; 94 98 PRAGMA cache_size = $cachesz; 95 99 " 96 100 97 101 if {[db one {PRAGMA page_size}]!=$pgsz} {
Changes to test/speedtest1.c.
1640 1640 for(i=0; i<n; i++){ 1641 1641 x1 = speedtest1_random()%nRow; 1642 1642 sqlite3_bind_int(g.pStmt, 1, x1); 1643 1643 speedtest1_run(); 1644 1644 } 1645 1645 speedtest1_end_test(); 1646 1646 } 1647 + 1648 +/* 1649 +*/ 1650 +void testset_trigger(void){ 1651 + int jj, ii; 1652 + char zNum[2000]; /* A number name */ 1653 + 1654 + const int NROW = 500*g.szTest; 1655 + const int NROW2 = 100*g.szTest; 1656 + 1657 + speedtest1_exec( 1658 + "BEGIN;" 1659 + "CREATE TABLE t1(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);" 1660 + "CREATE TABLE t2(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);" 1661 + "CREATE TABLE t3(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);" 1662 + "CREATE VIEW v1 AS SELECT rowid, i, t FROM t1;" 1663 + "CREATE VIEW v2 AS SELECT rowid, i, t FROM t2;" 1664 + "CREATE VIEW v3 AS SELECT rowid, i, t FROM t3;" 1665 + ); 1666 + for(jj=1; jj<=3; jj++){ 1667 + speedtest1_prepare("INSERT INTO t%d VALUES(NULL,?1,?2)", jj); 1668 + for(ii=0; ii<NROW; ii++){ 1669 + int x1 = speedtest1_random() % NROW; 1670 + speedtest1_numbername(x1, zNum, sizeof(zNum)); 1671 + sqlite3_bind_int(g.pStmt, 1, x1); 1672 + sqlite3_bind_text(g.pStmt, 2, zNum, -1, SQLITE_STATIC); 1673 + speedtest1_run(); 1674 + } 1675 + } 1676 + speedtest1_exec( 1677 + "CREATE INDEX i1 ON t1(t);" 1678 + "CREATE INDEX i2 ON t2(t);" 1679 + "CREATE INDEX i3 ON t3(t);" 1680 + "COMMIT;" 1681 + ); 1682 + 1683 + speedtest1_begin_test(100, "speed4p-join1"); 1684 + speedtest1_prepare( 1685 + "SELECT * FROM t1, t2, t3 WHERE t1.oid = t2.oid AND t2.oid = t3.oid" 1686 + ); 1687 + speedtest1_run(); 1688 + speedtest1_end_test(); 1689 + 1690 + speedtest1_begin_test(110, "speed4p-join2"); 1691 + speedtest1_prepare( 1692 + "SELECT * FROM t1, t2, t3 WHERE t1.t = t2.t AND t2.t = t3.t" 1693 + ); 1694 + speedtest1_run(); 1695 + speedtest1_end_test(); 1696 + 1697 + speedtest1_begin_test(120, "speed4p-view1"); 1698 + for(jj=1; jj<=3; jj++){ 1699 + speedtest1_prepare("SELECT * FROM v%d WHERE rowid = ?", jj); 1700 + for(ii=0; ii<NROW2; ii+=3){ 1701 + sqlite3_bind_int(g.pStmt, 1, ii*3); 1702 + speedtest1_run(); 1703 + } 1704 + } 1705 + speedtest1_end_test(); 1706 + 1707 + speedtest1_begin_test(130, "speed4p-table1"); 1708 + for(jj=1; jj<=3; jj++){ 1709 + speedtest1_prepare("SELECT * FROM t%d WHERE rowid = ?", jj); 1710 + for(ii=0; ii<NROW2; ii+=3){ 1711 + sqlite3_bind_int(g.pStmt, 1, ii*3); 1712 + speedtest1_run(); 1713 + } 1714 + } 1715 + speedtest1_end_test(); 1716 + 1717 + speedtest1_begin_test(140, "speed4p-table1"); 1718 + for(jj=1; jj<=3; jj++){ 1719 + speedtest1_prepare("SELECT * FROM t%d WHERE rowid = ?", jj); 1720 + for(ii=0; ii<NROW2; ii+=3){ 1721 + sqlite3_bind_int(g.pStmt, 1, ii*3); 1722 + speedtest1_run(); 1723 + } 1724 + } 1725 + speedtest1_end_test(); 1726 + 1727 + speedtest1_begin_test(150, "speed4p-subselect1"); 1728 + speedtest1_prepare("SELECT " 1729 + "(SELECT t FROM t1 WHERE rowid = ?1)," 1730 + "(SELECT t FROM t2 WHERE rowid = ?1)," 1731 + "(SELECT t FROM t3 WHERE rowid = ?1)" 1732 + ); 1733 + for(jj=0; jj<NROW2; jj++){ 1734 + sqlite3_bind_int(g.pStmt, 1, jj*3); 1735 + speedtest1_run(); 1736 + } 1737 + speedtest1_end_test(); 1738 + 1739 + speedtest1_begin_test(160, "speed4p-rowid-update"); 1740 + speedtest1_exec("BEGIN"); 1741 + speedtest1_prepare("UPDATE t1 SET i=i+1 WHERE rowid=?1"); 1742 + for(jj=0; jj<NROW2; jj++){ 1743 + sqlite3_bind_int(g.pStmt, 1, jj); 1744 + speedtest1_run(); 1745 + } 1746 + speedtest1_exec("COMMIT"); 1747 + speedtest1_end_test(); 1748 + 1749 + speedtest1_exec("CREATE TABLE t5(t TEXT PRIMARY KEY, i INTEGER);"); 1750 + speedtest1_begin_test(170, "speed4p-insert-ignore"); 1751 + speedtest1_exec("INSERT OR IGNORE INTO t5 SELECT t, i FROM t1"); 1752 + speedtest1_end_test(); 1753 + 1754 + speedtest1_exec( 1755 + "CREATE TABLE log(op TEXT, r INTEGER, i INTEGER, t TEXT);" 1756 + "CREATE TABLE t4(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);" 1757 + "CREATE TRIGGER t4_trigger1 AFTER INSERT ON t4 BEGIN" 1758 + " INSERT INTO log VALUES('INSERT INTO t4', new.rowid, new.i, new.t);" 1759 + "END;" 1760 + "CREATE TRIGGER t4_trigger2 AFTER UPDATE ON t4 BEGIN" 1761 + " INSERT INTO log VALUES('UPDATE OF t4', new.rowid, new.i, new.t);" 1762 + "END;" 1763 + "CREATE TRIGGER t4_trigger3 AFTER DELETE ON t4 BEGIN" 1764 + " INSERT INTO log VALUES('DELETE OF t4', old.rowid, old.i, old.t);" 1765 + "END;" 1766 + "BEGIN;" 1767 + ); 1768 + 1769 + speedtest1_begin_test(180, "speed4p-trigger1"); 1770 + speedtest1_prepare("INSERT INTO t4 VALUES(NULL, ?1, ?2)"); 1771 + for(jj=0; jj<NROW2; jj++){ 1772 + speedtest1_numbername(jj, zNum, sizeof(zNum)); 1773 + sqlite3_bind_int(g.pStmt, 1, jj); 1774 + sqlite3_bind_text(g.pStmt, 2, zNum, -1, SQLITE_STATIC); 1775 + speedtest1_run(); 1776 + } 1777 + speedtest1_end_test(); 1778 + 1779 + /* 1780 + ** Note: Of the queries, only half actually update a row. This property 1781 + ** was copied over from speed4p.test, where it was probably introduced 1782 + ** inadvertantly. 1783 + */ 1784 + speedtest1_begin_test(190, "speed4p-trigger2"); 1785 + speedtest1_prepare("UPDATE t4 SET i = ?1, t = ?2 WHERE rowid = ?3"); 1786 + for(jj=1; jj<=NROW2*2; jj+=2){ 1787 + speedtest1_numbername(jj*2, zNum, sizeof(zNum)); 1788 + sqlite3_bind_int(g.pStmt, 1, jj*2); 1789 + sqlite3_bind_text(g.pStmt, 2, zNum, -1, SQLITE_STATIC); 1790 + sqlite3_bind_int(g.pStmt, 3, jj); 1791 + speedtest1_run(); 1792 + } 1793 + speedtest1_end_test(); 1794 + 1795 + /* 1796 + ** Note: Same again. 1797 + */ 1798 + speedtest1_begin_test(200, "speed4p-trigger3"); 1799 + speedtest1_prepare("DELETE FROM t4 WHERE rowid = ?1"); 1800 + for(jj=1; jj<=NROW2*2; jj+=2){ 1801 + sqlite3_bind_int(g.pStmt, 1, jj*2); 1802 + speedtest1_run(); 1803 + } 1804 + speedtest1_end_test(); 1805 + speedtest1_exec("COMMIT"); 1806 + 1807 + /* 1808 + ** The following block contains the same tests as the above block that 1809 + ** tests triggers, with one crucial difference: no triggers are defined. 1810 + ** So the difference in speed between these tests and the preceding ones 1811 + ** is the amount of time taken to compile and execute the trigger programs. 1812 + */ 1813 + speedtest1_exec( 1814 + "DROP TABLE t4;" 1815 + "DROP TABLE log;" 1816 + "VACUUM;" 1817 + "CREATE TABLE t4(rowid INTEGER PRIMARY KEY, i INTEGER, t TEXT);" 1818 + "BEGIN;" 1819 + ); 1820 + speedtest1_begin_test(210, "speed4p-notrigger1"); 1821 + speedtest1_prepare("INSERT INTO t4 VALUES(NULL, ?1, ?2)"); 1822 + for(jj=0; jj<NROW2; jj++){ 1823 + speedtest1_numbername(jj, zNum, sizeof(zNum)); 1824 + sqlite3_bind_int(g.pStmt, 1, jj); 1825 + sqlite3_bind_text(g.pStmt, 2, zNum, -1, SQLITE_STATIC); 1826 + speedtest1_run(); 1827 + } 1828 + speedtest1_end_test(); 1829 + speedtest1_begin_test(210, "speed4p-notrigger2"); 1830 + speedtest1_prepare("UPDATE t4 SET i = ?1, t = ?2 WHERE rowid = ?3"); 1831 + for(jj=1; jj<=NROW2*2; jj+=2){ 1832 + speedtest1_numbername(jj*2, zNum, sizeof(zNum)); 1833 + sqlite3_bind_int(g.pStmt, 1, jj*2); 1834 + sqlite3_bind_text(g.pStmt, 2, zNum, -1, SQLITE_STATIC); 1835 + sqlite3_bind_int(g.pStmt, 3, jj); 1836 + speedtest1_run(); 1837 + } 1838 + speedtest1_end_test(); 1839 + speedtest1_begin_test(220, "speed4p-notrigger3"); 1840 + speedtest1_prepare("DELETE FROM t4 WHERE rowid = ?1"); 1841 + for(jj=1; jj<=NROW2*2; jj+=2){ 1842 + sqlite3_bind_int(g.pStmt, 1, jj*2); 1843 + speedtest1_run(); 1844 + } 1845 + speedtest1_end_test(); 1846 + speedtest1_exec("COMMIT"); 1847 +} 1647 1848 1648 1849 /* 1649 1850 ** A testset used for debugging speedtest1 itself. 1650 1851 */ 1651 1852 void testset_debug1(void){ 1652 1853 unsigned i, n; 1653 1854 unsigned x1, x2; ................................................................................ 1941 2142 testset_debug1(); 1942 2143 }else if( strcmp(zTSet,"orm")==0 ){ 1943 2144 testset_orm(); 1944 2145 }else if( strcmp(zTSet,"cte")==0 ){ 1945 2146 testset_cte(); 1946 2147 }else if( strcmp(zTSet,"fp")==0 ){ 1947 2148 testset_fp(); 2149 + }else if( strcmp(zTSet,"trigger")==0 ){ 2150 + testset_trigger(); 1948 2151 }else if( strcmp(zTSet,"rtree")==0 ){ 1949 2152 #ifdef SQLITE_ENABLE_RTREE 1950 2153 testset_rtree(6, 147); 1951 2154 #else 1952 2155 fatal_error("compile with -DSQLITE_ENABLE_RTREE to enable " 1953 2156 "the R-Tree tests\n"); 1954 2157 #endif 1955 2158 }else{ 1956 - fatal_error("unknown testset: \"%s\"\nChoices: main debug1 cte rtree fp\n", 2159 + fatal_error("unknown testset: \"%s\"\n" 2160 + "Choices: cte debug1 fp main orm rtree trigger\n", 1957 2161 zTSet); 1958 2162 } 1959 2163 speedtest1_final(); 1960 2164 1961 2165 if( showStats ){ 1962 2166 sqlite3_exec(g.db, "PRAGMA compile_options", xCompileOptions, 0, 0); 1963 2167 }
Changes to test/subquery2.test.
143 143 144 144 SELECT data, id FROM ( 145 145 SELECT id, data FROM ( 146 146 SELECT * FROM t3 UNION ALL SELECT * FROM t4 147 147 ) ORDER BY data 148 148 ); 149 149 } {a 4 b 3 c 2 d 1} 150 + 151 +#------------------------------------------------------------------------- 152 + 153 +do_execsql_test 4.0 { 154 + CREATE TABLE t6(x); 155 +} 156 + 157 +foreach {tn sql} { 158 + 1 { 159 + SELECT 'abc' FROM ( 160 + SELECT x FROM t6 ORDER BY 1 161 + UNION ALL 162 + SELECT x FROM t6 163 + ) 164 + } 165 + 2 { 166 + SELECT 'abc' FROM ( 167 + SELECT x FROM t6 168 + UNION ALL 169 + SELECT x FROM t6 ORDER BY 1 170 + UNION ALL 171 + SELECT x FROM t6 172 + ) 173 + } 174 + 3 { 175 + SELECT 'abc' FROM ( 176 + SELECT x FROM t6 ORDER BY 1 177 + UNION ALL 178 + SELECT x FROM t6 ORDER BY 1 179 + UNION ALL 180 + SELECT x FROM t6 181 + ) 182 + } 183 + 4 { 184 + SELECT 'abc' FROM ( 185 + SELECT x FROM t6 186 + UNION ALL 187 + SELECT x FROM t6 ORDER BY 1 188 + UNION ALL 189 + SELECT x FROM t6 ORDER BY 1 190 + UNION ALL 191 + SELECT x FROM t6 192 + ) 193 + } 194 +} { 195 + do_catchsql_test 4.$tn $sql [list {*}{ 196 + 1 {ORDER BY clause should come after UNION ALL not before} 197 + }] 198 +} 150 199 151 200 152 201 finish_test
Changes to test/tempdb2.test.
12 12 set testdir [file dirname $argv0] 13 13 source $testdir/tester.tcl 14 14 set testprefix tempdb2 15 15 16 16 db close 17 17 sqlite3 db "" 18 18 19 +set unlocked unlocked 20 +if {$::TEMP_STORE>=2} { set unlocked unknown } 21 + 19 22 proc int2str {i} { string range [string repeat "$i." 450] 0 899 } 20 23 db func int2str int2str 21 24 22 25 #------------------------------------------------------------------------- 23 26 # 24 27 # 1.1: Write a big transaction to the db. One so large that it forces 25 28 # the file to be created and the cache flushed to disk on COMMIT. ................................................................................ 51 54 52 55 CREATE TABLE t2(a INTEGER PRIMARY KEY, b); 53 56 WITH c(x) AS ( VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100 ) 54 57 INSERT INTO t2 SELECT x, int2str(x) FROM c; 55 58 COMMIT; 56 59 57 60 PRAGMA lock_status; 58 -} {main unlocked temp closed} 61 +} [list main $unlocked temp closed] 59 62 60 63 do_execsql_test 1.2 { 61 64 UPDATE t1 SET b=int2str(2); 62 65 SELECT b=int2str(2) FROM t1 63 66 } {1 1 1} 64 67 65 68 do_execsql_test 1.3 {
Changes to test/temptable2.test.
340 340 WITH x(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<500 ) 341 341 INSERT INTO t1 SELECT randomblob(100), randomblob(100) FROM x; 342 342 COMMIT; 343 343 INSERT INTO t2 VALUES(3, 4); 344 344 } 345 345 346 346 ifcapable mmap { 347 - if {[permutation]!="journaltest"} { 347 + if {[permutation]!="journaltest" && $::TEMP_STORE<2} { 348 348 # The journaltest permutation does not support mmap, so this part of 349 349 # the test is omitted. 350 350 do_execsql_test 10.2 { PRAGMA mmap_size = 512000 } 512000 351 351 } 352 352 } 353 353 354 354 do_execsql_test 10.3 { SELECT * FROM t2 } {1 2 3 4} 355 355 do_execsql_test 10.4 { PRAGMA integrity_check } ok 356 356 357 357 finish_test
Changes to test/thread001.test.
137 137 } {1} 138 138 do_test thread001.$tn.7 { 139 139 execsql { PRAGMA integrity_check } 140 140 } {ok} 141 141 } 142 142 143 143 sqlite3_enable_shared_cache $::enable_shared_cache 144 +catch { db close } 144 145 set sqlite_open_file_count 0 145 146 finish_test
Changes to test/trace3.test.
125 125 set ::stmtlist(record) {} 126 126 db trace_v2 trace_v2_record profile 127 127 execsql { 128 128 SELECT a, b FROM t1 ORDER BY a; 129 129 } 130 130 set stmt [lindex [lindex $::stmtlist(record) 0] 0] 131 131 set ns [lindex [lindex $::stmtlist(record) 0] 1] 132 - list $stmt [expr {$ns >= 0 && $ns <= 1000000}]; # less than 0.001 second 132 + list $stmt [expr {$ns >= 0 && $ns <= 9999999}]; # less than 0.010 seconds 133 133 } {/^-?\d+ 1$/} 134 134 do_test trace3-4.4 { 135 135 set ::stmtlist(record) {} 136 136 db trace_v2 trace_v2_record 2 137 137 execsql { 138 138 SELECT a, b FROM t1 ORDER BY a; 139 139 } 140 140 set stmt [lindex [lindex $::stmtlist(record) 0] 0] 141 141 set ns [lindex [lindex $::stmtlist(record) 0] 1] 142 - list $stmt [expr {$ns >= 0 && $ns <= 1000000}]; # less than 0.001 second 142 + list $stmt [expr {$ns >= 0 && $ns <= 9999999}]; # less than 0.010 seconds 143 143 } {/^-?\d+ 1$/} 144 144 145 145 do_test trace3-5.1 { 146 146 set ::stmtlist(record) {} 147 147 db trace_v2 trace_v2_record row 148 148 execsql { 149 149 SELECT a, b FROM t1 ORDER BY a;
Changes to test/without_rowid1.test.
337 337 do_execsql_test 8.1 { 338 338 CREATE TABLE t1(x INTEGER PRIMARY KEY UNIQUE, b) WITHOUT ROWID; 339 339 CREATE INDEX t1x ON t1(x); 340 340 INSERT INTO t1(x,b) VALUES('funny','buffalo'); 341 341 SELECT type, name, '|' FROM sqlite_master; 342 342 } {table t1 | index t1x |} 343 343 344 +# 2018-04-05: OSSFuzz found that the following was accessing an 345 +# unintialized memory cell. Which was not actually causing a 346 +# malfunction, but does cause an assert() to fail. 347 +# 348 +do_execsql_test 9.0 { 349 + CREATE TABLE t2(b, c, PRIMARY KEY(b,c)) WITHOUT ROWID; 350 + CREATE UNIQUE INDEX t2b ON t2(b); 351 + UPDATE t2 SET b=1 WHERE b=''; 352 +} 353 + 354 +do_execsql_test 10.1 { 355 + DELETE FROM t2 WHERE b=1 356 +} 344 357 345 358 346 359 finish_test
Changes to test/zipfile.test.
5 5 # 6 6 # May you do good and not evil. 7 7 # May you find forgiveness for yourself and forgive others. 8 8 # May you share freely, never taking more than you give. 9 9 # 10 10 #*********************************************************************** 11 11 # 12 + 13 +package require Tcl 8.6 12 14 13 15 set testdir [file dirname $argv0] 14 16 source $testdir/tester.tcl 15 17 set testprefix zipfile 16 18 17 19 ifcapable !vtab { 18 20 finish_test; return 19 21 } 20 22 if {[catch {load_static_extension db zipfile} error]} { 21 23 puts "Skipping zipfile tests, hit load error: $error" 22 24 finish_test; return 25 +} 26 +if {[catch {load_static_extension db fileio} error]} { 27 + puts "Skipping zipfile tests, hit load error: $error" 28 + finish_test; return 23 29 } 24 30 25 31 proc readfile {f} { 26 32 set fd [open $f] 27 33 fconfigure $fd -translation binary -encoding binary 28 34 set data [read $fd] 29 35 close $fd 30 36 set data 31 37 } 32 38 33 -if {$::tcl_platform(platform)=="unix" && [catch {exec unzip}]==0} { 34 - set ::UNZIP 1 35 - load_static_extension db fileio 39 +unset -nocomplain ::UNZIP 40 + 41 +if {[catch {exec unzip} msg]==0 && \ 42 + [regexp -line {^UnZip \d+\.\d+ .*? Info-ZIP\.} $msg]} { 43 + set ::UNZIP unzip 44 + proc fix_stat_mode {name mode} { 45 + if {$::tcl_platform(platform)=="windows"} { 46 + # 47 + # NOTE: Set or unset the write bits of the file permissions 48 + # based on the read-only attribute because the Win32 49 + # version of UnZip does this. 50 + # 51 + set writebits 0x12; # 0o22 52 + set result $mode 53 + if {[file attributes $name -readonly]} { 54 + set result [expr {$result | $writebits}] 55 + } else { 56 + set result [expr {$result & ~$writebits}] 57 + } 58 + return $result 59 + } else { 60 + return $mode 61 + } 62 + } 36 63 proc do_unzip {file} { 37 64 forcedelete test_unzip 38 65 file mkdir test_unzip 39 - exec unzip -d test_unzip $file 40 - 41 - set res [db eval { 42 - SELECT replace(name,'test_unzip/',''),mode,mtime,data 66 + exec $::UNZIP -d test_unzip $file 67 + 68 + db func modefix fix_stat_mode 69 + 70 + set res [db eval { 71 + SELECT replace(name,'test_unzip/',''),modefix(name,mode),mtime,data 43 72 FROM fsdir('test_unzip') 44 73 WHERE name!='test_unzip' 45 74 ORDER BY name 46 75 }] 47 76 set res 48 77 } 49 78 } ................................................................................ 104 133 # ( SELECT zipfile(name,mode,mtime,data,method) FROM zipfile($file) ) 105 134 # ); 106 135 # 107 136 # Then tests that unpacking the new archive using [unzip] produces 108 137 # the same results as in (1). 109 138 # 110 139 proc do_unzip_test {tn file} { 111 - if {[info vars ::UNZIP]==""} { return } 112 140 db func sss strip_slash 113 141 114 142 db eval { 115 143 SELECT writefile('test_unzip.zip', 116 144 ( SELECT zipfile(name,mode,mtime,data,method) FROM zipfile($file) ) 117 145 ); 118 146 } ................................................................................ 126 154 uplevel [list do_test $tn.1 [list set {} $r2] $r1] 127 155 uplevel [list do_test $tn.2 [list set {} $r3] $r1] 128 156 } 129 157 proc strip_slash {in} { regsub {/$} $in {} } 130 158 131 159 proc do_zip_tests {tn file} { 132 160 uplevel do_zipfile_blob_test $tn.1 $file 133 - uplevel do_unzip_test $tn.2 $file 161 + if {[info exists ::UNZIP]} { 162 + uplevel do_unzip_test $tn.2 $file 163 + } 134 164 } 135 165 136 166 forcedelete test.zip 137 167 do_execsql_test 1.0 { 138 168 CREATE VIRTUAL TABLE temp.zz USING zipfile('test.zip'); 139 169 PRAGMA table_info(zz); 140 170 } { ................................................................................ 242 272 UPDATE zz SET mtime=4 WHERE name='i.txt'; 243 273 SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); 244 274 } { 245 275 f.txt 33188 1000000000 abcde 0 246 276 h.txt 33188 1000000004 aaaaaaaaaabbbbbbbbbb 8 247 277 i.txt 33188 4 zxcvb 0 248 278 } 279 + 280 +if {$::tcl_platform(platform)=="unix"} { 281 + set modes -rw-r--r-x 282 + set perms 33189 283 +} else { 284 + set modes -rw-r--r--; # no execute bits on Win32 285 + set perms 33188 286 +} 249 287 250 288 do_execsql_test 1.6.3 { 251 - UPDATE zz SET mode='-rw-r--r-x' WHERE name='h.txt'; 289 + UPDATE zz SET mode=$modes WHERE name='h.txt'; 252 290 SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); 253 -} { 291 +} [string map [list %perms% $perms] { 254 292 f.txt 33188 1000000000 abcde 0 255 - h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8 293 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 256 294 i.txt 33188 4 zxcvb 0 257 -} 295 +}] 258 296 do_zip_tests 1.6.3a test.zip 259 297 260 298 do_execsql_test 1.6.4 { 261 299 UPDATE zz SET name = 'blue.txt' WHERE name='f.txt'; 262 300 SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); 263 -} { 301 +} [string map [list %perms% $perms] { 264 302 blue.txt 33188 1000000000 abcde 0 265 - h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8 303 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 266 304 i.txt 33188 4 zxcvb 0 267 -} 305 +}] 268 306 do_zip_tests 1.6.4a test.zip 269 307 270 308 do_execsql_test 1.6.5 { 271 309 UPDATE zz SET data = 'edcba' WHERE name='blue.txt'; 272 310 SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); 273 -} { 311 +} [string map [list %perms% $perms] { 274 312 blue.txt 33188 1000000000 edcba 0 275 - h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8 313 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 276 314 i.txt 33188 4 zxcvb 0 277 -} 315 +}] 278 316 279 317 do_execsql_test 1.6.6 { 280 318 UPDATE zz SET mode=NULL, data = NULL WHERE name='blue.txt'; 281 319 SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); 282 -} { 320 +} [string map [list %perms% $perms] { 283 321 blue.txt/ 16877 1000000000 {} 0 284 - h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8 322 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 285 323 i.txt 33188 4 zxcvb 0 286 -} 324 +}] 287 325 288 326 do_catchsql_test 1.6.7 { 289 327 UPDATE zz SET data=NULL WHERE name='i.txt' 290 328 } {1 {zipfile: mode does not match data}} 291 329 do_execsql_test 1.6.8 { 292 330 SELECT name, mode, mtime, data, method FROM zipfile('test.zip'); 293 -} { 331 +} [string map [list %perms% $perms] { 294 332 blue.txt/ 16877 1000000000 {} 0 295 - h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8 333 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 296 334 i.txt 33188 4 zxcvb 0 297 -} 335 +}] 298 336 299 -do_execsql_test 1.6.8 { 337 +do_execsql_test 1.6.9 { 300 338 UPDATE zz SET data = '' WHERE name='i.txt'; 301 339 SELECT name,mode,mtime,data,method from zipfile('test.zip'); 302 -} { 340 +} [string map [list %perms% $perms] { 303 341 blue.txt/ 16877 1000000000 {} 0 304 - h.txt 33189 1000000004 aaaaaaaaaabbbbbbbbbb 8 342 + h.txt %perms% 1000000004 aaaaaaaaaabbbbbbbbbb 8 305 343 i.txt 33188 4 {} 0 306 -} 344 +}] 307 345 308 -do_execsql_test 1.6.9 { 346 +do_execsql_test 1.6.10 { 309 347 SELECT a.name, a.data 310 348 FROM zz AS a, zz AS b 311 349 WHERE a.name=+b.name AND +a.mode=b.mode 312 350 } { 313 351 blue.txt/ {} 314 352 h.txt aaaaaaaaaabbbbbbbbbb 315 353 i.txt {} 316 354 } 317 355 318 -do_execsql_test 1.6.10 { 356 +do_execsql_test 1.6.11 { 319 357 SELECT name, data FROM zz WHERE name LIKE '%txt' 320 358 } { 321 359 h.txt aaaaaaaaaabbbbbbbbbb 322 360 i.txt {} 323 361 } 324 362 325 363 do_execsql_test 1.7 { ................................................................................ 356 394 } { 357 395 dirname3/ 16877 {} 358 396 dirname2/ 16877 {} 359 397 dirname2/file1.txt 33188 abcdefghijklmnop 360 398 } 361 399 do_zip_tests 2.4a test.zip 362 400 363 -# If on unix, check that the [unzip] utility can unpack our archive. 401 +# Check that the [unzip] utility can unpack our archive. 364 402 # 365 -if {$::tcl_platform(platform)=="unix"} { 403 +if {[info exists ::UNZIP]} { 366 404 do_test 2.5.1 { 367 405 forcedelete dirname 368 406 forcedelete dirname2 369 - set rc [catch { exec unzip test.zip > /dev/null } msg] 407 + if {$::tcl_platform(platform)=="unix"} { 408 + set null /dev/null 409 + } else { 410 + set null NUL 411 + } 412 + set rc [catch { exec $::UNZIP test.zip > $null } msg] 370 413 list $rc $msg 371 414 } {0 {}} 372 415 do_test 2.5.2 { file isdir dirname3 } 1 373 416 do_test 2.5.3 { file isdir dirname2 } 1 374 417 do_test 2.5.4 { file isdir dirname2/file1.txt } 0 375 418 do_test 2.5.5 { 376 419 set fd [open dirname2/file1.txt] ................................................................................ 380 423 } {abcdefghijklmnop} 381 424 } 382 425 383 426 #------------------------------------------------------------------------- 384 427 reset_db 385 428 forcedelete test.zip 386 429 load_static_extension db zipfile 430 +load_static_extension db fileio 387 431 388 432 do_execsql_test 3.0 { 389 433 CREATE VIRTUAL TABLE temp.x1 USING zipfile('test.zip'); 390 434 INSERT INTO x1(name, data) VALUES('dir1/', NULL); 391 435 INSERT INTO x1(name, data) VALUES('file1', '1234'); 392 436 INSERT INTO x1(name, data) VALUES('dir1/file2', '5678'); 393 437 } ................................................................................ 449 493 WITH c(name,data) AS ( 450 494 SELECT 'a.txt', 'abc' UNION ALL 451 495 SELECT NULL, 'def' 452 496 ) 453 497 SELECT zipfile(name,data) FROM c 454 498 } {1 {first argument to zipfile() must be non-NULL}} 455 499 456 -do_catchsql_test 4.7 { 500 +do_catchsql_test 4.8 { 457 501 WITH c(name,data,method) AS ( 458 502 SELECT 'a.txt', 'abc', 0 459 503 UNION SELECT 'b.txt', 'def', 8 460 504 UNION SELECT 'c.txt', 'ghi', 16 461 505 ) 462 506 SELECT zipfile(name,NULL,NULL,data,method) FROM c 463 507 } {1 {illegal method value: 16}} 464 508 465 -do_catchsql_test 4.8 { 509 +do_catchsql_test 4.9 { 466 510 WITH c(name,data) AS ( 467 511 SELECT 'a.txt', 'abc' 468 512 UNION SELECT 'b.txt', 'def' 469 513 UNION SELECT 'c.txt/', 'ghi' 470 514 ) 471 515 SELECT zipfile(name,NULL,NULL,data) FROM c 472 516 } {1 {non-directory name must not end with /}} ................................................................................ 481 525 SELECT name,mtime,data FROM zipfile( 482 526 ( SELECT rt( zipfile(name,NULL,mtime,data,NULL) ) FROM c ) 483 527 ) 484 528 } { 485 529 a.txt 946684800 abc 486 530 } 487 531 488 -if {[info vars ::UNZIP]!=""} { 532 +if {[info exists ::UNZIP]} { 489 533 ifcapable datetime { 490 - load_static_extension db fileio 491 534 forcedelete test1.zip test2.zip 492 535 do_test 6.0 { 493 536 execsql { 494 537 WITH c(name,mtime,data) AS ( 495 538 SELECT 'a.txt', 946684800, 'abc' UNION ALL 496 539 SELECT 'b.txt', 1000000000, 'abc' UNION ALL 497 540 SELECT 'c.txt', 1111111000, 'abc' ................................................................................ 498 541 ) 499 542 SELECT writefile('test1.zip', rt( zipfile(name, NULL, mtime, data) ) ), 500 543 writefile('test2.zip', ( zipfile(name, NULL, mtime, data) ) ) 501 544 FROM c; 502 545 } 503 546 forcedelete test_unzip 504 547 file mkdir test_unzip 505 - exec unzip -d test_unzip test1.zip 548 + exec $::UNZIP -d test_unzip test1.zip 506 549 507 550 db eval { 508 551 SELECT name, strftime('%s', mtime, 'unixepoch', 'localtime') 509 552 FROM fsdir('test_unzip') WHERE name!='test_unzip' 510 553 ORDER BY name 511 554 } 512 555 } [list {*}{ 513 556 test_unzip/a.txt 946684800 514 557 test_unzip/b.txt 1000000000 515 558 test_unzip/c.txt 1111111000 516 559 }] 560 + 561 + # fsdir() issue reported on the mailing list on 2018-03-14 by Jack Thaw. 562 + do_test 6.0b { 563 + db eval { 564 + SELECT sum(name LIKE '%/a.txt') 565 + FROM (VALUES(1),(2),(3)) CROSS JOIN fsdir('test_unzip') 566 + } 567 + } {3} 517 568 518 569 do_execsql_test 6.1 { 519 570 SELECT name, mtime, data FROM zipfile('test1.zip') 520 571 } { 521 572 a.txt 946684800 abc 522 573 b.txt 1000000000 abc 523 574 c.txt 1111111000 abc 524 575 } 525 576 526 577 do_test 6.2 { 527 578 forcedelete test_unzip 528 579 file mkdir test_unzip 529 - exec unzip -d test_unzip test2.zip 580 + exec $::UNZIP -d test_unzip test2.zip 530 581 531 582 db eval { 532 583 SELECT name, mtime 533 584 FROM fsdir('test_unzip') WHERE name!='test_unzip' 534 585 ORDER BY name 535 586 } 536 587 } [list {*}{ ................................................................................ 592 643 db eval { SELECT name, data FROM zz } { 593 644 db eval { DELETE FROM zz WHERE name=$name } 594 645 } 595 646 execsql { SELECT name, data FROM zz } 596 647 } {} 597 648 execsql COMMIT 598 649 650 +catch { forcedelete test_unzip } 651 +catch { file mkdir test_unzip } 599 652 do_execsql_test 8.1.1 { 600 653 CREATE VIRTUAL TABLE nogood USING zipfile('test_unzip'); 601 654 } 602 655 do_catchsql_test 8.1.2 { 603 656 INSERT INTO nogood(name, data) VALUES('abc', 'def'); 604 657 } {1 {zipfile: failed to open file test_unzip for writing}} 605 658 ................................................................................ 640 693 #------------------------------------------------------------------------- 641 694 # INSERT OR REPLACE and INSERT OR IGNORE 642 695 # 643 696 catch {db close} 644 697 forcedelete test.zip test.db 645 698 sqlite3 db :memory: 646 699 load_static_extension db zipfile 700 +load_static_extension db fileio 701 + 647 702 do_execsql_test 10.0 { 648 703 CREATE VIRTUAL TABLE z USING zipfile('test.zip'); 649 704 } {} 650 705 do_catchsql_test 10.1 { 651 706 INSERT INTO z(name,data) VALUES('a0','one'),('a0','two'); 652 707 } {1 {duplicate name: "a0"}} 653 708 do_execsql_test 10.2 { ................................................................................ 662 717 do_execsql_test 10.5 { 663 718 INSERT OR IGNORE INTO z(name,data) VALUES('a0','five'),('a0','six'); 664 719 } {} 665 720 do_execsql_test 10.6 { 666 721 SELECT name, data FROM z; 667 722 } {a0 four} 668 723 724 +do_execsql_test 11.1 { 725 + DELETE FROM z; 726 +} {} 727 +do_execsql_test 11.2 { 728 + SELECT name, data FROM z; 729 +} {} 730 +do_execsql_test 11.3 { 731 + INSERT INTO z (name,data) VALUES ('b0','one'); 732 + SELECT name, data FROM z; 733 +} {b0 one} 734 +do_execsql_test 11.4 { 735 + UPDATE z SET name = 'b1' WHERE name = 'b0'; 736 + SELECT name, data FROM z; 737 +} {b1 one} 738 +do_execsql_test 11.5 { 739 + INSERT INTO z (name,data) VALUES ('b0','one'); 740 + SELECT name, data FROM z ORDER BY name; 741 +} {b0 one b1 one} 742 +do_catchsql_test 11.6 { 743 + UPDATE z SET name = 'b1' WHERE name = 'b0'; 744 +} {1 {duplicate name: "b1"}} 745 +do_execsql_test 11.7 { 746 + UPDATE z SET data = 'two' WHERE name = 'b0'; 747 + SELECT name, data FROM z ORDER BY name; 748 +} {b0 two b1 one} 749 +do_catchsql_test 11.8 { 750 + UPDATE z SET name = 'b1'; 751 +} {1 {duplicate name: "b1"}} 752 +do_catchsql_test 11.9 { 753 + UPDATE z SET name = 'b2'; 754 +} {1 {duplicate name: "b2"}} 755 +do_execsql_test 11.10 { 756 + UPDATE z SET name = name; 757 + SELECT name, data FROM z ORDER BY name; 758 +} {b0 two b2 one} 759 +do_execsql_test 11.11 { 760 + UPDATE z SET name = name || 'suffix'; 761 + SELECT name, data FROM z ORDER BY name; 762 +} {b0suffix two b2suffix one} 669 763 670 764 finish_test
Changes to test/zipfile2.test.
5 5 # 6 6 # May you do good and not evil. 7 7 # May you find forgiveness for yourself and forgive others. 8 8 # May you share freely, never taking more than you give. 9 9 # 10 10 #*********************************************************************** 11 11 # 12 + 13 +package require Tcl 8.6 12 14 13 15 set testdir [file dirname $argv0] 14 16 source $testdir/tester.tcl 15 17 set testprefix zipfile2 16 18 17 19 ifcapable !vtab { 18 20 finish_test; return ................................................................................ 46 48 CREATE VIRTUAL TABLE bbb USING zipfile("testzip"); 47 49 CREATE VIRTUAL TABLE ccc USING zipfile(`testzip`); 48 50 CREATE VIRTUAL TABLE ddd USING zipfile([testzip]); 49 51 CREATE VIRTUAL TABLE eee USING zipfile(testzip); 50 52 CREATE VIRTUAL TABLE fff USING zipfile('test''zip'); 51 53 } 52 54 55 +if {$::tcl_platform(platform)=="windows"} { 56 + set res {1 {cannot open file: testdir}} 57 +} else { 58 + set res {1 {error in fread()}} 59 +} 53 60 do_test 2.0 { 54 61 forcedelete testdir 55 62 file mkdir testdir 56 63 execsql { CREATE VIRTUAL TABLE hhh USING zipfile('testdir') } 57 64 catchsql { SELECT * FROM hhh } 58 -} {1 {error in fread()}} 65 +} $res 59 66 60 67 61 68 set archive { 62 69 504B0304140000080000D4A52BEC09F3B6E0110000001100000005000900612E 63 70 747874555405000140420F00636F6E74656E7473206F6620612E747874504B03 64 71 04140000080000D4A52BECD98916A7110000001100000005000900622E747874 65 72 555405000140420F00636F6E74656E7473206F6620622E747874504B01021E03 ................................................................................ 199 206 set hex [binary encode hex $blob] 200 207 set hex [string map {6e6f7461646972 6e6f746164692f} $hex] 201 208 set blob2 [binary decode hex $hex] 202 209 203 210 execsql { SELECT name, data IS NULL FROM zipfile($blob2) } 204 211 } {notadi/ 1} 205 212 213 +#------------------------------------------------------------------------- 214 +# Test that duplicate entries may not be created using UPDATE 215 +# statements. 216 +# 217 +forcedelete test.zip 218 +do_execsql_test 6.0 { 219 + CREATE VIRTUAL TABLE temp.zip USING zipfile('test.zip'); 220 + INSERT INTO temp.zip (name,data) VALUES ('test1','test'); 221 + INSERT INTO temp.zip (name,data) VALUES ('test2','test'); 222 +} 223 +do_catchsql_test 6.1 { 224 + UPDATE temp.zip SET name='test1' WHERE name='test2' 225 +} {1 {duplicate name: "test1"}} 226 + 227 +forcedelete test.zip 228 +do_catchsql_test 6.2 { 229 + DROP TABLE zip; 230 + CREATE VIRTUAL TABLE temp.zip USING zipfile('test.zip'); 231 + INSERT INTO temp.zip (name,data) VALUES ('test','test'); 232 + UPDATE temp.zip set name=name||'new' where name='test'; 233 + INSERT INTO temp.zip (name,data) VALUES ('test','test'); 234 + UPDATE temp.zip set name=name||'new' where name='test'; 235 +} {1 {duplicate name: "testnew"}} 236 + 237 +forcedelete test.zip 238 +do_execsql_test 6.3 { 239 + INSERT INTO temp.zip (name,data) VALUES ('test1','test'); 240 + INSERT INTO temp.zip (name,data) VALUES ('test2','test'); 241 + UPDATE OR REPLACE zip SET name='test2' WHERE name='test1'; 242 + SELECT name FROM zip; 243 +} {test2} 206 244 207 245 finish_test 208 246
Changes to tool/lemon.c.
3250 3250 /* Generate the "*.out" log file */ 3251 3251 void ReportOutput(struct lemon *lemp) 3252 3252 { 3253 3253 int i; 3254 3254 struct state *stp; 3255 3255 struct config *cfp; 3256 3256 struct action *ap; 3257 + struct rule *rp; 3257 3258 FILE *fp; 3258 3259 3259 3260 fp = file_open(lemp,".out","wb"); 3260 3261 if( fp==0 ) return; 3261 3262 for(i=0; i<lemp->nxstate; i++){ 3262 3263 stp = lemp->sorted[i]; 3263 3264 fprintf(fp,"State %d:\n",stp->statenum); ................................................................................ 3302 3303 } 3303 3304 for(j=0; j<lemp->nterminal; j++){ 3304 3305 if( sp->firstset && SetFind(sp->firstset, j) ){ 3305 3306 fprintf(fp, " %s", lemp->symbols[j]->name); 3306 3307 } 3307 3308 } 3308 3309 } 3310 + if( sp->prec>=0 ) fprintf(fp," (precedence=%d)", sp->prec); 3309 3311 fprintf(fp, "\n"); 3312 + } 3313 + fprintf(fp, "----------------------------------------------------\n"); 3314 + fprintf(fp, "Rules:\n"); 3315 + for(rp=lemp->rule; rp; rp=rp->next){ 3316 + fprintf(fp, "%4d: ", rp->iRule); 3317 + rule_print(fp, rp); 3318 + fprintf(fp,"."); 3319 + if( rp->precsym ){ 3320 + fprintf(fp," [%s precedence=%d]", 3321 + rp->precsym->name, rp->precsym->prec); 3322 + } 3323 + fprintf(fp,"\n"); 3310 3324 } 3311 3325 fclose(fp); 3312 3326 return; 3313 3327 } 3314 3328 3315 3329 /* Search for the file "name" which is in the same directory as 3316 3330 ** the exacutable */
Changes to tool/mksqlite3h.tcl.
68 68 69 69 set declpattern3 \ 70 70 {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3changeset_[_a-zA-Z0-9]+)(\(.*)$} 71 71 72 72 set declpattern4 \ 73 73 {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3changegroup_[_a-zA-Z0-9]+)(\(.*)$} 74 74 75 +set declpattern5 \ 76 + {^ *([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3rebaser_[_a-zA-Z0-9]+)(\(.*)$} 77 + 75 78 # Force the output to use unix line endings, even on Windows. 76 79 fconfigure stdout -translation lf 77 80 78 81 set filelist [subst { 79 82 $TOP/src/sqlite.h.in 80 83 $TOP/ext/rtree/sqlite3rtree.h 81 84 $TOP/ext/session/sqlite3session.h ................................................................................ 117 120 118 121 if {[regexp $varpattern $line] && ![regexp {^ *typedef} $line]} { 119 122 set line "SQLITE_API $line" 120 123 } else { 121 124 if {[regexp $declpattern1 $line all rettype funcname rest] || \ 122 125 [regexp $declpattern2 $line all rettype funcname rest] || \ 123 126 [regexp $declpattern3 $line all rettype funcname rest] || \ 124 - [regexp $declpattern4 $line all rettype funcname rest]} { 127 + [regexp $declpattern4 $line all rettype funcname rest] || \ 128 + [regexp $declpattern5 $line all rettype funcname rest]} { 125 129 set line SQLITE_API 126 130 append line " " [string trim $rettype] 127 131 if {[string index $rettype end] ne "*"} { 128 132 append line " " 129 133 } 130 134 if {$useapicall} { 131 135 if {[lsearch -exact $cdecllist $funcname] >= 0} {