update bundled sqlite to 3.8.4.1

The "Fixed CE build of sqlite3" patch is preserved in this change.
(ea70ec8711)

Change-Id: I9cf211785071386173a87f645773cdae08498354
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
Reviewed-by: Mark Brand <mabrand@mabrand.nl>
This commit is contained in:
Mark Brand 2014-03-18 13:10:34 +01:00 committed by The Qt Project
parent 4059e586cc
commit 1fad6a2483
3 changed files with 7928 additions and 6494 deletions

View File

@ -45,14 +45,17 @@
# include <sys/types.h> # include <sys/types.h>
#endif #endif
#ifdef HAVE_EDITLINE #if defined(HAVE_READLINE) && HAVE_READLINE!=0
# include <editline/editline.h>
#endif
#if defined(HAVE_READLINE) && HAVE_READLINE==1
# include <readline/readline.h> # include <readline/readline.h>
# include <readline/history.h> # include <readline/history.h>
#else
# undef HAVE_READLINE
#endif #endif
#if !defined(HAVE_EDITLINE) && (!defined(HAVE_READLINE) || HAVE_READLINE!=1) #if defined(HAVE_EDITLINE) && !defined(HAVE_READLINE)
# define HAVE_READLINE 1
# include <editline/readline.h>
#endif
#if !defined(HAVE_READLINE)
# define add_history(X) # define add_history(X)
# define read_history(X) # define read_history(X)
# define write_history(X) # define write_history(X)
@ -62,7 +65,9 @@
#if defined(_WIN32) || defined(WIN32) #if defined(_WIN32) || defined(WIN32)
# include <io.h> # include <io.h>
#define isatty(h) _isatty(h) #define isatty(h) _isatty(h)
#define access(f,m) _access((f),(m)) #ifndef access
# define access(f,m) _access((f),(m))
#endif
#undef popen #undef popen
#define popen _popen #define popen _popen
#undef pclose #undef pclose
@ -413,7 +418,7 @@ static char *one_input_line(FILE *in, char *zPrior, int isContinuation){
zResult = local_getline(zPrior, in); zResult = local_getline(zPrior, in);
}else{ }else{
zPrompt = isContinuation ? continuePrompt : mainPrompt; zPrompt = isContinuation ? continuePrompt : mainPrompt;
#if defined(HAVE_READLINE) && HAVE_READLINE==1 #if defined(HAVE_READLINE)
free(zPrior); free(zPrior);
zResult = readline(zPrompt); zResult = readline(zPrompt);
if( zResult && *zResult ) add_history(zResult); if( zResult && *zResult ) add_history(zResult);
@ -441,6 +446,7 @@ struct previous_mode_data {
struct callback_data { struct callback_data {
sqlite3 *db; /* The database */ sqlite3 *db; /* The database */
int echoOn; /* True to echo input commands */ int echoOn; /* True to echo input commands */
int autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL statement */
int statsOn; /* True to display memory stats before each finalize */ int statsOn; /* True to display memory stats before each finalize */
int cnt; /* Number of records displayed so far */ int cnt; /* Number of records displayed so far */
FILE *out; /* Write results here */ FILE *out; /* Write results here */
@ -597,6 +603,7 @@ static void output_c_string(FILE *out, const char *z){
*/ */
static void output_html_string(FILE *out, const char *z){ static void output_html_string(FILE *out, const char *z){
int i; int i;
if( z==0 ) z = "";
while( *z ){ while( *z ){
for(i=0; z[i] for(i=0; z[i]
&& z[i]!='<' && z[i]!='<'
@ -1004,7 +1011,7 @@ static int run_table_dump_query(
int nResult; int nResult;
int i; int i;
const char *z; const char *z;
rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0); rc = sqlite3_prepare_v2(p->db, zSelect, -1, &pSelect, 0);
if( rc!=SQLITE_OK || !pSelect ){ if( rc!=SQLITE_OK || !pSelect ){
fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db)); fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++; if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
@ -1176,7 +1183,8 @@ static int str_in_array(const char *zStr, const char **azArray){
** **
** * For each "Goto", if the jump destination is earlier in the program ** * For each "Goto", if the jump destination is earlier in the program
** and ends on one of: ** and ends on one of:
** Yield SeekGt SeekLt RowSetRead ** Yield SeekGt SeekLt RowSetRead Rewind
** or if the P1 parameter is one instead of zero,
** then indent all opcodes between the earlier instruction ** then indent all opcodes between the earlier instruction
** and "Goto" by 2 spaces. ** and "Goto" by 2 spaces.
*/ */
@ -1188,7 +1196,7 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
int iOp; /* Index of operation in p->aiIndent[] */ int iOp; /* Index of operation in p->aiIndent[] */
const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 };
const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", 0 }; const char *azYield[] = { "Yield", "SeekLt", "SeekGt", "RowSetRead", "Rewind", 0 };
const char *azGoto[] = { "Goto", 0 }; const char *azGoto[] = { "Goto", 0 };
/* Try to figure out if this is really an EXPLAIN statement. If this /* Try to figure out if this is really an EXPLAIN statement. If this
@ -1224,8 +1232,10 @@ static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
if( str_in_array(zOp, azNext) ){ if( str_in_array(zOp, azNext) ){
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2; for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
} }
if( str_in_array(zOp, azGoto) && p2op<p->nIndent && abYield[p2op] ){ if( str_in_array(zOp, azGoto) && p2op<p->nIndent
for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2; && (abYield[p2op] || sqlite3_column_int(pSql, 2))
){
for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
} }
} }
@ -1296,6 +1306,23 @@ static int shell_exec(
fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql); fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
} }
/* Show the EXPLAIN QUERY PLAN if .eqp is on */
if( pArg && pArg->autoEQP ){
sqlite3_stmt *pExplain;
char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", sqlite3_sql(pStmt));
rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
if( rc==SQLITE_OK ){
while( sqlite3_step(pExplain)==SQLITE_ROW ){
fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
}
}
sqlite3_finalize(pExplain);
sqlite3_free(zEQP);
}
/* Output TESTCTRL_EXPLAIN text of requested */ /* Output TESTCTRL_EXPLAIN text of requested */
if( pArg && pArg->mode==MODE_Explain ){ if( pArg && pArg->mode==MODE_Explain ){
const char *zExplain = 0; const char *zExplain = 0;
@ -1452,7 +1479,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
zTableInfo = appendText(zTableInfo, zTable, '"'); zTableInfo = appendText(zTableInfo, zTable, '"');
zTableInfo = appendText(zTableInfo, ");", 0); zTableInfo = appendText(zTableInfo, ");", 0);
rc = sqlite3_prepare(p->db, zTableInfo, -1, &pTableInfo, 0); rc = sqlite3_prepare_v2(p->db, zTableInfo, -1, &pTableInfo, 0);
free(zTableInfo); free(zTableInfo);
if( rc!=SQLITE_OK || !pTableInfo ){ if( rc!=SQLITE_OK || !pTableInfo ){
return 1; return 1;
@ -1542,6 +1569,7 @@ static int run_schema_dump_query(
static char zHelp[] = static char zHelp[] =
".backup ?DB? FILE Backup DB (default \"main\") to FILE\n" ".backup ?DB? FILE Backup DB (default \"main\") to FILE\n"
".bail ON|OFF Stop after hitting an error. Default OFF\n" ".bail ON|OFF Stop after hitting an error. Default OFF\n"
".clone NEWDB Clone data into NEWDB from the existing database\n"
".databases List names and files of attached databases\n" ".databases List names and files of attached databases\n"
".dump ?TABLE? ... Dump the database in an SQL text format\n" ".dump ?TABLE? ... Dump the database in an SQL text format\n"
" If TABLE specified, only dump tables matching\n" " If TABLE specified, only dump tables matching\n"
@ -1581,6 +1609,7 @@ static char zHelp[] =
".quit Exit this program\n" ".quit Exit this program\n"
".read FILENAME Execute SQL in FILENAME\n" ".read FILENAME Execute SQL in FILENAME\n"
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n" ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE\n"
".save FILE Write in-memory database into FILE\n"
".schema ?TABLE? Show the CREATE statements\n" ".schema ?TABLE? Show the CREATE statements\n"
" If TABLE specified, only show tables matching\n" " If TABLE specified, only show tables matching\n"
" LIKE pattern TABLE.\n" " LIKE pattern TABLE.\n"
@ -1836,7 +1865,7 @@ static void csv_append_char(CSVReader *p, int c){
** + Report syntax errors on stderr ** + Report syntax errors on stderr
*/ */
static char *csv_read_one_field(CSVReader *p){ static char *csv_read_one_field(CSVReader *p){
int c, pc; int c, pc, ppc;
int cSep = p->cSeparator; int cSep = p->cSeparator;
p->n = 0; p->n = 0;
c = fgetc(p->in); c = fgetc(p->in);
@ -1847,7 +1876,7 @@ static char *csv_read_one_field(CSVReader *p){
if( c=='"' ){ if( c=='"' ){
int startLine = p->nLine; int startLine = p->nLine;
int cQuote = c; int cQuote = c;
pc = 0; pc = ppc = 0;
while( 1 ){ while( 1 ){
c = fgetc(p->in); c = fgetc(p->in);
if( c=='\n' ) p->nLine++; if( c=='\n' ) p->nLine++;
@ -1859,7 +1888,7 @@ static char *csv_read_one_field(CSVReader *p){
} }
if( (c==cSep && pc==cQuote) if( (c==cSep && pc==cQuote)
|| (c=='\n' && pc==cQuote) || (c=='\n' && pc==cQuote)
|| (c=='\n' && pc=='\r' && p->n>=2 && p->z[p->n-2]==cQuote) || (c=='\n' && pc=='\r' && ppc==cQuote)
|| (c==EOF && pc==cQuote) || (c==EOF && pc==cQuote)
){ ){
do{ p->n--; }while( p->z[p->n]!=cQuote ); do{ p->n--; }while( p->z[p->n]!=cQuote );
@ -1877,6 +1906,7 @@ static char *csv_read_one_field(CSVReader *p){
break; break;
} }
csv_append_char(p, c); csv_append_char(p, c);
ppc = pc;
pc = c; pc = c;
} }
}else{ }else{
@ -1886,7 +1916,7 @@ static char *csv_read_one_field(CSVReader *p){
} }
if( c=='\n' ){ if( c=='\n' ){
p->nLine++; p->nLine++;
if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--; if( p->n>0 && p->z[p->n-1]=='\r' ) p->n--;
} }
p->cTerm = c; p->cTerm = c;
} }
@ -1894,6 +1924,219 @@ static char *csv_read_one_field(CSVReader *p){
return p->z; return p->z;
} }
/*
** Try to transfer data for table zTable. If an error is seen while
** moving forward, try to go backwards. The backwards movement won't
** work for WITHOUT ROWID tables.
*/
static void tryToCloneData(
struct callback_data *p,
sqlite3 *newDb,
const char *zTable
){
sqlite3_stmt *pQuery = 0;
sqlite3_stmt *pInsert = 0;
char *zQuery = 0;
char *zInsert = 0;
int rc;
int i, j, n;
int nTable = (int)strlen(zTable);
int k = 0;
int cnt = 0;
const int spinRate = 10000;
zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
fprintf(stderr, "Error %d: %s on [%s]\n",
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
zQuery);
goto end_data_xfer;
}
n = sqlite3_column_count(pQuery);
zInsert = sqlite3_malloc(200 + nTable + n*3);
if( zInsert==0 ){
fprintf(stderr, "out of memory\n");
goto end_data_xfer;
}
sqlite3_snprintf(200+nTable,zInsert,
"INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
i = (int)strlen(zInsert);
for(j=1; j<n; j++){
memcpy(zInsert+i, ",?", 2);
i += 2;
}
memcpy(zInsert+i, ");", 3);
rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
if( rc ){
fprintf(stderr, "Error %d: %s on [%s]\n",
sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb),
zQuery);
goto end_data_xfer;
}
for(k=0; k<2; k++){
while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
for(i=0; i<n; i++){
switch( sqlite3_column_type(pQuery, i) ){
case SQLITE_NULL: {
sqlite3_bind_null(pInsert, i+1);
break;
}
case SQLITE_INTEGER: {
sqlite3_bind_int64(pInsert, i+1, sqlite3_column_int64(pQuery,i));
break;
}
case SQLITE_FLOAT: {
sqlite3_bind_double(pInsert, i+1, sqlite3_column_double(pQuery,i));
break;
}
case SQLITE_TEXT: {
sqlite3_bind_text(pInsert, i+1,
(const char*)sqlite3_column_text(pQuery,i),
-1, SQLITE_STATIC);
break;
}
case SQLITE_BLOB: {
sqlite3_bind_blob(pInsert, i+1, sqlite3_column_blob(pQuery,i),
sqlite3_column_bytes(pQuery,i),
SQLITE_STATIC);
break;
}
}
} /* End for */
rc = sqlite3_step(pInsert);
if( rc!=SQLITE_OK && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
fprintf(stderr, "Error %d: %s\n", sqlite3_extended_errcode(newDb),
sqlite3_errmsg(newDb));
}
sqlite3_reset(pInsert);
cnt++;
if( (cnt%spinRate)==0 ){
printf("%c\b", "|/-\\"[(cnt/spinRate)%4]);
fflush(stdout);
}
} /* End while */
if( rc==SQLITE_DONE ) break;
sqlite3_finalize(pQuery);
sqlite3_free(zQuery);
zQuery = sqlite3_mprintf("SELECT * FROM \"%w\" ORDER BY rowid DESC;",
zTable);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
fprintf(stderr, "Warning: cannot step \"%s\" backwards", zTable);
break;
}
} /* End for(k=0...) */
end_data_xfer:
sqlite3_finalize(pQuery);
sqlite3_finalize(pInsert);
sqlite3_free(zQuery);
sqlite3_free(zInsert);
}
/*
** Try to transfer all rows of the schema that match zWhere. For
** each row, invoke xForEach() on the object defined by that row.
** If an error is encountered while moving forward through the
** sqlite_master table, try again moving backwards.
*/
static void tryToCloneSchema(
struct callback_data *p,
sqlite3 *newDb,
const char *zWhere,
void (*xForEach)(struct callback_data*,sqlite3*,const char*)
){
sqlite3_stmt *pQuery = 0;
char *zQuery = 0;
int rc;
const unsigned char *zName;
const unsigned char *zSql;
char *zErrMsg = 0;
zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
" WHERE %s", zWhere);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
fprintf(stderr, "Error: (%d) %s on [%s]\n",
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
zQuery);
goto end_schema_xfer;
}
while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
zName = sqlite3_column_text(pQuery, 0);
zSql = sqlite3_column_text(pQuery, 1);
printf("%s... ", zName); fflush(stdout);
sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
if( zErrMsg ){
fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
sqlite3_free(zErrMsg);
zErrMsg = 0;
}
if( xForEach ){
xForEach(p, newDb, (const char*)zName);
}
printf("done\n");
}
if( rc!=SQLITE_DONE ){
sqlite3_finalize(pQuery);
sqlite3_free(zQuery);
zQuery = sqlite3_mprintf("SELECT name, sql FROM sqlite_master"
" WHERE %s ORDER BY rowid DESC", zWhere);
rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
if( rc ){
fprintf(stderr, "Error: (%d) %s on [%s]\n",
sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
zQuery);
goto end_schema_xfer;
}
while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
zName = sqlite3_column_text(pQuery, 0);
zSql = sqlite3_column_text(pQuery, 1);
printf("%s... ", zName); fflush(stdout);
sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
if( zErrMsg ){
fprintf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
sqlite3_free(zErrMsg);
zErrMsg = 0;
}
if( xForEach ){
xForEach(p, newDb, (const char*)zName);
}
printf("done\n");
}
}
end_schema_xfer:
sqlite3_finalize(pQuery);
sqlite3_free(zQuery);
}
/*
** Open a new database file named "zNewDb". Try to recover as much information
** as possible out of the main database (which might be corrupt) and write it
** into zNewDb.
*/
static void tryToClone(struct callback_data *p, const char *zNewDb){
int rc;
sqlite3 *newDb = 0;
if( access(zNewDb,0)==0 ){
fprintf(stderr, "File \"%s\" already exists.\n", zNewDb);
return;
}
rc = sqlite3_open(zNewDb, &newDb);
if( rc ){
fprintf(stderr, "Cannot create output database: %s\n",
sqlite3_errmsg(newDb));
}else{
sqlite3_exec(newDb, "BEGIN EXCLUSIVE;", 0, 0, 0);
tryToCloneSchema(p, newDb, "type='table'", tryToCloneData);
tryToCloneSchema(p, newDb, "type!='table'", 0);
sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
}
sqlite3_close(newDb);
}
/* /*
** If an input line begins with "." then invoke this routine to ** If an input line begins with "." then invoke this routine to
** process that line. ** process that line.
@ -1936,7 +2179,9 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( nArg==0 ) return 0; /* no tokens, no error */ if( nArg==0 ) return 0; /* no tokens, no error */
n = strlen30(azArg[0]); n = strlen30(azArg[0]);
c = azArg[0][0]; c = azArg[0][0];
if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){ if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
|| (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
){
const char *zDestFile = 0; const char *zDestFile = 0;
const char *zDb = 0; const char *zDb = 0;
sqlite3 *pDest; sqlite3 *pDest;
@ -2001,6 +2246,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
test_breakpoint(); test_breakpoint();
}else }else
if( c=='c' && strncmp(azArg[0], "clone", n)==0 && nArg>1 && nArg<3 ){
tryToClone(p, azArg[1]);
}else
if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){ if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
struct callback_data data; struct callback_data data;
char *zErrMsg = 0; char *zErrMsg = 0;
@ -2073,6 +2322,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
p->echoOn = booleanValue(azArg[1]); p->echoOn = booleanValue(azArg[1]);
}else }else
if( c=='e' && strncmp(azArg[0], "eqp", n)==0 && nArg>1 && nArg<3 ){
p->autoEQP = booleanValue(azArg[1]);
}else
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){ if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc); if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
rc = 2; rc = 2;
@ -2173,7 +2426,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
return 1; return 1;
} }
nByte = strlen30(zSql); nByte = strlen30(zSql);
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){ if( rc && sqlite3_strglob("no such table: *", sqlite3_errmsg(db))==0 ){
char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable); char *zCreate = sqlite3_mprintf("CREATE TABLE %s", zTable);
char cSep = '('; char cSep = '(';
@ -2199,7 +2452,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
xCloser(sCsv.in); xCloser(sCsv.in);
return 1; return 1;
} }
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
} }
sqlite3_free(zSql); sqlite3_free(zSql);
if( rc ){ if( rc ){
@ -2226,7 +2479,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
} }
zSql[j++] = ')'; zSql[j++] = ')';
zSql[j] = 0; zSql[j] = 0;
rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
sqlite3_free(zSql); sqlite3_free(zSql);
if( rc ){ if( rc ){
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db)); fprintf(stderr, "Error: %s\n", sqlite3_errmsg(db));
@ -2645,6 +2898,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){ if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
int i; int i;
fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off"); fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off"); fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off"); fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]); fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
@ -3037,7 +3291,10 @@ static int process_input(struct callback_data *p, FILE *in){
seenInterrupt = 0; seenInterrupt = 0;
} }
lineno++; lineno++;
if( nSql==0 && _all_whitespace(zLine) ) continue; if( nSql==0 && _all_whitespace(zLine) ){
if( p->echoOn ) printf("%s\n", zLine);
continue;
}
if( zLine && zLine[0]=='.' && nSql==0 ){ if( zLine && zLine[0]=='.' && nSql==0 ){
if( p->echoOn ) printf("%s\n", zLine); if( p->echoOn ) printf("%s\n", zLine);
rc = do_meta_command(zLine, p); rc = do_meta_command(zLine, p);
@ -3099,6 +3356,7 @@ static int process_input(struct callback_data *p, FILE *in){
} }
nSql = 0; nSql = 0;
}else if( nSql && _all_whitespace(zSql) ){ }else if( nSql && _all_whitespace(zSql) ){
if( p->echoOn ) printf("%s\n", zSql);
nSql = 0; nSql = 0;
} }
} }
@ -3276,6 +3534,26 @@ static void main_init(struct callback_data *data) {
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
} }
/*
** Output text to the console in a font that attracts extra attention.
*/
#ifdef _WIN32
static void printBold(const char *zText){
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO defaultScreenInfo;
GetConsoleScreenBufferInfo(out, &defaultScreenInfo);
SetConsoleTextAttribute(out,
FOREGROUND_RED|FOREGROUND_INTENSITY
);
printf("%s", zText);
SetConsoleTextAttribute(out, defaultScreenInfo.wAttributes);
}
#else
static void printBold(const char *zText){
printf("\033[1m%s\033[0m", zText);
}
#endif
/* /*
** Get the argument to an --option. Throw an error and die if no argument ** Get the argument to an --option. Throw an error and die if no argument
** is available. ** is available.
@ -3296,12 +3574,15 @@ int main(int argc, char **argv){
char *zFirstCmd = 0; char *zFirstCmd = 0;
int i; int i;
int rc = 0; int rc = 0;
int warnInmemoryDb = 0;
#if USE_SYSTEM_SQLITE+0!=1
if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
sqlite3_sourceid(), SQLITE_SOURCE_ID); sqlite3_sourceid(), SQLITE_SOURCE_ID);
exit(1); exit(1);
} }
#endif
Argv0 = argv[0]; Argv0 = argv[0];
main_init(&data); main_init(&data);
stdin_is_interactive = isatty(0); stdin_is_interactive = isatty(0);
@ -3390,9 +3671,15 @@ int main(int argc, char **argv){
if( data.zDbFilename==0 ){ if( data.zDbFilename==0 ){
#ifndef SQLITE_OMIT_MEMORYDB #ifndef SQLITE_OMIT_MEMORYDB
data.zDbFilename = ":memory:"; data.zDbFilename = ":memory:";
warnInmemoryDb = argc==1;
#else #else
fprintf(stderr,"%s: Error: no database filename specified\n", Argv0); fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
return 1; return 1;
#endif
#ifdef SQLITE_SHELL_DBNAME_PROC
{ extern void SQLITE_SHELL_DBNAME_PROC(const char**);
SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
warnInmemoryDb = 0; }
#endif #endif
} }
data.out = stdout; data.out = stdout;
@ -3449,6 +3736,8 @@ int main(int argc, char **argv){
data.showHeader = 0; data.showHeader = 0;
}else if( strcmp(z,"-echo")==0 ){ }else if( strcmp(z,"-echo")==0 ){
data.echoOn = 1; data.echoOn = 1;
}else if( strcmp(z,"-eqp")==0 ){
data.autoEQP = 1;
}else if( strcmp(z,"-stats")==0 ){ }else if( strcmp(z,"-stats")==0 ){
data.statsOn = 1; data.statsOn = 1;
}else if( strcmp(z,"-bail")==0 ){ }else if( strcmp(z,"-bail")==0 ){
@ -3526,10 +3815,15 @@ int main(int argc, char **argv){
int nHistory; int nHistory;
printf( printf(
"SQLite version %s %.19s\n" /*extra-version-info*/ "SQLite version %s %.19s\n" /*extra-version-info*/
"Enter \".help\" for instructions\n" "Enter \".help\" for usage hints.\n",
"Enter SQL statements terminated with a \";\"\n",
sqlite3_libversion(), sqlite3_sourceid() sqlite3_libversion(), sqlite3_sourceid()
); );
if( warnInmemoryDb ){
printf("Connected to a ");
printBold("transient in-memory database");
printf(".\nUse \".open FILENAME\" to reopen on a "
"persistent database.\n");
}
zHome = find_home_dir(); zHome = find_home_dir();
if( zHome ){ if( zHome ){
nHistory = strlen30(zHome) + 20; nHistory = strlen30(zHome) + 20;
@ -3537,7 +3831,7 @@ int main(int argc, char **argv){
sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome);
} }
} }
#if defined(HAVE_READLINE) && HAVE_READLINE==1 #if defined(HAVE_READLINE)
if( zHistory ) read_history(zHistory); if( zHistory ) read_history(zHistory);
#endif #endif
rc = process_input(&data, 0); rc = process_input(&data, 0);

File diff suppressed because it is too large Load Diff

View File

@ -107,9 +107,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.8.2" #define SQLITE_VERSION "3.8.4.1"
#define SQLITE_VERSION_NUMBER 3008002 #define SQLITE_VERSION_NUMBER 3008004
#define SQLITE_SOURCE_ID "2013-12-06 14:53:30 27392118af4c38c5203a04b8013e1afdb1cebd0d" #define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers
@ -491,6 +491,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
#define SQLITE_READONLY_DBMOVED (SQLITE_READONLY | (4<<8))
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8)) #define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8)) #define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
@ -558,7 +559,8 @@ SQLITE_API int sqlite3_exec(
** after reboot following a crash or power loss, the only bytes in a ** after reboot following a crash or power loss, the only bytes in a
** file that were written at the application level might have changed ** file that were written at the application level might have changed
** and that adjacent bytes, even bytes within the same sector are ** and that adjacent bytes, even bytes within the same sector are
** guaranteed to be unchanged. ** guaranteed to be unchanged. The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
** flag indicate that a file cannot be deleted when open.
*/ */
#define SQLITE_IOCAP_ATOMIC 0x00000001 #define SQLITE_IOCAP_ATOMIC 0x00000001
#define SQLITE_IOCAP_ATOMIC512 0x00000002 #define SQLITE_IOCAP_ATOMIC512 0x00000002
@ -789,15 +791,29 @@ struct sqlite3_io_methods {
** additional information. ** additional information.
** **
** <li>[[SQLITE_FCNTL_SYNC_OMITTED]] ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]]
** ^(The [SQLITE_FCNTL_SYNC_OMITTED] opcode is generated internally by ** No longer in use.
** SQLite and sent to all VFSes in place of a call to the xSync method **
** when the database connection has [PRAGMA synchronous] set to OFF.)^ ** <li>[[SQLITE_FCNTL_SYNC]]
** Some specialized VFSes need this signal in order to operate correctly ** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and
** when [PRAGMA synchronous | PRAGMA synchronous=OFF] is set, but most ** sent to the VFS immediately before the xSync method is invoked on a
** VFSes do not need this signal and should silently ignore this opcode. ** database file descriptor. Or, if the xSync method is not invoked
** Applications should not call [sqlite3_file_control()] with this ** because the user has configured SQLite with
** opcode as doing so may disrupt the operation of the specialized VFSes ** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place
** that do require it. ** of the xSync method. In most cases, the pointer argument passed with
** this file-control is NULL. However, if the database file is being synced
** as part of a multi-database commit, the argument points to a nul-terminated
** string containing the transactions master-journal file name. VFSes that
** do not need this signal should silently ignore this opcode. Applications
** should not call [sqlite3_file_control()] with this opcode as doing so may
** disrupt the operation of the specialized VFSes that do require it.
**
** <li>[[SQLITE_FCNTL_COMMIT_PHASETWO]]
** The [SQLITE_FCNTL_COMMIT_PHASETWO] opcode is generated internally by SQLite
** and sent to the VFS after a transaction has been committed immediately
** but before the database is unlocked. VFSes that do not need this signal
** should silently ignore this opcode. Applications should not call
** [sqlite3_file_control()] with this opcode as doing so may disrupt the
** operation of the specialized VFSes that do require it.
** **
** <li>[[SQLITE_FCNTL_WIN32_AV_RETRY]] ** <li>[[SQLITE_FCNTL_WIN32_AV_RETRY]]
** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
@ -921,6 +937,12 @@ struct sqlite3_io_methods {
** SQLite stack may generate instances of this file control if ** SQLite stack may generate instances of this file control if
** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled. ** the [SQLITE_USE_FCNTL_TRACE] compile-time option is enabled.
** **
** <li>[[SQLITE_FCNTL_HAS_MOVED]]
** The [SQLITE_FCNTL_HAS_MOVED] file control interprets its argument as a
** pointer to an integer and it writes a boolean into that integer depending
** on whether or not the file has been renamed, moved, or deleted since it
** was first opened.
**
** </ul> ** </ul>
*/ */
#define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_LOCKSTATE 1
@ -941,6 +963,9 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_TEMPFILENAME 16 #define SQLITE_FCNTL_TEMPFILENAME 16
#define SQLITE_FCNTL_MMAP_SIZE 18 #define SQLITE_FCNTL_MMAP_SIZE 18
#define SQLITE_FCNTL_TRACE 19 #define SQLITE_FCNTL_TRACE 19
#define SQLITE_FCNTL_HAS_MOVED 20
#define SQLITE_FCNTL_SYNC 21
#define SQLITE_FCNTL_COMMIT_PHASETWO 22
/* /*
** CAPI3REF: Mutex Handle ** CAPI3REF: Mutex Handle
@ -2375,11 +2400,13 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
** applications to access the same PRNG for other purposes. ** applications to access the same PRNG for other purposes.
** **
** ^A call to this routine stores N bytes of randomness into buffer P. ** ^A call to this routine stores N bytes of randomness into buffer P.
** ^If N is less than one, then P can be a NULL pointer.
** **
** ^The first time this routine is invoked (either internally or by ** ^If this routine has not been previously called or if the previous
** the application) the PRNG is seeded using randomness obtained ** call had N less than one, then the PRNG is seeded using randomness
** from the xRandomness method of the default [sqlite3_vfs] object. ** obtained from the xRandomness method of the default [sqlite3_vfs] object.
** ^On all subsequent invocations, the pseudo-randomness is generated ** ^If the previous call to this routine had an N of 1 or more then
** the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness ** internally and without recourse to the [sqlite3_vfs] xRandomness
** method. ** method.
*/ */
@ -2539,6 +2566,7 @@ SQLITE_API int sqlite3_set_authorizer(
#define SQLITE_FUNCTION 31 /* NULL Function Name */ #define SQLITE_FUNCTION 31 /* NULL Function Name */
#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */ #define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
#define SQLITE_COPY 0 /* No longer used */ #define SQLITE_COPY 0 /* No longer used */
#define SQLITE_RECURSIVE 33 /* NULL NULL */
/* /*
** CAPI3REF: Tracing And Profiling Functions ** CAPI3REF: Tracing And Profiling Functions
@ -3957,15 +3985,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
** **
** ^The fourth parameter, eTextRep, specifies what ** ^The fourth parameter, eTextRep, specifies what
** [SQLITE_UTF8 | text encoding] this SQL function prefers for ** [SQLITE_UTF8 | text encoding] this SQL function prefers for
** its parameters. Every SQL function implementation must be able to work ** its parameters. The application should set this parameter to
** with UTF-8, UTF-16le, or UTF-16be. But some implementations may be ** [SQLITE_UTF16LE] if the function implementation invokes
** more efficient with one encoding than another. ^An application may ** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the
** invoke sqlite3_create_function() or sqlite3_create_function16() multiple ** implementation invokes [sqlite3_value_text16be()] on an input, or
** times with the same function but with different values of eTextRep. ** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8]
** otherwise. ^The same SQL function may be registered multiple times using
** different preferred text encodings, with different implementations for
** each encoding.
** ^When multiple implementations of the same function are available, SQLite ** ^When multiple implementations of the same function are available, SQLite
** will pick the one that involves the least amount of data conversion. ** will pick the one that involves the least amount of data conversion.
** If there is only a single implementation which does not care what text **
** encoding is used, then the fourth argument should be [SQLITE_ANY]. ** ^The fourth parameter may optionally be ORed with [SQLITE_DETERMINISTIC]
** to signal that the function will always return the same result given
** the same inputs within a single SQL statement. Most SQL functions are
** deterministic. The built-in [random()] SQL function is an example of a
** function that is not deterministic. The SQLite query planner is able to
** perform additional optimizations on deterministic functions, so use
** of the [SQLITE_DETERMINISTIC] flag is recommended where possible.
** **
** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** ^(The fifth parameter is an arbitrary pointer. The implementation of the
** function can gain access to this pointer using [sqlite3_user_data()].)^ ** function can gain access to this pointer using [sqlite3_user_data()].)^
@ -4051,9 +4088,19 @@ SQLITE_API int sqlite3_create_function_v2(
#define SQLITE_UTF16LE 2 #define SQLITE_UTF16LE 2
#define SQLITE_UTF16BE 3 #define SQLITE_UTF16BE 3
#define SQLITE_UTF16 4 /* Use native byte order */ #define SQLITE_UTF16 4 /* Use native byte order */
#define SQLITE_ANY 5 /* sqlite3_create_function only */ #define SQLITE_ANY 5 /* Deprecated */
#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ #define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */
/*
** CAPI3REF: Function Flags
**
** These constants may be ORed together with the
** [SQLITE_UTF8 | preferred text encoding] as the fourth argument
** to [sqlite3_create_function()], [sqlite3_create_function16()], or
** [sqlite3_create_function_v2()].
*/
#define SQLITE_DETERMINISTIC 0x800
/* /*
** CAPI3REF: Deprecated Functions ** CAPI3REF: Deprecated Functions
** DEPRECATED ** DEPRECATED
@ -6075,7 +6122,8 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19
#define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_NEVER_CORRUPT 20
#define SQLITE_TESTCTRL_LAST 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21
#define SQLITE_TESTCTRL_LAST 21
/* /*
** CAPI3REF: SQLite Runtime Status ** CAPI3REF: SQLite Runtime Status