libs: updated to sqlite-amalgamation-3150200

This commit is contained in:
Remy Marquis 2016-12-04 14:25:02 +01:00
parent 0c435cd3ad
commit a0c1c64fa2
4 changed files with 4745 additions and 2879 deletions

View file

@ -2,4 +2,4 @@ Compile ET: L specific SQLite3 for several plattforms & architectures
Download sqlite3 amalgamation sources from https://www.sqlite.org/download.html
- tested with sqlite-amalgamation-3140200
- tested with sqlite-amalgamation-3150200

View file

@ -143,6 +143,7 @@
extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
#endif
/* On Windows, we normally run with output mode of TEXT so that \n characters
@ -626,8 +627,10 @@ struct ShellState {
int normalMode; /* Output mode before ".explain on" */
int writableSchema; /* True if PRAGMA writable_schema=ON */
int showHeader; /* True to show column names in List or Column mode */
int nCheck; /* Number of ".check" commands run */
unsigned shellFlgs; /* Various flags */
char *zDestTable; /* Name of destination table when MODE_Insert */
char zTestcase[30]; /* Name of current test case */
char colSeparator[20]; /* Column separator character for several modes */
char rowSeparator[20]; /* Row separator character for MODE_Ascii */
int colWidth[100]; /* Requested width of each column when in column mode*/
@ -894,6 +897,7 @@ static void interrupt_handler(int NotUsed){
}
#endif
#ifndef SQLITE_OMIT_AUTHORIZATION
/*
** When the ".auth ON" is set, the following authorizer callback is
** invoked. It always returns SQLITE_OK.
@ -926,7 +930,7 @@ static int shellAuth(
az[1] = zA2;
az[2] = zA3;
az[3] = zA4;
raw_printf(p->out, "authorizer: %s", azAction[op]);
utf8_printf(p->out, "authorizer: %s", azAction[op]);
for(i=0; i<4; i++){
raw_printf(p->out, " ");
if( az[i] ){
@ -938,7 +942,8 @@ static int shellAuth(
raw_printf(p->out, "\n");
return SQLITE_OK;
}
#endif
/*
** This is the callback routine that the shell
@ -1442,7 +1447,7 @@ static void displayLinuxIoStats(FILE *out){
for(i=0; i<ArraySize(aTrans); i++){
int n = (int)strlen(aTrans[i].zPattern);
if( strncmp(aTrans[i].zPattern, z, n)==0 ){
raw_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
break;
}
}
@ -2131,11 +2136,14 @@ static int run_schema_dump_query(
** Text of a help message
*/
static char zHelp[] =
#ifndef SQLITE_OMIT_AUTHORIZATION
".auth ON|OFF Show authorizer callbacks\n"
#endif
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
".bail on|off Stop after hitting an error. Default OFF\n"
".binary on|off Turn binary output on or off. Default OFF\n"
".changes on|off Show number of rows changed by SQL\n"
".check GLOB Fail if output since .testcase does not match\n"
".clone NEWDB Clone data into NEWDB from the existing database\n"
".databases List names and files of attached databases\n"
".dbinfo ?DB? Show status information about the database\n"
@ -2173,7 +2181,8 @@ static char zHelp[] =
" tcl TCL list elements\n"
".nullvalue STRING Use STRING in place of NULL values\n"
".once FILENAME Output for the next SQL command only to FILENAME\n"
".open ?FILENAME? Close existing database and reopen FILENAME\n"
".open ?--new? ?FILE? Close existing database and reopen FILE\n"
" The --new starts with an empty file\n"
".output ?FILENAME? Send output to FILENAME or stdout\n"
".print STRING... Print literal STRING\n"
".prompt MAIN CONTINUE Replace the standard prompts\n"
@ -2196,6 +2205,7 @@ static char zHelp[] =
".tables ?TABLE? List names of tables\n"
" If TABLE specified, only list tables matching\n"
" LIKE pattern TABLE.\n"
".testcase NAME Begin redirecting output to 'testcase-out.txt'\n"
".timeout MS Try opening locked tables for MS milliseconds\n"
".timer on|off Turn SQL timer on or off\n"
".trace FILE|off Output each SQL statement as it is run\n"
@ -2232,6 +2242,35 @@ void session_help(ShellState *p){
/* Forward reference */
static int process_input(ShellState *p, FILE *in);
/*
** Read the content of a file into memory obtained from sqlite3_malloc64().
** The caller is responsible for freeing the memory.
**
** NULL is returned if any error is encountered.
*/
static char *readFile(const char *zName){
FILE *in = fopen(zName, "rb");
long nIn;
size_t nRead;
char *pBuf;
if( in==0 ) return 0;
fseek(in, 0, SEEK_END);
nIn = ftell(in);
rewind(in);
pBuf = sqlite3_malloc64( nIn+1 );
if( pBuf==0 ) return 0;
nRead = fread(pBuf, nIn, 1, in);
fclose(in);
if( nRead!=1 ){
sqlite3_free(pBuf);
return 0;
}
pBuf[nIn] = 0;
return pBuf;
}
/*
** Implementation of the "readfile(X)" SQL function. The entire content
** of the file named X is read and returned as a BLOB. NULL is returned
@ -2243,25 +2282,13 @@ static void readfileFunc(
sqlite3_value **argv
){
const char *zName;
FILE *in;
long nIn;
void *pBuf;
UNUSED_PARAMETER(argc);
zName = (const char*)sqlite3_value_text(argv[0]);
if( zName==0 ) return;
in = fopen(zName, "rb");
if( in==0 ) return;
fseek(in, 0, SEEK_END);
nIn = ftell(in);
rewind(in);
pBuf = sqlite3_malloc64( nIn );
if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
}else{
sqlite3_free(pBuf);
}
fclose(in);
pBuf = readFile(zName);
if( pBuf ) sqlite3_result_blob(context, pBuf, -1, sqlite3_free);
}
/*
@ -3063,6 +3090,104 @@ static int shellNomemError(void){
return 1;
}
/*
** Compare the pattern in zGlob[] against the text in z[]. Return TRUE
** if they match and FALSE (0) if they do not match.
**
** Globbing rules:
**
** '*' Matches any sequence of zero or more characters.
**
** '?' Matches exactly one character.
**
** [...] Matches one character from the enclosed list of
** characters.
**
** [^...] Matches one character not in the enclosed list.
**
** '#' Matches any sequence of one or more digits with an
** optional + or - sign in front
**
** ' ' Any span of whitespace matches any other span of
** whitespace.
**
** Extra whitespace at the end of z[] is ignored.
*/
static int testcase_glob(const char *zGlob, const char *z){
int c, c2;
int invert;
int seen;
while( (c = (*(zGlob++)))!=0 ){
if( IsSpace(c) ){
if( !IsSpace(*z) ) return 0;
while( IsSpace(*zGlob) ) zGlob++;
while( IsSpace(*z) ) z++;
}else if( c=='*' ){
while( (c=(*(zGlob++))) == '*' || c=='?' ){
if( c=='?' && (*(z++))==0 ) return 0;
}
if( c==0 ){
return 1;
}else if( c=='[' ){
while( *z && testcase_glob(zGlob-1,z)==0 ){
z++;
}
return (*z)!=0;
}
while( (c2 = (*(z++)))!=0 ){
while( c2!=c ){
c2 = *(z++);
if( c2==0 ) return 0;
}
if( testcase_glob(zGlob,z) ) return 1;
}
return 0;
}else if( c=='?' ){
if( (*(z++))==0 ) return 0;
}else if( c=='[' ){
int prior_c = 0;
seen = 0;
invert = 0;
c = *(z++);
if( c==0 ) return 0;
c2 = *(zGlob++);
if( c2=='^' ){
invert = 1;
c2 = *(zGlob++);
}
if( c2==']' ){
if( c==']' ) seen = 1;
c2 = *(zGlob++);
}
while( c2 && c2!=']' ){
if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){
c2 = *(zGlob++);
if( c>=prior_c && c<=c2 ) seen = 1;
prior_c = 0;
}else{
if( c==c2 ){
seen = 1;
}
prior_c = c2;
}
c2 = *(zGlob++);
}
if( c2==0 || (seen ^ invert)==0 ) return 0;
}else if( c=='#' ){
if( (z[0]=='-' || z[0]=='+') && IsDigit(z[1]) ) z++;
if( !IsDigit(z[0]) ) return 0;
z++;
while( IsDigit(z[0]) ){ z++; }
}else{
if( c!=(*(z++)) ) return 0;
}
}
while( IsSpace(*z) ){ z++; }
return *z==0;
}
/*
** Compare the string as a command-line option with either one or two
** initial "-" characters.
@ -3074,6 +3199,21 @@ static int optionMatch(const char *zStr, const char *zOpt){
return strcmp(zStr, zOpt)==0;
}
/*
** Delete a file.
*/
int shellDeleteFile(const char *zFilename){
int rc;
#ifdef _WIN32
wchar_t *z = sqlite3_win32_utf8_to_unicode(zFilename);
rc = _wunlink(z);
sqlite3_free(z);
#else
rc = unlink(zFilename);
#endif
return rc;
}
/*
** If an input line begins with "." then invoke this routine to
** process that line.
@ -3117,6 +3257,7 @@ static int do_meta_command(char *zLine, ShellState *p){
n = strlen30(azArg[0]);
c = azArg[0][0];
#ifndef SQLITE_OMIT_AUTHORIZATION
if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
if( nArg!=2 ){
raw_printf(stderr, "Usage: .auth ON|OFF\n");
@ -3130,6 +3271,7 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_set_authorizer(p->db, 0, 0);
}
}else
#endif
if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
|| (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
@ -3225,6 +3367,31 @@ static int do_meta_command(char *zLine, ShellState *p){
}
}else
/* Cancel output redirection, if it is currently set (by .testcase)
** Then read the content of the testcase-out.txt file and compare against
** azArg[1]. If there are differences, report an error and exit.
*/
if( c=='c' && n>=3 && strncmp(azArg[0], "check", n)==0 ){
char *zRes = 0;
output_reset(p);
if( nArg!=2 ){
raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
rc = 2;
}else if( (zRes = readFile("testcase-out.txt"))==0 ){
raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
rc = 2;
}else if( testcase_glob(azArg[1],zRes)==0 ){
utf8_printf(stderr,
"testcase-%s FAILED\n Expected: [%s]\n Got: [%s]\n",
p->zTestcase, azArg[1], zRes);
rc = 2;
}else{
utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
p->nCheck++;
}
sqlite3_free(zRes);
}else
if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
if( nArg==2 ){
tryToClone(p, azArg[1]);
@ -3833,22 +4000,43 @@ static int do_meta_command(char *zLine, ShellState *p){
}else
if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
sqlite3 *savedDb = p->db;
const char *zSavedFilename = p->zDbFilename;
char *zNewFilename = 0;
char *zNewFilename; /* Name of the database file to open */
int iName = 1; /* Index in azArg[] of the filename */
int newFlag = 0; /* True to delete file before opening */
/* Close the existing database */
session_close_all(p);
sqlite3_close(p->db);
p->db = 0;
if( nArg>=2 ) zNewFilename = sqlite3_mprintf("%s", azArg[1]);
p->zDbFilename = zNewFilename;
open_db(p, 1);
if( p->db!=0 ){
session_close_all(p);
sqlite3_close(savedDb);
sqlite3_free(p->zFreeOnClose);
p->zFreeOnClose = zNewFilename;
}else{
sqlite3_free(zNewFilename);
p->db = savedDb;
p->zDbFilename = zSavedFilename;
sqlite3_free(p->zFreeOnClose);
p->zFreeOnClose = 0;
/* Check for command-line arguments */
for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
const char *z = azArg[iName];
if( optionMatch(z,"new") ){
newFlag = 1;
}else if( z[0]=='-' ){
utf8_printf(stderr, "unknown option: %s\n", z);
rc = 1;
goto meta_command_exit;
}
}
/* If a filename is specified, try to open it first */
zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
if( zNewFilename ){
if( newFlag ) shellDeleteFile(zNewFilename);
p->zDbFilename = zNewFilename;
open_db(p, 1);
if( p->db==0 ){
utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
sqlite3_free(zNewFilename);
}else{
p->zFreeOnClose = zNewFilename;
}
}
if( p->db==0 ){
/* As a fall-back open a TEMP database */
p->zDbFilename = 0;
open_db(p, 0);
}
}else
@ -4378,6 +4566,8 @@ static int do_meta_command(char *zLine, ShellState *p){
raw_printf(p->out, "%d ", p->colWidth[i]);
}
raw_printf(p->out, "\n");
utf8_printf(p->out, "%12.12s: %s\n", "filename",
p->zDbFilename ? p->zDbFilename : "");
}else
if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
@ -4495,6 +4685,20 @@ static int do_meta_command(char *zLine, ShellState *p){
sqlite3_free(azResult);
}else
/* Begin redirecting output to the file "testcase-out.txt" */
if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
output_reset(p);
p->out = output_file_open("testcase-out.txt");
if( p->out==0 ){
utf8_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
}
if( nArg>=2 ){
sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
}else{
sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
}
}else
if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
static const struct {
const char *zCtrlName; /* Name of a test-control option */
@ -5005,8 +5209,13 @@ static int process_input(ShellState *p, FILE *in){
** Return a pathname which is the user's home directory. A
** 0 return indicates an error of some kind.
*/
static char *find_home_dir(void){
static char *find_home_dir(int clearFlag){
static char *home_dir = NULL;
if( clearFlag ){
free(home_dir);
home_dir = 0;
return 0;
}
if( home_dir ) return home_dir;
#if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) \
@ -5081,7 +5290,7 @@ static void process_sqliterc(
FILE *in = NULL;
if (sqliterc == NULL) {
home_dir = find_home_dir();
home_dir = find_home_dir(0);
if( home_dir==0 ){
raw_printf(stderr, "-- warning: cannot find home directory;"
" cannot read ~/.sqliterc\n");
@ -5569,7 +5778,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
printf(".\nUse \".open FILENAME\" to reopen on a "
"persistent database.\n");
}
zHome = find_home_dir();
zHome = find_home_dir(0);
if( zHome ){
nHistory = strlen30(zHome) + 20;
if( (zHistory = malloc(nHistory))!=0 ){
@ -5593,6 +5802,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
sqlite3_close(data.db);
}
sqlite3_free(data.zFreeOnClose);
find_home_dir(1);
#if !SQLITE_SHELL_IS_UTF8
for(i=0; i<argc; i++) sqlite3_free(argv[i]);
sqlite3_free(argv);

File diff suppressed because it is too large Load diff

View file

@ -108,7 +108,8 @@ extern "C" {
** be held constant and Z will be incremented or else Y will be incremented
** and Z will be reset to zero.
**
** Since version 3.6.18, SQLite source code has been stored in the
** Since [version 3.6.18] ([dateof:3.6.18]),
** SQLite source code has been stored in the
** <a href="http://www.fossil-scm.org/">Fossil configuration management
** system</a>. ^The SQLITE_SOURCE_ID macro evaluates to
** a string which identifies a particular check-in of SQLite
@ -120,9 +121,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.14.2"
#define SQLITE_VERSION_NUMBER 3014002
#define SQLITE_SOURCE_ID "2016-09-12 18:50:49 29dbef4b8585f753861a36d6dd102ca634197bd6"
#define SQLITE_VERSION "3.15.2"
#define SQLITE_VERSION_NUMBER 3015002
#define SQLITE_SOURCE_ID "2016-11-28 19:13:37 bbd85d235f7037c6a033a9690534391ffeacecc8"
/*
** CAPI3REF: Run-Time Library Version Numbers
@ -452,7 +453,8 @@ SQLITE_API int sqlite3_exec(
** [result codes]. However, experience has shown that many of
** these result codes are too coarse-grained. They do not provide as
** much information about problems as programmers might like. In an effort to
** address this, newer versions of SQLite (version 3.3.8 and later) include
** address this, newer versions of SQLite (version 3.3.8 [dateof:3.3.8]
** and later) include
** support for additional result codes that provide more detailed information
** about errors. These [extended result codes] are enabled or disabled
** on a per database connection basis using the
@ -976,6 +978,12 @@ struct sqlite3_io_methods {
** on whether or not the file has been renamed, moved, or deleted since it
** was first opened.
**
** <li>[[SQLITE_FCNTL_WIN32_GET_HANDLE]]
** The [SQLITE_FCNTL_WIN32_GET_HANDLE] opcode can be used to obtain the
** underlying native file handle associated with a file handle. This file
** control interprets its argument as a pointer to a native file handle and
** writes the resulting value there.
**
** <li>[[SQLITE_FCNTL_WIN32_SET_HANDLE]]
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
** opcode causes the xFileControl method to swap the file handle with the one
@ -1026,6 +1034,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_RBU 26
#define SQLITE_FCNTL_VFS_POINTER 27
#define SQLITE_FCNTL_JOURNAL_POINTER 28
#define SQLITE_FCNTL_WIN32_GET_HANDLE 29
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@ -1969,8 +1978,18 @@ struct sqlite3_mem_methods {
** be a NULL pointer, in which case the new setting is not reported back.
** </dd>
**
** <dt>SQLITE_DBCONFIG_MAINDBNAME</dt>
** <dd> ^This option is used to change the name of the "main" database
** schema. ^The sole argument is a pointer to a constant UTF8 string
** which will become the new schema name in place of "main". ^SQLite
** does not make a copy of the new main schema name string, so the application
** must ensure that the argument passed into this DBCONFIG option is unchanged
** until after the database connection closes.
** </dd>
**
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */
@ -4041,7 +4060,8 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
** other than [SQLITE_ROW] before any subsequent invocation of
** sqlite3_step(). Failure to reset the prepared statement using
** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from
** sqlite3_step(). But after version 3.6.23.1, sqlite3_step() began
** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1],
** sqlite3_step() began
** calling [sqlite3_reset()] automatically in this circumstance rather
** than returning [SQLITE_MISUSE]. This is not considered a compatibility
** break because any application that ever receives an SQLITE_MISUSE error
@ -5404,7 +5424,8 @@ SQLITE_API void *sqlite3_update_hook(
** and disabled if the argument is false.)^
**
** ^Cache sharing is enabled and disabled for an entire process.
** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]).
** In prior versions of SQLite,
** sharing was enabled or disabled for each thread separately.
**
** ^(The cache sharing mode set by this interface effects all subsequent
@ -5498,7 +5519,8 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
** from the heap.
** </ul>)^
**
** Beginning with SQLite version 3.7.3, the soft heap limit is enforced
** Beginning with SQLite [version 3.7.3] ([dateof:3.7.3]),
** the soft heap limit is enforced
** regardless of whether or not the [SQLITE_ENABLE_MEMORY_MANAGEMENT]
** compile-time option is invoked. With [SQLITE_ENABLE_MEMORY_MANAGEMENT],
** the soft heap limit is enforced on every memory allocation. Without
@ -5892,13 +5914,15 @@ struct sqlite3_module {
** the xUpdate method are automatically rolled back by SQLite.
**
** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
** structure for SQLite version 3.8.2. If a virtual table extension is
** structure for SQLite [version 3.8.2] ([dateof:3.8.2]).
** If a virtual table extension is
** used with an SQLite version earlier than 3.8.2, the results of attempting
** to read or write the estimatedRows field are undefined (but are likely
** to included crashing the application). The estimatedRows field should
** therefore only be used if [sqlite3_libversion_number()] returns a
** value greater than or equal to 3008002. Similarly, the idxFlags field
** was added for version 3.9.0. It may therefore only be used if
** was added for [version 3.9.0] ([dateof:3.9.0]).
** It may therefore only be used if
** sqlite3_libversion_number() returns a value greater than or equal to
** 3009000.
*/
@ -6596,7 +6620,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */
#define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */
#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */
#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_random() */
#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */
#define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */
#define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */
#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */
@ -6700,6 +6724,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20
#define SQLITE_TESTCTRL_VDBE_COVERAGE 21
#define SQLITE_TESTCTRL_BYTEORDER 22
@ -8639,7 +8664,7 @@ int sqlite3session_attach(
** CAPI3REF: Set a table filter on a Session Object.
**
** The second argument (xFilter) is the "filter callback". For changes to rows
** in tables that are not attached to the Session oject, the filter is called
** in tables that are not attached to the Session object, the filter is called
** to determine whether changes to the table's rows should be tracked or not.
** If xFilter returns 0, changes is not tracked. Note that once a table is
** attached, xFilter will not be called again.
@ -8905,7 +8930,7 @@ int sqlite3session_isempty(sqlite3_session *pSession);
** [sqlite3changeset_invert()] functions, all changes within the changeset
** that apply to a single table are grouped together. This means that when
** an application iterates through a changeset using an iterator created by
** this function, all changes that relate to a single table are visted
** this function, all changes that relate to a single table are visited
** consecutively. There is no chance that the iterator will visit a change
** the applies to table X, then one for table Y, and then later on visit
** another change for table X.
@ -8992,7 +9017,7 @@ int sqlite3changeset_op(
** 0x01 if the corresponding column is part of the tables primary key, or
** 0x00 if it is not.
**
** If argumet pnCol is not NULL, then *pnCol is set to the number of columns
** If argument pnCol is not NULL, then *pnCol is set to the number of columns
** in the table.
**
** If this function is called when the iterator does not point to a valid
@ -9209,12 +9234,12 @@ int sqlite3changeset_concat(
/*
** Changegroup handle.
** CAPI3REF: Changegroup Handle
*/
typedef struct sqlite3_changegroup sqlite3_changegroup;
/*
** CAPI3REF: Combine two or more changesets into a single changeset.
** CAPI3REF: Create A New Changegroup Object
**
** An sqlite3_changegroup object is used to combine two or more changesets
** (or patchsets) into a single changeset (or patchset). A single changegroup
@ -9251,6 +9276,8 @@ typedef struct sqlite3_changegroup sqlite3_changegroup;
int sqlite3changegroup_new(sqlite3_changegroup **pp);
/*
** CAPI3REF: Add A Changeset To A Changegroup
**
** Add all changes within the changeset (or patchset) in buffer pData (size
** nData bytes) to the changegroup.
**
@ -9265,7 +9292,7 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
** apply to the same row as a change already present in the changegroup if
** the two rows have the same primary key.
**
** Changes to rows that that do not already appear in the changegroup are
** Changes to rows that do not already appear in the changegroup are
** simply copied into it. Or, if both the new changeset and the changegroup
** contain changes that apply to a single row, the final contents of the
** changegroup depends on the type of each change, as follows:
@ -9326,6 +9353,8 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
/*
** CAPI3REF: Obtain A Composite Changeset From A Changegroup
**
** Obtain a buffer containing a changeset (or patchset) representing the
** current contents of the changegroup. If the inputs to the changegroup
** were themselves changesets, the output is a changeset. Or, if the
@ -9354,7 +9383,7 @@ int sqlite3changegroup_output(
);
/*
** Delete a changegroup object.
** CAPI3REF: Delete A Changegroup Object
*/
void sqlite3changegroup_delete(sqlite3_changegroup*);