Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Update the latest SQLite to the latest 3.37.0 beta, to test SQLite. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
51bb976fb971819e7def4e75f9841b1c |
| User & Date: | drh 2021-11-03 19:10:56.714 |
Context
|
2021-11-04
| ||
| 00:59 | Update the built-in SQLite with the fix for the broken shadow table protections. check-in: 00650cf020 user: drh tags: trunk | |
|
2021-11-03
| ||
| 19:10 | Update the latest SQLite to the latest 3.37.0 beta, to test SQLite. check-in: 51bb976fb9 user: drh tags: trunk | |
|
2021-11-02
| ||
| 15:52 | Work around a warning in older versions of OpenSSL (e.g. 1.0.2g) where ASN1_time_check() is declared with a non-const ASN1_TIME* parameter. check-in: af8109c00d user: danield tags: trunk | |
Changes
Changes to src/shell.c.
| ︙ | ︙ | |||
13660 13661 13662 13663 13664 13665 13666 |
sqlite3_errmsg(p->db));
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
}
return rc;
}
/*
| | | > > < < | > | < < | 13660 13661 13662 13663 13664 13665 13666 13667 13668 13669 13670 13671 13672 13673 13674 13675 13676 13677 13678 13679 13680 13681 13682 13683 |
sqlite3_errmsg(p->db));
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
}
return rc;
}
/*
** Allocate space and save off string indicating current error.
*/
static char *save_err_msg(
sqlite3 *db, /* Database to query */
const char *zWhen, /* Qualifier (format) wrapper */
int rc /* Error code returned from API */
){
if( zWhen==0 )
zWhen = "%s (%d)";
return sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc);
}
#ifdef __linux__
/*
** Attempt to display I/O stats on Linux using /proc/PID/io
*/
static void displayLinuxIoStats(FILE *out){
|
| ︙ | ︙ | |||
14592 14593 14594 14595 14596 14597 14598 |
#endif
while( zSql[0] && (SQLITE_OK == rc) ){
static const char *zStmtSql;
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
if( SQLITE_OK != rc ){
if( pzErrMsg ){
| | | 14591 14592 14593 14594 14595 14596 14597 14598 14599 14600 14601 14602 14603 14604 14605 |
#endif
while( zSql[0] && (SQLITE_OK == rc) ){
static const char *zStmtSql;
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
if( SQLITE_OK != rc ){
if( pzErrMsg ){
*pzErrMsg = save_err_msg(db, "in prepare, %s (%d)", rc);
}
}else{
if( !pStmt ){
/* this happens for a comment or white-space */
zSql = zLeftover;
while( IsSpace(zSql[0]) ) zSql++;
continue;
|
| ︙ | ︙ | |||
14706 14707 14708 14709 14710 14711 14712 |
** next statement to execute. */
rc2 = sqlite3_finalize(pStmt);
if( rc!=SQLITE_NOMEM ) rc = rc2;
if( rc==SQLITE_OK ){
zSql = zLeftover;
while( IsSpace(zSql[0]) ) zSql++;
}else if( pzErrMsg ){
| | | 14705 14706 14707 14708 14709 14710 14711 14712 14713 14714 14715 14716 14717 14718 14719 |
** next statement to execute. */
rc2 = sqlite3_finalize(pStmt);
if( rc!=SQLITE_NOMEM ) rc = rc2;
if( rc==SQLITE_OK ){
zSql = zLeftover;
while( IsSpace(zSql[0]) ) zSql++;
}else if( pzErrMsg ){
*pzErrMsg = save_err_msg(db, "stepping, %s (%d)", rc);
}
/* clear saved stmt handle */
if( pArg ){
pArg->pStmt = NULL;
}
}
|
| ︙ | ︙ | |||
15020 15021 15022 15023 15024 15025 15026 15027 15028 15029 15030 15031 15032 15033 15034 15035 15036 15037 15038 15039 15040 |
static const char *(azHelp[]) = {
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
".archive ... Manage SQL archives",
" Each command must have exactly one of the following options:",
" -c, --create Create a new archive",
" -u, --update Add or update files with changed mtime",
" -i, --insert Like -u but always add even if unchanged",
" -t, --list List contents of archive",
" -x, --extract Extract files from archive",
" Optional arguments:",
" -v, --verbose Print each filename as it is processed",
" -f FILE, --file FILE Use archive FILE (default is current db)",
" -a FILE, --append FILE Open FILE using the apndvfs VFS",
" -C DIR, --directory DIR Read/extract files from directory DIR",
" -n, --dryrun Show the SQL that would have occurred",
" Examples:",
" .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
" .ar -tf ARCHIVE # List members of ARCHIVE",
" .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
" See also:",
" http://sqlite.org/cli.html#sqlite_archive_support",
| > > | 15019 15020 15021 15022 15023 15024 15025 15026 15027 15028 15029 15030 15031 15032 15033 15034 15035 15036 15037 15038 15039 15040 15041 |
static const char *(azHelp[]) = {
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
".archive ... Manage SQL archives",
" Each command must have exactly one of the following options:",
" -c, --create Create a new archive",
" -u, --update Add or update files with changed mtime",
" -i, --insert Like -u but always add even if unchanged",
" -r, --remove Remove files from archive",
" -t, --list List contents of archive",
" -x, --extract Extract files from archive",
" Optional arguments:",
" -v, --verbose Print each filename as it is processed",
" -f FILE, --file FILE Use archive FILE (default is current db)",
" -a FILE, --append FILE Open FILE using the apndvfs VFS",
" -C DIR, --directory DIR Read/extract files from directory DIR",
" -g, --glob Use glob matching for names in archive",
" -n, --dryrun Show the SQL that would have occurred",
" Examples:",
" .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
" .ar -tf ARCHIVE # List members of ARCHIVE",
" .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
" See also:",
" http://sqlite.org/cli.html#sqlite_archive_support",
|
| ︙ | ︙ | |||
17187 17188 17189 17190 17191 17192 17193 17194 17195 17196 17197 17198 17199 17200 |
typedef struct ArCommand ArCommand;
struct ArCommand {
u8 eCmd; /* An AR_CMD_* value */
u8 bVerbose; /* True if --verbose */
u8 bZip; /* True if the archive is a ZIP */
u8 bDryRun; /* True if --dry-run */
u8 bAppend; /* True if --append */
u8 fromCmdLine; /* Run from -A instead of .archive */
int nArg; /* Number of command arguments */
char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
const char *zFile; /* --file argument, or NULL */
const char *zDir; /* --directory argument, or NULL */
char **azArg; /* Array of command arguments */
ShellState *p; /* Shell state */
| > | 17188 17189 17190 17191 17192 17193 17194 17195 17196 17197 17198 17199 17200 17201 17202 |
typedef struct ArCommand ArCommand;
struct ArCommand {
u8 eCmd; /* An AR_CMD_* value */
u8 bVerbose; /* True if --verbose */
u8 bZip; /* True if the archive is a ZIP */
u8 bDryRun; /* True if --dry-run */
u8 bAppend; /* True if --append */
u8 bGlob; /* True if --glob */
u8 fromCmdLine; /* Run from -A instead of .archive */
int nArg; /* Number of command arguments */
char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
const char *zFile; /* --file argument, or NULL */
const char *zDir; /* --directory argument, or NULL */
char **azArg; /* Array of command arguments */
ShellState *p; /* Shell state */
|
| ︙ | ︙ | |||
17234 17235 17236 17237 17238 17239 17240 17241 17242 17243 17244 | */ #define AR_CMD_CREATE 1 #define AR_CMD_UPDATE 2 #define AR_CMD_INSERT 3 #define AR_CMD_EXTRACT 4 #define AR_CMD_LIST 5 #define AR_CMD_HELP 6 /* ** Other (non-command) switches. */ | > | | | | | > > > > > | 17236 17237 17238 17239 17240 17241 17242 17243 17244 17245 17246 17247 17248 17249 17250 17251 17252 17253 17254 17255 17256 17257 17258 17259 17260 17261 17262 17263 17264 17265 17266 17267 17268 17269 17270 17271 17272 17273 17274 17275 17276 17277 17278 17279 17280 17281 |
*/
#define AR_CMD_CREATE 1
#define AR_CMD_UPDATE 2
#define AR_CMD_INSERT 3
#define AR_CMD_EXTRACT 4
#define AR_CMD_LIST 5
#define AR_CMD_HELP 6
#define AR_CMD_REMOVE 7
/*
** Other (non-command) switches.
*/
#define AR_SWITCH_VERBOSE 8
#define AR_SWITCH_FILE 9
#define AR_SWITCH_DIRECTORY 10
#define AR_SWITCH_APPEND 11
#define AR_SWITCH_DRYRUN 12
#define AR_SWITCH_GLOB 13
static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
switch( eSwitch ){
case AR_CMD_CREATE:
case AR_CMD_EXTRACT:
case AR_CMD_LIST:
case AR_CMD_REMOVE:
case AR_CMD_UPDATE:
case AR_CMD_INSERT:
case AR_CMD_HELP:
if( pAr->eCmd ){
return arErrorMsg(pAr, "multiple command options");
}
pAr->eCmd = eSwitch;
break;
case AR_SWITCH_DRYRUN:
pAr->bDryRun = 1;
break;
case AR_SWITCH_GLOB:
pAr->bGlob = 1;
break;
case AR_SWITCH_VERBOSE:
pAr->bVerbose = 1;
break;
case AR_SWITCH_APPEND:
pAr->bAppend = 1;
/* Fall thru into --file */
|
| ︙ | ︙ | |||
17299 17300 17301 17302 17303 17304 17305 17306 17307 17308 17309 17310 17311 17312 17313 17314 17315 17316 17317 17318 17319 |
u8 eSwitch;
u8 bArg;
} aSwitch[] = {
{ "create", 'c', AR_CMD_CREATE, 0 },
{ "extract", 'x', AR_CMD_EXTRACT, 0 },
{ "insert", 'i', AR_CMD_INSERT, 0 },
{ "list", 't', AR_CMD_LIST, 0 },
{ "update", 'u', AR_CMD_UPDATE, 0 },
{ "help", 'h', AR_CMD_HELP, 0 },
{ "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
{ "file", 'f', AR_SWITCH_FILE, 1 },
{ "append", 'a', AR_SWITCH_APPEND, 1 },
{ "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
{ "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
};
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
struct ArSwitch *pEnd = &aSwitch[nSwitch];
if( nArg<=1 ){
utf8_printf(stderr, "Wrong number of arguments. Usage:\n");
return arUsage(stderr);
| > > | 17307 17308 17309 17310 17311 17312 17313 17314 17315 17316 17317 17318 17319 17320 17321 17322 17323 17324 17325 17326 17327 17328 17329 |
u8 eSwitch;
u8 bArg;
} aSwitch[] = {
{ "create", 'c', AR_CMD_CREATE, 0 },
{ "extract", 'x', AR_CMD_EXTRACT, 0 },
{ "insert", 'i', AR_CMD_INSERT, 0 },
{ "list", 't', AR_CMD_LIST, 0 },
{ "remove", 'r', AR_CMD_REMOVE, 0 },
{ "update", 'u', AR_CMD_UPDATE, 0 },
{ "help", 'h', AR_CMD_HELP, 0 },
{ "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
{ "file", 'f', AR_SWITCH_FILE, 1 },
{ "append", 'a', AR_SWITCH_APPEND, 1 },
{ "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
{ "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
{ "glob", 'g', AR_SWITCH_GLOB, 0 },
};
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
struct ArSwitch *pEnd = &aSwitch[nSwitch];
if( nArg<=1 ){
utf8_printf(stderr, "Wrong number of arguments. Usage:\n");
return arUsage(stderr);
|
| ︙ | ︙ | |||
17422 17423 17424 17425 17426 17427 17428 | } return SQLITE_OK; } /* ** This function assumes that all arguments within the ArCommand.azArg[] | | | | | | > > > > > | < < < | 17432 17433 17434 17435 17436 17437 17438 17439 17440 17441 17442 17443 17444 17445 17446 17447 17448 17449 17450 17451 17452 17453 17454 17455 17456 17457 17458 17459 17460 17461 17462 17463 17464 17465 17466 17467 |
}
return SQLITE_OK;
}
/*
** This function assumes that all arguments within the ArCommand.azArg[]
** array refer to archive members, as for the --extract, --list or --remove
** commands. It checks that each of them are "present". If any specified
** file is not present in the archive, an error is printed to stderr and an
** error code returned. Otherwise, if all specified arguments are present
** in the archive, SQLITE_OK is returned. Here, "present" means either an
** exact equality when pAr->bGlob is false or a "name GLOB pattern" match
** when pAr->bGlob is true.
**
** This function strips any trailing '/' characters from each argument.
** This is consistent with the way the [tar] command seems to work on
** Linux.
*/
static int arCheckEntries(ArCommand *pAr){
int rc = SQLITE_OK;
if( pAr->nArg ){
int i, j;
sqlite3_stmt *pTest = 0;
const char *zSel = (pAr->bGlob)
? "SELECT name FROM %s WHERE glob($name,name)"
: "SELECT name FROM %s WHERE name=$name";
shellPreparePrintf(pAr->db, &rc, &pTest, zSel, pAr->zSrcTable);
j = sqlite3_bind_parameter_index(pTest, "$name");
for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
char *z = pAr->azArg[i];
int n = strlen30(z);
int bOk = 0;
while( n>0 && z[n-1]=='/' ) n--;
z[n] = '\0';
|
| ︙ | ︙ | |||
17469 17470 17471 17472 17473 17474 17475 | } /* ** Format a WHERE clause that can be used against the "sqlar" table to ** identify all archive members that match the command arguments held ** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning. ** The caller is responsible for eventually calling sqlite3_free() on | | > | > | | | 17481 17482 17483 17484 17485 17486 17487 17488 17489 17490 17491 17492 17493 17494 17495 17496 17497 17498 17499 17500 17501 17502 17503 17504 17505 17506 17507 17508 17509 17510 17511 17512 17513 17514 17515 |
}
/*
** Format a WHERE clause that can be used against the "sqlar" table to
** identify all archive members that match the command arguments held
** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
** The caller is responsible for eventually calling sqlite3_free() on
** any non-NULL (*pzWhere) value. Here, "match" means strict equality
** when pAr->bGlob is false and GLOB match when pAr->bGlob is true.
*/
static void arWhereClause(
int *pRc,
ArCommand *pAr,
char **pzWhere /* OUT: New WHERE clause */
){
char *zWhere = 0;
const char *zSameOp = (pAr->bGlob)? "GLOB" : "=";
if( *pRc==SQLITE_OK ){
if( pAr->nArg==0 ){
zWhere = sqlite3_mprintf("1");
}else{
int i;
const char *zSep = "";
for(i=0; i<pAr->nArg; i++){
const char *z = pAr->azArg[i];
zWhere = sqlite3_mprintf(
"%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
);
if( zWhere==0 ){
*pRc = SQLITE_NOMEM;
break;
}
zSep = " OR ";
}
|
| ︙ | ︙ | |||
17540 17541 17542 17543 17544 17545 17546 17547 17548 17549 17550 17551 17552 17553 |
}
}
shellFinalize(&rc, pSql);
sqlite3_free(zWhere);
return rc;
}
/*
** Implementation of .ar "eXtract" command.
*/
static int arExtractCommand(ArCommand *pAr){
const char *zSql1 =
"SELECT "
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 17554 17555 17556 17557 17558 17559 17560 17561 17562 17563 17564 17565 17566 17567 17568 17569 17570 17571 17572 17573 17574 17575 17576 17577 17578 17579 17580 17581 17582 17583 17584 17585 17586 17587 17588 17589 17590 17591 17592 17593 17594 17595 17596 17597 17598 17599 17600 17601 17602 17603 17604 17605 17606 17607 17608 |
}
}
shellFinalize(&rc, pSql);
sqlite3_free(zWhere);
return rc;
}
/*
** Implementation of .ar "Remove" command.
*/
static int arRemoveCommand(ArCommand *pAr){
int rc = 0;
char *zSql = 0;
char *zWhere = 0;
if( pAr->nArg ){
/* Verify that args actually exist within the archive before proceeding.
** And formulate a WHERE clause to match them. */
rc = arCheckEntries(pAr);
arWhereClause(&rc, pAr, &zWhere);
}
if( rc==SQLITE_OK ){
zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;",
pAr->zSrcTable, zWhere);
if( pAr->bDryRun ){
utf8_printf(pAr->p->out, "%s\n", zSql);
}else{
char *zErr = 0;
rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0);
if( rc==SQLITE_OK ){
rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
if( rc!=SQLITE_OK ){
sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0);
}else{
rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0);
}
}
if( zErr ){
utf8_printf(stdout, "ERROR: %s\n", zErr);
sqlite3_free(zErr);
}
}
}
sqlite3_free(zWhere);
sqlite3_free(zSql);
return rc;
}
/*
** Implementation of .ar "eXtract" command.
*/
static int arExtractCommand(ArCommand *pAr){
const char *zSql1 =
"SELECT "
|
| ︙ | ︙ | |||
17793 17794 17795 17796 17797 17798 17799 |
}
}
cmd.bZip = 1;
}else if( cmd.zFile ){
int flags;
if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
| | | 17848 17849 17850 17851 17852 17853 17854 17855 17856 17857 17858 17859 17860 17861 17862 |
}
}
cmd.bZip = 1;
}else if( cmd.zFile ){
int flags;
if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
|| cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){
flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
}else{
flags = SQLITE_OPEN_READONLY;
}
cmd.db = 0;
if( cmd.bDryRun ){
utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile,
|
| ︙ | ︙ | |||
17848 17849 17850 17851 17852 17853 17854 17855 17856 17857 17858 17859 17860 17861 |
case AR_CMD_HELP:
arUsage(pState->out);
break;
case AR_CMD_INSERT:
rc = arCreateOrUpdateCommand(&cmd, 1, 0);
break;
default:
assert( cmd.eCmd==AR_CMD_UPDATE );
rc = arCreateOrUpdateCommand(&cmd, 1, 1);
break;
}
}
| > > > > | 17903 17904 17905 17906 17907 17908 17909 17910 17911 17912 17913 17914 17915 17916 17917 17918 17919 17920 |
case AR_CMD_HELP:
arUsage(pState->out);
break;
case AR_CMD_INSERT:
rc = arCreateOrUpdateCommand(&cmd, 1, 0);
break;
case AR_CMD_REMOVE:
rc = arRemoveCommand(&cmd);
break;
default:
assert( cmd.eCmd==AR_CMD_UPDATE );
rc = arCreateOrUpdateCommand(&cmd, 1, 1);
break;
}
}
|
| ︙ | ︙ | |||
19337 19338 19339 19340 19341 19342 19343 19344 19345 19346 19347 19348 19349 19350 |
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
int eVerbose = 0; /* Larger for more console output */
int nSkip = 0; /* Initial lines to skip */
int useOutputMode = 1; /* Use output mode to determine separators */
failIfSafeMode(p, "cannot run .import in safe mode");
memset(&sCtx, 0, sizeof(sCtx));
if( p->mode==MODE_Ascii ){
xRead = ascii_read_one_field;
}else{
xRead = csv_read_one_field;
}
for(i=1; i<nArg; i++){
char *z = azArg[i];
| > > > > > | 19396 19397 19398 19399 19400 19401 19402 19403 19404 19405 19406 19407 19408 19409 19410 19411 19412 19413 19414 |
char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
int eVerbose = 0; /* Larger for more console output */
int nSkip = 0; /* Initial lines to skip */
int useOutputMode = 1; /* Use output mode to determine separators */
failIfSafeMode(p, "cannot run .import in safe mode");
memset(&sCtx, 0, sizeof(sCtx));
sCtx.z = sqlite3_malloc64(120);
if( sCtx.z==0 ){
import_cleanup(&sCtx);
shell_out_of_memory();
}
if( p->mode==MODE_Ascii ){
xRead = ascii_read_one_field;
}else{
xRead = csv_read_one_field;
}
for(i=1; i<nArg; i++){
char *z = azArg[i];
|
| ︙ | ︙ | |||
19446 19447 19448 19449 19450 19451 19452 19453 19454 19455 19456 19457 19458 19459 |
}else{
sCtx.in = fopen(sCtx.zFile, "rb");
sCtx.xCloser = fclose;
}
if( sCtx.in==0 ){
utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
rc = 1;
goto meta_command_exit;
}
if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
char zSep[2];
zSep[1] = 0;
zSep[0] = sCtx.cColSep;
utf8_printf(p->out, "Column separator ");
| > | 19510 19511 19512 19513 19514 19515 19516 19517 19518 19519 19520 19521 19522 19523 19524 |
}else{
sCtx.in = fopen(sCtx.zFile, "rb");
sCtx.xCloser = fclose;
}
if( sCtx.in==0 ){
utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
rc = 1;
import_cleanup(&sCtx);
goto meta_command_exit;
}
if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
char zSep[2];
zSep[1] = 0;
zSep[0] = sCtx.cColSep;
utf8_printf(p->out, "Column separator ");
|
| ︙ | ︙ |
Changes to src/sqlite3.c.
| ︙ | ︙ | |||
450 451 452 453 454 455 456 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.37.0" #define SQLITE_VERSION_NUMBER 3037000 | | | 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.37.0" #define SQLITE_VERSION_NUMBER 3037000 #define SQLITE_SOURCE_ID "2021-11-03 16:35:23 3206edff947b9edb485466f05b2baadf725d798229630c7e83e88c0b9ae278ca" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 | ** ^The rollback callback is not invoked if a transaction is ** automatically rolled back because the database connection is closed. ** ** See also the [sqlite3_update_hook()] interface. */ SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks ** METHOD: sqlite3 ** ** ^The sqlite3_update_hook() interface registers a callback function ** with the [database connection] identified by the first argument | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 |
** ^The rollback callback is not invoked if a transaction is
** automatically rolled back because the database connection is closed.
**
** See also the [sqlite3_update_hook()] interface.
*/
SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
** CAPI3REF: Autovacuum Compaction Amount Callback
** METHOD: sqlite3
**
** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback
** function C that is invoked prior to each autovacuum of the database
** file. ^The callback is passed a copy of the generic data pointer (P),
** the schema-name of the attached database that is being autovacuumed,
** the the size of the database file in pages, the number of free pages,
** and the number of bytes per page, respectively. The callback should
** return the number of free pages that should be removed by the
** autovacuum. ^If the callback returns zero, then no autovacuum happens.
** ^If the value returned is greater than or equal to the number of
** free pages, then a complete autovacuum happens.
**
** <p>^If there are multiple ATTACH-ed database files that are being
** modified as part of a transaction commit, then the autovacuum pages
** callback is invoked separately for each file.
**
** <p><b>The callback is not reentrant.</b> The callback function should
** not attempt to invoke any other SQLite interface. If it does, bad
** things may happen, including segmentation faults and corrupt database
** files. The callback function should be a simple function that
** does some arithmetic on its input parameters and returns a result.
**
** ^The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional
** destructor for the P parameter. ^If X is not NULL, then X(P) is
** invoked whenever the database connection closes or when the callback
** is overwritten by another invocation of sqlite3_autovacuum_pages().
**
** <p>^There is only one autovacuum pages callback per database connection.
** ^Each call to the sqlite3_autovacuum_pages() interface overrides all
** previous invocations for that database connection. ^If the callback
** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer,
** then the autovacuum steps callback is cancelled. The return value
** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might
** be some other error code if something goes wrong. The current
** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other
** return codes might be added in future releases.
**
** <p>If no autovacuum pages callback is specified (the usual case) or
** a NULL pointer is provided for the callback,
** then the default behavior is to vacuum all free pages. So, in other
** words, the default behavior is the same as if the callback function
** were something like this:
**
** <blockquote><pre>
** unsigned int demonstration_autovac_pages_callback(
** void *pClientData,
** const char *zSchema,
** unsigned int nDbPage,
** unsigned int nFreePage,
** unsigned int nBytePerPage
** ){
** return nFreePage;
** }
** </pre></blockquote>
*/
SQLITE_API int sqlite3_autovacuum_pages(
sqlite3 *db,
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
void*,
void(*)(void*)
);
/*
** CAPI3REF: Data Change Notification Callbacks
** METHOD: sqlite3
**
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
|
| ︙ | ︙ | |||
16435 16436 16437 16438 16439 16440 16441 16442 16443 16444 16445 16446 16447 16448 |
#endif
void *pCommitArg; /* Argument to xCommitCallback() */
int (*xCommitCallback)(void*); /* Invoked at every commit. */
void *pRollbackArg; /* Argument to xRollbackCallback() */
void (*xRollbackCallback)(void*); /* Invoked at every commit. */
void *pUpdateArg;
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
Parse *pParse; /* Current parse */
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
);
PreUpdate *pPreUpdate; /* Context for active pre-update callback */
| > > > | 16501 16502 16503 16504 16505 16506 16507 16508 16509 16510 16511 16512 16513 16514 16515 16516 16517 |
#endif
void *pCommitArg; /* Argument to xCommitCallback() */
int (*xCommitCallback)(void*); /* Invoked at every commit. */
void *pRollbackArg; /* Argument to xRollbackCallback() */
void (*xRollbackCallback)(void*); /* Invoked at every commit. */
void *pUpdateArg;
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
void *pAutovacPagesArg; /* Client argument to autovac_pages */
void (*xAutovacDestr)(void*); /* Destructor for pAutovacPAgesArg */
unsigned int (*xAutovacPages)(void*,const char*,u32,u32,u32);
Parse *pParse; /* Current parse */
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
);
PreUpdate *pPreUpdate; /* Context for active pre-update callback */
|
| ︙ | ︙ | |||
18692 18693 18694 18695 18696 18697 18698 18699 18700 18701 18702 18703 18704 18705 18706 18707 | u32 nInitRow; /* Number of rows processed */ Pgno mxPage; /* Maximum page number. 0 for no limit. */ } InitData; /* ** Allowed values for mInitFlags */ #define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ #define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning ** parameters are for temporary use during development, to help find ** optimial values for parameters in the query planner. The should not ** be used on trunk check-ins. They are a temporary mechanism available ** for transient development builds only. | > > | 18761 18762 18763 18764 18765 18766 18767 18768 18769 18770 18771 18772 18773 18774 18775 18776 18777 18778 | u32 nInitRow; /* Number of rows processed */ Pgno mxPage; /* Maximum page number. 0 for no limit. */ } InitData; /* ** Allowed values for mInitFlags */ #define INITFLAG_AlterMask 0x0003 /* Types of ALTER */ #define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ #define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ #define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */ /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning ** parameters are for temporary use during development, to help find ** optimial values for parameters in the query planner. The should not ** be used on trunk check-ins. They are a temporary mechanism available ** for transient development builds only. |
| ︙ | ︙ | |||
24124 24125 24126 24127 24128 24129 24130 24131 24132 24133 24134 24135 24136 24137 24138 24139 24140 24141 24142 24143 |
int rc;
sqlite3_file *pFile;
pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
if( pFile ){
rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
if( rc!=SQLITE_OK ){
sqlite3_free(pFile);
}else{
*ppFile = pFile;
}
}else{
rc = SQLITE_NOMEM_BKPT;
}
return rc;
}
SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
assert( pFile );
sqlite3OsClose(pFile);
sqlite3_free(pFile);
}
| > > > | 24195 24196 24197 24198 24199 24200 24201 24202 24203 24204 24205 24206 24207 24208 24209 24210 24211 24212 24213 24214 24215 24216 24217 |
int rc;
sqlite3_file *pFile;
pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
if( pFile ){
rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
if( rc!=SQLITE_OK ){
sqlite3_free(pFile);
*ppFile = 0;
}else{
*ppFile = pFile;
}
}else{
*ppFile = 0;
rc = SQLITE_NOMEM_BKPT;
}
assert( *ppFile!=0 || rc!=SQLITE_OK );
return rc;
}
SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
assert( pFile );
sqlite3OsClose(pFile);
sqlite3_free(pFile);
}
|
| ︙ | ︙ | |||
38077 38078 38079 38080 38081 38082 38083 |
}else{
pFile->ctrlFlags |= mask;
}
}
/* Forward declaration */
static int unixGetTempname(int nBuf, char *zBuf);
| > | > | 38151 38152 38153 38154 38155 38156 38157 38158 38159 38160 38161 38162 38163 38164 38165 38166 38167 |
}else{
pFile->ctrlFlags |= mask;
}
}
/* Forward declaration */
static int unixGetTempname(int nBuf, char *zBuf);
#ifndef SQLITE_OMIT_WAL
static int unixFcntlExternalReader(unixFile*, int*);
#endif
/*
** Information and control of an open file handle.
*/
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
unixFile *pFile = (unixFile*)id;
switch( op ){
|
| ︙ | ︙ | |||
38196 38197 38198 38199 38200 38201 38202 38203 38204 38205 38206 38207 38208 38209 38210 |
case SQLITE_FCNTL_SET_LOCKPROXYFILE:
case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
return proxyFileControl(id,op,pArg);
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
case SQLITE_FCNTL_EXTERNAL_READER: {
return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
}
}
return SQLITE_NOTFOUND;
}
/*
** If pFd->sectorSize is non-zero when this function is called, it is a
| > > > > > | 38272 38273 38274 38275 38276 38277 38278 38279 38280 38281 38282 38283 38284 38285 38286 38287 38288 38289 38290 38291 |
case SQLITE_FCNTL_SET_LOCKPROXYFILE:
case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
return proxyFileControl(id,op,pArg);
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
case SQLITE_FCNTL_EXTERNAL_READER: {
#ifndef SQLITE_OMIT_WAL
return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
#else
*(int*)pArg = 0;
return SQLITE_OK;
#endif
}
}
return SQLITE_NOTFOUND;
}
/*
** If pFd->sectorSize is non-zero when this function is called, it is a
|
| ︙ | ︙ | |||
48900 48901 48902 48903 48904 48905 48906 48907 48908 48909 48910 48911 48912 48913 |
sqlite3_file *pFd,
int flags,
int *pOutFlags
){
MemFile *pFile = (MemFile*)pFd;
MemStore *p = 0;
int szName;
memset(pFile, 0, sizeof(*pFile));
szName = sqlite3Strlen30(zName);
if( szName>1 && zName[0]=='/' ){
int i;
#ifndef SQLITE_MUTEX_OMIT
sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
| > | 48981 48982 48983 48984 48985 48986 48987 48988 48989 48990 48991 48992 48993 48994 48995 |
sqlite3_file *pFd,
int flags,
int *pOutFlags
){
MemFile *pFile = (MemFile*)pFd;
MemStore *p = 0;
int szName;
UNUSED_PARAMETER(pVfs);
memset(pFile, 0, sizeof(*pFile));
szName = sqlite3Strlen30(zName);
if( szName>1 && zName[0]=='/' ){
int i;
#ifndef SQLITE_MUTEX_OMIT
sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
|
| ︙ | ︙ | |||
60862 60863 60864 60865 60866 60867 60868 | ** numbered from zero. ** ** If the wal-index is currently smaller the iPage pages then the size ** of the wal-index might be increased, but only if it is safe to do ** so. It is safe to enlarge the wal-index if pWal->writeLock is true ** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE. ** | | > | | > > > | 60944 60945 60946 60947 60948 60949 60950 60951 60952 60953 60954 60955 60956 60957 60958 60959 60960 60961 60962 60963 60964 |
** numbered from zero.
**
** If the wal-index is currently smaller the iPage pages then the size
** of the wal-index might be increased, but only if it is safe to do
** so. It is safe to enlarge the wal-index if pWal->writeLock is true
** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
**
** Three possible result scenarios:
**
** (1) rc==SQLITE_OK and *ppPage==Requested-Wal-Index-Page
** (2) rc>=SQLITE_ERROR and *ppPage==NULL
** (3) rc==SQLITE_OK and *ppPage==NULL // only if iPage==0
**
** Scenario (3) can only occur when pWal->writeLock is false and iPage==0
*/
static SQLITE_NOINLINE int walIndexPageRealloc(
Wal *pWal, /* The WAL context */
int iPage, /* The page we seek */
volatile u32 **ppPage /* Write the page pointer here */
){
int rc = SQLITE_OK;
|
| ︙ | ︙ | |||
60897 60898 60899 60900 60901 60902 60903 |
if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
);
| | > > | 60983 60984 60985 60986 60987 60988 60989 60990 60991 60992 60993 60994 60995 60996 60997 60998 60999 |
if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
}else{
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
);
assert( pWal->apWiData[iPage]!=0
|| rc!=SQLITE_OK
|| (pWal->writeLock==0 && iPage==0) );
testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
if( rc==SQLITE_OK ){
if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM;
}else if( (rc&0xff)==SQLITE_READONLY ){
pWal->readOnly |= WAL_SHM_RDONLY;
if( rc==SQLITE_READONLY ){
rc = SQLITE_OK;
|
| ︙ | ︙ | |||
61236 61237 61238 61239 61240 61241 61242 | ** ** Set output variable pLoc->aHash to point to the start of the hash table ** in the wal-index file. Set pLoc->iZero to one less than the frame ** number of the first frame indexed by this hash table. If a ** slot in the hash table is set to N, it refers to frame number ** (pLoc->iZero+N) in the log. ** | | | | > | | 61324 61325 61326 61327 61328 61329 61330 61331 61332 61333 61334 61335 61336 61337 61338 61339 61340 61341 61342 61343 61344 61345 61346 61347 61348 61349 61350 61351 61352 61353 61354 61355 61356 61357 61358 61359 61360 |
**
** Set output variable pLoc->aHash to point to the start of the hash table
** in the wal-index file. Set pLoc->iZero to one less than the frame
** number of the first frame indexed by this hash table. If a
** slot in the hash table is set to N, it refers to frame number
** (pLoc->iZero+N) in the log.
**
** Finally, set pLoc->aPgno so that pLoc->aPgno[0] is the page number of the
** first frame indexed by the hash table, frame (pLoc->iZero).
*/
static int walHashGet(
Wal *pWal, /* WAL handle */
int iHash, /* Find the iHash'th table */
WalHashLoc *pLoc /* OUT: Hash table location */
){
int rc; /* Return code */
rc = walIndexPage(pWal, iHash, &pLoc->aPgno);
assert( rc==SQLITE_OK || iHash>0 );
if( pLoc->aPgno ){
pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE];
if( iHash==0 ){
pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
pLoc->iZero = 0;
}else{
pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
}
}else if( NEVER(rc==SQLITE_OK) ){
rc = SQLITE_ERROR;
}
return rc;
}
/*
** Return the number of the wal-index page that contains the hash-table
** and page-number array that contain entries corresponding to WAL frame
|
| ︙ | ︙ | |||
61339 61340 61341 61342 61343 61344 61345 |
sLoc.aHash[i] = 0;
}
}
/* Zero the entries in the aPgno array that correspond to frames with
** frame numbers greater than pWal->hdr.mxFrame.
*/
| | > | | | | | 61428 61429 61430 61431 61432 61433 61434 61435 61436 61437 61438 61439 61440 61441 61442 61443 61444 61445 61446 61447 61448 61449 61450 61451 61452 61453 61454 61455 61456 61457 |
sLoc.aHash[i] = 0;
}
}
/* Zero the entries in the aPgno array that correspond to frames with
** frame numbers greater than pWal->hdr.mxFrame.
*/
nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit]);
assert( nByte>=0 );
memset((void *)&sLoc.aPgno[iLimit], 0, nByte);
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
/* Verify that the every entry in the mapping region is still reachable
** via the hash table even after the cleanup.
*/
if( iLimit ){
int j; /* Loop counter */
int iKey; /* Hash key */
for(j=0; j<iLimit; j++){
for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){
if( sLoc.aHash[iKey]==j+1 ) break;
}
assert( sLoc.aHash[iKey]==j+1 );
}
}
#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
}
/*
|
| ︙ | ︙ | |||
61385 61386 61387 61388 61389 61390 61391 |
idx = iFrame - sLoc.iZero;
assert( idx <= HASHTABLE_NSLOT/2 + 1 );
/* If this is the first entry to be added to this hash-table, zero the
** entire hash table and aPgno[] array before proceeding.
*/
if( idx==1 ){
| | | | | | | | | | < | 61475 61476 61477 61478 61479 61480 61481 61482 61483 61484 61485 61486 61487 61488 61489 61490 61491 61492 61493 61494 61495 61496 61497 61498 61499 61500 61501 61502 61503 61504 61505 61506 61507 61508 61509 61510 61511 61512 61513 61514 61515 61516 61517 61518 61519 61520 61521 61522 61523 61524 61525 61526 61527 61528 61529 61530 61531 61532 61533 61534 61535 61536 61537 61538 61539 61540 61541 |
idx = iFrame - sLoc.iZero;
assert( idx <= HASHTABLE_NSLOT/2 + 1 );
/* If this is the first entry to be added to this hash-table, zero the
** entire hash table and aPgno[] array before proceeding.
*/
if( idx==1 ){
int nByte = (int)((u8*)&sLoc.aHash[HASHTABLE_NSLOT] - (u8*)sLoc.aPgno);
assert( nByte>=0 );
memset((void*)sLoc.aPgno, 0, nByte);
}
/* If the entry in aPgno[] is already set, then the previous writer
** must have exited unexpectedly in the middle of a transaction (after
** writing one or more dirty pages to the WAL to free up memory).
** Remove the remnants of that writers uncommitted transaction from
** the hash-table before writing any new entries.
*/
if( sLoc.aPgno[idx-1] ){
walCleanupHash(pWal);
assert( !sLoc.aPgno[idx-1] );
}
/* Write the aPgno[] array entry and the hash-table slot. */
nCollide = idx;
for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
}
sLoc.aPgno[idx-1] = iPage;
AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx);
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
/* Verify that the number of entries in the hash table exactly equals
** the number of entries in the mapping region.
*/
{
int i; /* Loop counter */
int nEntry = 0; /* Number of entries in the hash table */
for(i=0; i<HASHTABLE_NSLOT; i++){ if( sLoc.aHash[i] ) nEntry++; }
assert( nEntry==idx );
}
/* Verify that the every entry in the mapping region is reachable
** via the hash table. This turns out to be a really, really expensive
** thing to check, so only do this occasionally - not on every
** iteration.
*/
if( (idx&0x3ff)==0 ){
int i; /* Loop counter */
for(i=0; i<idx; i++){
for(iKey=walHash(sLoc.aPgno[i]);
sLoc.aHash[iKey];
iKey=walNextHash(iKey)){
if( sLoc.aHash[iKey]==i+1 ) break;
}
assert( sLoc.aHash[iKey]==i+1 );
}
}
#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
}
return rc;
}
/*
** Recover the wal-index by reading the write-ahead log file.
|
| ︙ | ︙ | |||
61560 61561 61562 61563 61564 61565 61566 |
for(iPg=0; iPg<=(u32)walFramePage(iLastFrame); iPg++){
u32 *aShare;
u32 iFrame; /* Index of last frame read */
u32 iLast = MIN(iLastFrame, HASHTABLE_NPAGE_ONE+iPg*HASHTABLE_NPAGE);
u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE);
u32 nHdr, nHdr32;
rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare);
| > | | 61649 61650 61651 61652 61653 61654 61655 61656 61657 61658 61659 61660 61661 61662 61663 61664 |
for(iPg=0; iPg<=(u32)walFramePage(iLastFrame); iPg++){
u32 *aShare;
u32 iFrame; /* Index of last frame read */
u32 iLast = MIN(iLastFrame, HASHTABLE_NPAGE_ONE+iPg*HASHTABLE_NPAGE);
u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE);
u32 nHdr, nHdr32;
rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare);
assert( aShare!=0 || rc!=SQLITE_OK );
if( aShare==0 ) break;
pWal->apWiData[iPg] = aPrivate;
for(iFrame=iFirst; iFrame<=iLast; iFrame++){
i64 iOffset = walFrameOffset(iFrame, szPage);
u32 pgno; /* Database page number for frame */
u32 nTruncate; /* dbsize field from frame header */
|
| ︙ | ︙ | |||
62057 62058 62059 62060 62061 62062 62063 |
rc = walHashGet(pWal, i, &sLoc);
if( rc==SQLITE_OK ){
int j; /* Counter variable */
int nEntry; /* Number of entries in this segment */
ht_slot *aIndex; /* Sorted index for this segment */
| < | 62147 62148 62149 62150 62151 62152 62153 62154 62155 62156 62157 62158 62159 62160 |
rc = walHashGet(pWal, i, &sLoc);
if( rc==SQLITE_OK ){
int j; /* Counter variable */
int nEntry; /* Number of entries in this segment */
ht_slot *aIndex; /* Sorted index for this segment */
if( (i+1)==nSegment ){
nEntry = (int)(iLast - sLoc.iZero);
}else{
nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno);
}
aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[sLoc.iZero];
sLoc.iZero++;
|
| ︙ | ︙ | |||
63196 63197 63198 63199 63200 63201 63202 |
WalHashLoc sLoc; /* Hash table location */
u32 pgno; /* Page number in db file */
i64 iDbOff; /* Offset of db file entry */
i64 iWalOff; /* Offset of wal file entry */
rc = walHashGet(pWal, walFramePage(i), &sLoc);
if( rc!=SQLITE_OK ) break;
| > | | 63285 63286 63287 63288 63289 63290 63291 63292 63293 63294 63295 63296 63297 63298 63299 63300 |
WalHashLoc sLoc; /* Hash table location */
u32 pgno; /* Page number in db file */
i64 iDbOff; /* Offset of db file entry */
i64 iWalOff; /* Offset of wal file entry */
rc = walHashGet(pWal, walFramePage(i), &sLoc);
if( rc!=SQLITE_OK ) break;
assert( i - sLoc.iZero - 1 >=0 );
pgno = sLoc.aPgno[i-sLoc.iZero-1];
iDbOff = (i64)(pgno-1) * szPage;
if( iDbOff+szPage<=szDb ){
iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
if( rc==SQLITE_OK ){
|
| ︙ | ︙ | |||
63429 63430 63431 63432 63433 63434 63435 |
if( rc!=SQLITE_OK ){
return rc;
}
nCollide = HASHTABLE_NSLOT;
iKey = walHash(pgno);
while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
u32 iFrame = iH + sLoc.iZero;
| | | 63519 63520 63521 63522 63523 63524 63525 63526 63527 63528 63529 63530 63531 63532 63533 |
if( rc!=SQLITE_OK ){
return rc;
}
nCollide = HASHTABLE_NSLOT;
iKey = walHash(pgno);
while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
u32 iFrame = iH + sLoc.iZero;
if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){
assert( iFrame>iRead || CORRUPT_DB );
iRead = iFrame;
}
if( (nCollide--)==0 ){
return SQLITE_CORRUPT_BKPT;
}
iKey = walNextHash(iKey);
|
| ︙ | ︙ | |||
69373 69374 69375 69376 69377 69378 69379 | sqlite3BtreeLeave(p); return rc; } /* ** This routine is called prior to sqlite3PagerCommit when a transaction ** is committed for an auto-vacuum database. | < < < < < | | > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > | | > | | > | 69463 69464 69465 69466 69467 69468 69469 69470 69471 69472 69473 69474 69475 69476 69477 69478 69479 69480 69481 69482 69483 69484 69485 69486 69487 69488 69489 69490 69491 69492 69493 69494 69495 69496 69497 69498 69499 69500 69501 69502 69503 69504 69505 69506 69507 69508 69509 69510 69511 69512 69513 69514 69515 69516 69517 69518 69519 69520 69521 69522 69523 69524 69525 69526 69527 69528 69529 69530 69531 69532 69533 69534 69535 69536 69537 69538 69539 69540 69541 69542 69543 69544 69545 |
sqlite3BtreeLeave(p);
return rc;
}
/*
** This routine is called prior to sqlite3PagerCommit when a transaction
** is committed for an auto-vacuum database.
*/
static int autoVacuumCommit(Btree *p){
int rc = SQLITE_OK;
Pager *pPager;
BtShared *pBt;
sqlite3 *db;
VVA_ONLY( int nRef );
assert( p!=0 );
pBt = p->pBt;
pPager = pBt->pPager;
VVA_ONLY( nRef = sqlite3PagerRefcount(pPager); )
assert( sqlite3_mutex_held(pBt->mutex) );
invalidateAllOverflowCache(pBt);
assert(pBt->autoVacuum);
if( !pBt->incrVacuum ){
Pgno nFin; /* Number of pages in database after autovacuuming */
Pgno nFree; /* Number of pages on the freelist initially */
Pgno nVac; /* Number of pages to vacuum */
Pgno iFree; /* The next page to be freed */
Pgno nOrig; /* Database size before freeing */
nOrig = btreePagecount(pBt);
if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
/* It is not possible to create a database for which the final page
** is either a pointer-map page or the pending-byte page. If one
** is encountered, this indicates corruption.
*/
return SQLITE_CORRUPT_BKPT;
}
nFree = get4byte(&pBt->pPage1->aData[36]);
db = p->db;
if( db->xAutovacPages ){
int iDb;
for(iDb=0; ALWAYS(iDb<db->nDb); iDb++){
if( db->aDb[iDb].pBt==p ) break;
}
nVac = db->xAutovacPages(
db->pAutovacPagesArg,
db->aDb[iDb].zDbSName,
nOrig,
nFree,
pBt->pageSize
);
if( nVac>nFree ){
nVac = nFree;
}
if( nVac==0 ){
return SQLITE_OK;
}
}else{
nVac = nFree;
}
nFin = finalDbSize(pBt, nOrig, nVac);
if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
if( nFin<nOrig ){
rc = saveAllCursors(pBt, 0, 0);
}
for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
rc = incrVacuumStep(pBt, nFin, iFree, nVac==nFree);
}
if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
if( nVac==nFree ){
put4byte(&pBt->pPage1->aData[32], 0);
put4byte(&pBt->pPage1->aData[36], 0);
}
put4byte(&pBt->pPage1->aData[28], nFin);
pBt->bDoTruncate = 1;
pBt->nPage = nFin;
}
if( rc!=SQLITE_OK ){
sqlite3PagerRollback(pPager);
}
|
| ︙ | ︙ | |||
69465 69466 69467 69468 69469 69470 69471 |
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zSuperJrnl){
int rc = SQLITE_OK;
if( p->inTrans==TRANS_WRITE ){
BtShared *pBt = p->pBt;
sqlite3BtreeEnter(p);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum ){
| | | 69582 69583 69584 69585 69586 69587 69588 69589 69590 69591 69592 69593 69594 69595 69596 |
SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zSuperJrnl){
int rc = SQLITE_OK;
if( p->inTrans==TRANS_WRITE ){
BtShared *pBt = p->pBt;
sqlite3BtreeEnter(p);
#ifndef SQLITE_OMIT_AUTOVACUUM
if( pBt->autoVacuum ){
rc = autoVacuumCommit(p);
if( rc!=SQLITE_OK ){
sqlite3BtreeLeave(p);
return rc;
}
}
if( pBt->bDoTruncate ){
sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage);
|
| ︙ | ︙ | |||
77427 77428 77429 77430 77431 77432 77433 77434 77435 77436 77437 77438 77439 77440 |
if( nByte<=0 ){
if( (pMem->flags & MEM_Blob)==0 ) return SQLITE_OK;
nByte = 1;
}
if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
return SQLITE_NOMEM_BKPT;
}
memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
pMem->n += pMem->u.nZero;
pMem->flags &= ~(MEM_Zero|MEM_Term);
return SQLITE_OK;
}
#endif
| > > | 77544 77545 77546 77547 77548 77549 77550 77551 77552 77553 77554 77555 77556 77557 77558 77559 |
if( nByte<=0 ){
if( (pMem->flags & MEM_Blob)==0 ) return SQLITE_OK;
nByte = 1;
}
if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
return SQLITE_NOMEM_BKPT;
}
assert( pMem->z!=0 );
assert( sqlite3DbMallocSize(pMem->db,pMem->z) >= nByte );
memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
pMem->n += pMem->u.nZero;
pMem->flags &= ~(MEM_Zero|MEM_Term);
return SQLITE_OK;
}
#endif
|
| ︙ | ︙ | |||
89394 89395 89396 89397 89398 89399 89400 |
break;
}else{
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
}
| | > > > > > | 89513 89514 89515 89516 89517 89518 89519 89520 89521 89522 89523 89524 89525 89526 89527 89528 89529 89530 89531 89532 89533 89534 89535 89536 89537 89538 89539 89540 89541 |
break;
}else{
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
}
/* Opcode: TypeCheck P1 P2 P3 P4 *
** Synopsis: typecheck(r[P1@P2])
**
** Apply affinities to the range of P2 registers beginning with P1.
** Take the affinities from the Table object in P4. If any value
** cannot be coerced into the correct type, then raise an error.
**
** This opcode is similar to OP_Affinity except that this opcode
** forces the register type to the Table column type. This is used
** to implement "strict affinity".
**
** GENERATED ALWAYS AS ... STATIC columns are only checked if P3
** is zero. When P3 is non-zero, no type checking occurs for
** static generated columns. Virtual columns are computed at query time
** and so they are never checked.
**
** Preconditions:
**
** <ul>
** <li> P2 should be the number of non-virtual columns in the
** table of P4.
** <li> Table P4 should be a STRICT table.
|
| ︙ | ︙ | |||
89427 89428 89429 89430 89431 89432 89433 |
assert( pOp->p4type==P4_TABLE );
pTab = pOp->p4.pTab;
assert( pTab->tabFlags & TF_Strict );
assert( pTab->nNVCol==pOp->p2 );
aCol = pTab->aCol;
pIn1 = &aMem[pOp->p1];
for(i=0; i<pTab->nCol; i++){
| > | > > | 89551 89552 89553 89554 89555 89556 89557 89558 89559 89560 89561 89562 89563 89564 89565 89566 89567 89568 |
assert( pOp->p4type==P4_TABLE );
pTab = pOp->p4.pTab;
assert( pTab->tabFlags & TF_Strict );
assert( pTab->nNVCol==pOp->p2 );
aCol = pTab->aCol;
pIn1 = &aMem[pOp->p1];
for(i=0; i<pTab->nCol; i++){
if( aCol[i].colFlags & COLFLAG_GENERATED ){
if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue;
if( pOp->p3 ){ pIn1++; continue; }
}
assert( pIn1 < &aMem[pOp->p1+pOp->p2] );
applyAffinity(pIn1, aCol[i].affinity, encoding);
if( (pIn1->flags & MEM_Null)==0 ){
switch( aCol[i].eCType ){
case COLTYPE_BLOB: {
if( (pIn1->flags & MEM_Blob)==0 ) goto vdbe_type_error;
break;
|
| ︙ | ︙ | |||
90151 90152 90153 90154 90155 90156 90157 90158 90159 90160 90161 90162 90163 90164 |
int iMeta = 0;
assert( p->bIsReader );
assert( p->readOnly==0 || pOp->p2==0 );
assert( pOp->p2>=0 && pOp->p2<=2 );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
rc = SQLITE_READONLY;
goto abort_due_to_error;
}
pBt = db->aDb[pOp->p1].pBt;
if( pBt ){
| > | 90278 90279 90280 90281 90282 90283 90284 90285 90286 90287 90288 90289 90290 90291 90292 |
int iMeta = 0;
assert( p->bIsReader );
assert( p->readOnly==0 || pOp->p2==0 );
assert( pOp->p2>=0 && pOp->p2<=2 );
assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( rc==SQLITE_OK );
if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
rc = SQLITE_READONLY;
goto abort_due_to_error;
}
pBt = db->aDb[pOp->p1].pBt;
if( pBt ){
|
| ︙ | ︙ | |||
90194 90195 90196 90197 90198 90199 90200 |
** counter. If the statement transaction needs to be rolled back,
** the value of this counter needs to be restored too. */
p->nStmtDefCons = db->nDeferredCons;
p->nStmtDefImmCons = db->nDeferredImmCons;
}
}
assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
| > | | 90322 90323 90324 90325 90326 90327 90328 90329 90330 90331 90332 90333 90334 90335 90336 90337 |
** counter. If the statement transaction needs to be rolled back,
** the value of this counter needs to be restored too. */
p->nStmtDefCons = db->nDeferredCons;
p->nStmtDefImmCons = db->nDeferredImmCons;
}
}
assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
if( rc==SQLITE_OK
&& pOp->p5
&& (iMeta!=pOp->p3
|| db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
){
/*
** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
** version is checked to ensure that the schema has not changed since the
** SQL statement was prepared.
|
| ︙ | ︙ | |||
97452 97453 97454 97455 97456 97457 97458 97459 97460 97461 97462 97463 97464 97465 |
pIncr->pTask = pTask;
pIncr->mxSz = MAX(pTask->pSorter->mxKeysize+9,pTask->pSorter->mxPmaSize/2);
pTask->file2.iEof += pIncr->mxSz;
}else{
vdbeMergeEngineFree(pMerger);
rc = SQLITE_NOMEM_BKPT;
}
return rc;
}
#if SQLITE_MAX_WORKER_THREADS>0
/*
** Set the "use-threads" flag on object pIncr.
*/
| > | 97581 97582 97583 97584 97585 97586 97587 97588 97589 97590 97591 97592 97593 97594 97595 |
pIncr->pTask = pTask;
pIncr->mxSz = MAX(pTask->pSorter->mxKeysize+9,pTask->pSorter->mxPmaSize/2);
pTask->file2.iEof += pIncr->mxSz;
}else{
vdbeMergeEngineFree(pMerger);
rc = SQLITE_NOMEM_BKPT;
}
assert( *ppOut!=0 || rc!=SQLITE_OK );
return rc;
}
#if SQLITE_MAX_WORKER_THREADS>0
/*
** Set the "use-threads" flag on object pIncr.
*/
|
| ︙ | ︙ | |||
103134 103135 103136 103137 103138 103139 103140 |
pp = &pNew->pPrior;
pNext = pNew;
}
return pRet;
}
#else
| | | 103264 103265 103266 103267 103268 103269 103270 103271 103272 103273 103274 103275 103276 103277 103278 |
pp = &pNew->pPrior;
pNext = pNew;
}
return pRet;
}
#else
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){
assert( p==0 );
return 0;
}
#endif
/*
|
| ︙ | ︙ | |||
108140 108141 108142 108143 108144 108145 108146 |
sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2);
sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
sqlite3ReleaseTempReg(pParse, r1);
/* Reload the table definition */
| | | 108270 108271 108272 108273 108274 108275 108276 108277 108278 108279 108280 108281 108282 108283 108284 |
sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2);
sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2);
VdbeCoverage(v);
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
sqlite3ReleaseTempReg(pParse, r1);
/* Reload the table definition */
renameReloadSchema(pParse, iDb, INITFLAG_AlterAdd);
/* Verify that constraints are still satisfied */
if( pNew->pCheck!=0
|| (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0)
){
sqlite3NestedParse(pParse,
"SELECT CASE WHEN quick_check GLOB 'CHECK*'"
|
| ︙ | ︙ | |||
109033 109034 109035 109036 109037 109038 109039 109040 109041 109042 109043 109044 109045 109046 |
if( p->pTab==0 ){
rc = SQLITE_ERROR;
}else{
p->pTab->nTabRef++;
rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
}
}
}
sNC.pSrcList = pSrc;
if( rc==SQLITE_OK && pStep->pWhere ){
rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
}
if( rc==SQLITE_OK ){
rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
| > > > | 109163 109164 109165 109166 109167 109168 109169 109170 109171 109172 109173 109174 109175 109176 109177 109178 109179 |
if( p->pTab==0 ){
rc = SQLITE_ERROR;
}else{
p->pTab->nTabRef++;
rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
}
}
}
if( rc==SQLITE_OK && db->mallocFailed ){
rc = SQLITE_NOMEM;
}
sNC.pSrcList = pSrc;
if( rc==SQLITE_OK && pStep->pWhere ){
rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
}
if( rc==SQLITE_OK ){
rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList);
|
| ︙ | ︙ | |||
123936 123937 123938 123939 123940 123941 123942 | testcase( pTab->tabFlags & TF_HasVirtual ); testcase( pTab->tabFlags & TF_HasStored ); /* Before computing generated columns, first go through and make sure ** that appropriate affinity has been applied to the regular columns */ sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore); | | | | | | | | | | | | | | | | | | | > > > > > > | 124069 124070 124071 124072 124073 124074 124075 124076 124077 124078 124079 124080 124081 124082 124083 124084 124085 124086 124087 124088 124089 124090 124091 124092 124093 124094 124095 124096 124097 124098 124099 124100 124101 124102 124103 124104 124105 124106 |
testcase( pTab->tabFlags & TF_HasVirtual );
testcase( pTab->tabFlags & TF_HasStored );
/* Before computing generated columns, first go through and make sure
** that appropriate affinity has been applied to the regular columns
*/
sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore);
if( (pTab->tabFlags & TF_HasStored)!=0 ){
pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1);
if( pOp->opcode==OP_Affinity ){
/* Change the OP_Affinity argument to '@' (NONE) for all stored
** columns. '@' is the no-op affinity and those columns have not
** yet been computed. */
int ii, jj;
char *zP4 = pOp->p4.z;
assert( zP4!=0 );
assert( pOp->p4type==P4_DYNAMIC );
for(ii=jj=0; zP4[jj]; ii++){
if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){
continue;
}
if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){
zP4[jj] = SQLITE_AFF_NONE;
}
jj++;
}
}else if( pOp->opcode==OP_TypeCheck ){
/* If an OP_TypeCheck was generated because the table is STRICT,
** then set the P3 operand to indicate that generated columns should
** not be checked */
pOp->p3 = 1;
}
}
/* Because there can be multiple generated columns that refer to one another,
** this is a two-pass algorithm. On the first pass, mark all generated
** columns as "not available".
*/
|
| ︙ | ︙ | |||
125981 125982 125983 125984 125985 125986 125987 |
break;
}
default: {
int nConflictCk; /* Number of opcodes in conflict check logic */
assert( onError==OE_Replace );
nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk;
| | > | 126120 126121 126122 126123 126124 126125 126126 126127 126128 126129 126130 126131 126132 126133 126134 126135 |
break;
}
default: {
int nConflictCk; /* Number of opcodes in conflict check logic */
assert( onError==OE_Replace );
nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk;
assert( nConflictCk>0 || db->mallocFailed );
testcase( nConflictCk<=0 );
testcase( nConflictCk>1 );
if( regTrigCnt ){
sqlite3MultiWrite(pParse);
nReplaceTrig++;
}
if( pTrigger && isUpdate ){
sqlite3VdbeAddOp1(v, OP_CursorLock, iDataCur);
|
| ︙ | ︙ | |||
126267 126268 126269 126270 126271 126272 126273 |
Index *pIdx;
Vdbe *v;
assert( op==OP_OpenRead || op==OP_OpenWrite );
assert( op==OP_OpenWrite || p5==0 );
if( IsVirtual(pTab) ){
/* This routine is a no-op for virtual tables. Leave the output
| | | > | 126407 126408 126409 126410 126411 126412 126413 126414 126415 126416 126417 126418 126419 126420 126421 126422 126423 |
Index *pIdx;
Vdbe *v;
assert( op==OP_OpenRead || op==OP_OpenWrite );
assert( op==OP_OpenWrite || p5==0 );
if( IsVirtual(pTab) ){
/* This routine is a no-op for virtual tables. Leave the output
** variables *piDataCur and *piIdxCur set to illegal cursor numbers
** for improved error detection. */
*piDataCur = *piIdxCur = -999;
return 0;
}
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
v = pParse->pVdbe;
assert( v!=0 );
if( iBase<0 ) iBase = pParse->nTab;
iDataCur = iBase++;
|
| ︙ | ︙ | |||
127279 127280 127281 127282 127283 127284 127285 127286 127287 127288 127289 127290 127291 127292 | void (*free_filename)(char*); sqlite3_file *(*database_file_object)(const char*); /* Version 3.34.0 and later */ int (*txn_state)(sqlite3*,const char*); /* Version 3.36.1 and later */ sqlite3_int64 (*changes64)(sqlite3*); sqlite3_int64 (*total_changes64)(sqlite3*); }; /* ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". */ typedef int (*sqlite3_loadext_entry)( | > > > > | 127420 127421 127422 127423 127424 127425 127426 127427 127428 127429 127430 127431 127432 127433 127434 127435 127436 127437 |
void (*free_filename)(char*);
sqlite3_file *(*database_file_object)(const char*);
/* Version 3.34.0 and later */
int (*txn_state)(sqlite3*,const char*);
/* Version 3.36.1 and later */
sqlite3_int64 (*changes64)(sqlite3*);
sqlite3_int64 (*total_changes64)(sqlite3*);
/* Version 3.37.0 and later */
int (*autovacuum_pages)(sqlite3*,
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
void*, void(*)(void*));
};
/*
** This is the function signature used for all extension entry points. It
** is also defined in the file "loadext.c".
*/
typedef int (*sqlite3_loadext_entry)(
|
| ︙ | ︙ | |||
127585 127586 127587 127588 127589 127590 127591 127592 127593 127594 127595 127596 127597 127598 | #define sqlite3_filename_wal sqlite3_api->filename_wal /* Version 3.32.0 and later */ #define sqlite3_create_filename sqlite3_api->create_filename #define sqlite3_free_filename sqlite3_api->free_filename #define sqlite3_database_file_object sqlite3_api->database_file_object /* Version 3.34.0 and later */ #define sqlite3_txn_state sqlite3_api->txn_state #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; | > > > > > | 127730 127731 127732 127733 127734 127735 127736 127737 127738 127739 127740 127741 127742 127743 127744 127745 127746 127747 127748 | #define sqlite3_filename_wal sqlite3_api->filename_wal /* Version 3.32.0 and later */ #define sqlite3_create_filename sqlite3_api->create_filename #define sqlite3_free_filename sqlite3_api->free_filename #define sqlite3_database_file_object sqlite3_api->database_file_object /* Version 3.34.0 and later */ #define sqlite3_txn_state sqlite3_api->txn_state /* Version 3.36.1 and later */ #define sqlite3_changes64 sqlite3_api->changes64 #define sqlite3_total_changes64 sqlite3_api->total_changes64 * Version 3.37.0 and later */ #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; |
| ︙ | ︙ | |||
128072 128073 128074 128075 128076 128077 128078 128079 128080 128081 128082 128083 128084 128085 | sqlite3_free_filename, sqlite3_database_file_object, /* Version 3.34.0 and later */ sqlite3_txn_state, /* Version 3.36.1 and later */ sqlite3_changes64, sqlite3_total_changes64, }; /* True if x is the directory separator character */ #if SQLITE_OS_WIN # define DirSep(X) ((X)=='/'||(X)=='\\') #else | > > | 128222 128223 128224 128225 128226 128227 128228 128229 128230 128231 128232 128233 128234 128235 128236 128237 | sqlite3_free_filename, sqlite3_database_file_object, /* Version 3.34.0 and later */ sqlite3_txn_state, /* Version 3.36.1 and later */ sqlite3_changes64, sqlite3_total_changes64, /* Version 3.37.0 and later */ sqlite3_autovacuum_pages, }; /* True if x is the directory separator character */ #if SQLITE_OS_WIN # define DirSep(X) ((X)=='/'||(X)=='\\') #else |
| ︙ | ︙ | |||
130909 130910 130911 130912 130913 130914 130915 |
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
}
if( pCol->notNull ){
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
pCol->zCnName);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
| | | 131061 131062 131063 131064 131065 131066 131067 131068 131069 131070 131071 131072 131073 131074 131075 |
sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
}
if( pCol->notNull ){
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
pCol->zCnName);
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
if( bStrict && pCol->eCType!=COLTYPE_ANY ){
sqlite3VdbeGoto(v, doError);
}else{
integrityCheckResultRow(v);
}
sqlite3VdbeJumpHere(v, jmp2);
}
if( (pTab->tabFlags & TF_Strict)!=0
|
| ︙ | ︙ | |||
131870 131871 131872 131873 131874 131875 131876 |
const char *zExtra /* Error information */
){
sqlite3 *db = pData->db;
if( db->mallocFailed ){
pData->rc = SQLITE_NOMEM_BKPT;
}else if( pData->pzErrMsg[0]!=0 ){
/* A error message has already been generated. Do not overwrite it */
| | > > > > > | | 132022 132023 132024 132025 132026 132027 132028 132029 132030 132031 132032 132033 132034 132035 132036 132037 132038 132039 132040 132041 132042 132043 132044 |
const char *zExtra /* Error information */
){
sqlite3 *db = pData->db;
if( db->mallocFailed ){
pData->rc = SQLITE_NOMEM_BKPT;
}else if( pData->pzErrMsg[0]!=0 ){
/* A error message has already been generated. Do not overwrite it */
}else if( pData->mInitFlags & (INITFLAG_AlterMask) ){
static const char *azAlterType[] = {
"rename",
"drop column",
"add column"
};
*pData->pzErrMsg = sqlite3MPrintf(db,
"error in %s %s after %s: %s", azObj[0], azObj[1],
azAlterType[(pData->mInitFlags&INITFLAG_AlterMask)-1],
zExtra
);
pData->rc = SQLITE_ERROR;
}else if( db->flags & SQLITE_WriteSchema ){
pData->rc = SQLITE_CORRUPT_BKPT;
}else{
char *z;
|
| ︙ | ︙ | |||
143904 143905 143906 143907 143908 143909 143910 | rc = execSql(db, pzErrMsg, "BEGIN"); if( rc!=SQLITE_OK ) goto end_of_vacuum; rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0); if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Do not attempt to change the page size for a WAL database */ if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain)) | | > > | 144061 144062 144063 144064 144065 144066 144067 144068 144069 144070 144071 144072 144073 144074 144075 144076 144077 |
rc = execSql(db, pzErrMsg, "BEGIN");
if( rc!=SQLITE_OK ) goto end_of_vacuum;
rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0);
if( rc!=SQLITE_OK ) goto end_of_vacuum;
/* Do not attempt to change the page size for a WAL database */
if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
==PAGER_JOURNALMODE_WAL
&& pOut==0
){
db->nextPagesize = 0;
}
if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
|| (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
|| NEVER(db->mallocFailed)
){
|
| ︙ | ︙ | |||
147903 147904 147905 147906 147907 147908 147909 147910 147911 147912 147913 147914 147915 147916 147917 147918 |
}
}
/* Load the value for the inequality constraint at the end of the
** range (if any).
*/
nConstraint = nEq;
if( pRangeEnd ){
Expr *pRight = pRangeEnd->pExpr->pRight;
codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
if( (pRangeEnd->wtFlags & TERM_VNULL)==0
&& sqlite3ExprCanBeNull(pRight)
){
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
VdbeCoverage(v);
| > > > > > > > > > > > | 148062 148063 148064 148065 148066 148067 148068 148069 148070 148071 148072 148073 148074 148075 148076 148077 148078 148079 148080 148081 148082 148083 148084 148085 148086 148087 148088 |
}
}
/* Load the value for the inequality constraint at the end of the
** range (if any).
*/
nConstraint = nEq;
assert( pLevel->p2==0 );
if( pRangeEnd ){
Expr *pRight = pRangeEnd->pExpr->pRight;
if( addrSeekScan ){
/* For a seek-scan that has a range on the lowest term of the index,
** we have to make the top of the loop be code that sets the end
** condition of the range. Otherwise, the OP_SeekScan might jump
** over that initialization, leaving the range-end value set to the
** range-start value, resulting in a wrong answer.
** See ticket 5981a8c041a3c2f3 (2021-11-02).
*/
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
}
codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
if( (pRangeEnd->wtFlags & TERM_VNULL)==0
&& sqlite3ExprCanBeNull(pRight)
){
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt);
VdbeCoverage(v);
|
| ︙ | ︙ | |||
147938 147939 147940 147941 147942 147943 147944 |
}
nConstraint++;
}
sqlite3DbFree(db, zStartAff);
sqlite3DbFree(db, zEndAff);
/* Top of the loop body */
| | | 148108 148109 148110 148111 148112 148113 148114 148115 148116 148117 148118 148119 148120 148121 148122 |
}
nConstraint++;
}
sqlite3DbFree(db, zStartAff);
sqlite3DbFree(db, zEndAff);
/* Top of the loop body */
if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v);
/* Check if the index cursor is past the end of the range. */
if( nConstraint ){
if( regBignull ){
/* Except, skip the end-of-range check while doing the NULL-scan */
sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+3);
VdbeComment((v, "If NULL-scan 2nd pass"));
|
| ︙ | ︙ | |||
167562 167563 167564 167565 167566 167567 167568 167569 167570 167571 167572 167573 167574 167575 |
/* The temp-database schema is allocated differently from the other schema
** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()).
** So it needs to be freed here. Todo: Why not roll the temp schema into
** the same sqliteMalloc() as the one that allocates the database
** structure?
*/
sqlite3DbFree(db, db->aDb[1].pSchema);
sqlite3_mutex_leave(db->mutex);
db->eOpenState = SQLITE_STATE_CLOSED;
sqlite3_mutex_free(db->mutex);
assert( sqlite3LookasideUsed(db,0)==0 );
if( db->lookaside.bMalloced ){
sqlite3_free(db->lookaside.pStart);
}
| > > > | 167732 167733 167734 167735 167736 167737 167738 167739 167740 167741 167742 167743 167744 167745 167746 167747 167748 |
/* The temp-database schema is allocated differently from the other schema
** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()).
** So it needs to be freed here. Todo: Why not roll the temp schema into
** the same sqliteMalloc() as the one that allocates the database
** structure?
*/
sqlite3DbFree(db, db->aDb[1].pSchema);
if( db->xAutovacDestr ){
db->xAutovacDestr(db->pAutovacPagesArg);
}
sqlite3_mutex_leave(db->mutex);
db->eOpenState = SQLITE_STATE_CLOSED;
sqlite3_mutex_free(db->mutex);
assert( sqlite3LookasideUsed(db,0)==0 );
if( db->lookaside.bMalloced ){
sqlite3_free(db->lookaside.pStart);
}
|
| ︙ | ︙ | |||
168462 168463 168464 168465 168466 168467 168468 168469 168470 168471 168472 168473 168474 168475 | pRet = db->pPreUpdateArg; db->xPreUpdateCallback = xCallback; db->pPreUpdateArg = pArg; sqlite3_mutex_leave(db->mutex); return pRet; } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ #ifndef SQLITE_OMIT_WAL /* ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). ** Invoke sqlite3_wal_checkpoint if the number of frames in the log file ** is greater than sqlite3.pWalArg cast to an integer (the value configured by ** wal_autocheckpoint()). | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 168635 168636 168637 168638 168639 168640 168641 168642 168643 168644 168645 168646 168647 168648 168649 168650 168651 168652 168653 168654 168655 168656 168657 168658 168659 168660 168661 168662 168663 168664 168665 168666 168667 168668 168669 168670 168671 168672 168673 168674 168675 168676 |
pRet = db->pPreUpdateArg;
db->xPreUpdateCallback = xCallback;
db->pPreUpdateArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pRet;
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
/*
** Register a function to be invoked prior to each autovacuum that
** determines the number of pages to vacuum.
*/
SQLITE_API int sqlite3_autovacuum_pages(
sqlite3 *db, /* Attach the hook to this database */
unsigned int (*xCallback)(void*,const char*,u32,u32,u32),
void *pArg, /* Argument to the function */
void (*xDestructor)(void*) /* Destructor for pArg */
){
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ){
if( xDestructor ) xDestructor(pArg);
return SQLITE_MISUSE_BKPT;
}
#endif
sqlite3_mutex_enter(db->mutex);
if( db->xAutovacDestr ){
db->xAutovacDestr(db->pAutovacPagesArg);
}
db->xAutovacPages = xCallback;
db->pAutovacPagesArg = pArg;
db->xAutovacDestr = xDestructor;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
#ifndef SQLITE_OMIT_WAL
/*
** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
** Invoke sqlite3_wal_checkpoint if the number of frames in the log file
** is greater than sqlite3.pWalArg cast to an integer (the value configured by
** wal_autocheckpoint()).
|
| ︙ | ︙ | |||
190859 190860 190861 190862 190863 190864 190865 | # define NEVER(X) ((X)?(assert(0),1):0) # else # define ALWAYS(X) (X) # define NEVER(X) (X) # endif # define testcase(X) #endif | | | 191060 191061 191062 191063 191064 191065 191066 191067 191068 191069 191070 191071 191072 191073 191074 | # define NEVER(X) ((X)?(assert(0),1):0) # else # define ALWAYS(X) (X) # define NEVER(X) (X) # endif # define testcase(X) #endif #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) # define VVA(X) #else # define VVA(X) X #endif /* ** Some of the testcase() macros in this file are problematic for gcov |
| ︙ | ︙ | |||
221611 221612 221613 221614 221615 221616 221617 221618 221619 221620 221621 221622 221623 221624 221625 221626 |
struct Fts5PoslistPopulator {
Fts5PoslistWriter writer;
int bOk; /* True if ok to populate */
int bMiss;
};
static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
Fts5PoslistPopulator *pRet;
pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
if( pRet ){
int i;
memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
for(i=0; i<pExpr->nPhrase; i++){
Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
| > > > > > > > > > | | 221812 221813 221814 221815 221816 221817 221818 221819 221820 221821 221822 221823 221824 221825 221826 221827 221828 221829 221830 221831 221832 221833 221834 221835 221836 221837 221838 221839 221840 221841 221842 221843 221844 |
struct Fts5PoslistPopulator {
Fts5PoslistWriter writer;
int bOk; /* True if ok to populate */
int bMiss;
};
/*
** Clear the position lists associated with all phrases in the expression
** passed as the first argument. Argument bLive is true if the expression
** might be pointing to a real entry, otherwise it has just been reset.
**
** At present this function is only used for detail=col and detail=none
** fts5 tables. This implies that all phrases must be at most 1 token
** in size, as phrase matches are not supported without detail=full.
*/
static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
Fts5PoslistPopulator *pRet;
pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
if( pRet ){
int i;
memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
for(i=0; i<pExpr->nPhrase; i++){
Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
assert( pExpr->apExprPhrase[i]->nTerm<=1 );
if( bLive &&
(pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
){
pRet[i].bMiss = 1;
}else{
pBuf->n = 0;
}
|
| ︙ | ︙ | |||
231985 231986 231987 231988 231989 231990 231991 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
| | | 232195 232196 232197 232198 232199 232200 232201 232202 232203 232204 232205 232206 232207 232208 232209 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2021-11-02 17:55:01 1d9004cd015073853ce0ca811a68ea5411733eedee993b97a38a42ba139d7590", -1, SQLITE_TRANSIENT);
}
/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts5ShadowName(const char *zName){
|
| ︙ | ︙ |
Changes to src/sqlite3.h.
| ︙ | ︙ | |||
144 145 146 147 148 149 150 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.37.0" #define SQLITE_VERSION_NUMBER 3037000 | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.37.0" #define SQLITE_VERSION_NUMBER 3037000 #define SQLITE_SOURCE_ID "2021-11-03 16:35:23 3206edff947b9edb485466f05b2baadf725d798229630c7e83e88c0b9ae278ca" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 | ** ^The rollback callback is not invoked if a transaction is ** automatically rolled back because the database connection is closed. ** ** See also the [sqlite3_update_hook()] interface. */ SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks ** METHOD: sqlite3 ** ** ^The sqlite3_update_hook() interface registers a callback function ** with the [database connection] identified by the first argument | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 |
** ^The rollback callback is not invoked if a transaction is
** automatically rolled back because the database connection is closed.
**
** See also the [sqlite3_update_hook()] interface.
*/
SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
/*
** CAPI3REF: Autovacuum Compaction Amount Callback
** METHOD: sqlite3
**
** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback
** function C that is invoked prior to each autovacuum of the database
** file. ^The callback is passed a copy of the generic data pointer (P),
** the schema-name of the attached database that is being autovacuumed,
** the the size of the database file in pages, the number of free pages,
** and the number of bytes per page, respectively. The callback should
** return the number of free pages that should be removed by the
** autovacuum. ^If the callback returns zero, then no autovacuum happens.
** ^If the value returned is greater than or equal to the number of
** free pages, then a complete autovacuum happens.
**
** <p>^If there are multiple ATTACH-ed database files that are being
** modified as part of a transaction commit, then the autovacuum pages
** callback is invoked separately for each file.
**
** <p><b>The callback is not reentrant.</b> The callback function should
** not attempt to invoke any other SQLite interface. If it does, bad
** things may happen, including segmentation faults and corrupt database
** files. The callback function should be a simple function that
** does some arithmetic on its input parameters and returns a result.
**
** ^The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional
** destructor for the P parameter. ^If X is not NULL, then X(P) is
** invoked whenever the database connection closes or when the callback
** is overwritten by another invocation of sqlite3_autovacuum_pages().
**
** <p>^There is only one autovacuum pages callback per database connection.
** ^Each call to the sqlite3_autovacuum_pages() interface overrides all
** previous invocations for that database connection. ^If the callback
** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer,
** then the autovacuum steps callback is cancelled. The return value
** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might
** be some other error code if something goes wrong. The current
** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other
** return codes might be added in future releases.
**
** <p>If no autovacuum pages callback is specified (the usual case) or
** a NULL pointer is provided for the callback,
** then the default behavior is to vacuum all free pages. So, in other
** words, the default behavior is the same as if the callback function
** were something like this:
**
** <blockquote><pre>
** unsigned int demonstration_autovac_pages_callback(
** void *pClientData,
** const char *zSchema,
** unsigned int nDbPage,
** unsigned int nFreePage,
** unsigned int nBytePerPage
** ){
** return nFreePage;
** }
** </pre></blockquote>
*/
SQLITE_API int sqlite3_autovacuum_pages(
sqlite3 *db,
unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
void*,
void(*)(void*)
);
/*
** CAPI3REF: Data Change Notification Callbacks
** METHOD: sqlite3
**
** ^The sqlite3_update_hook() interface registers a callback function
** with the [database connection] identified by the first argument
|
| ︙ | ︙ |