aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2016-11-11 18:45:55 +0000
committerdan <dan@noemail.net>2016-11-11 18:45:55 +0000
commit04cd7aa373d0218a766aa24987a99d16bcdcbac2 (patch)
treef44e1af007c5bd8eb814cac3bec1bea0476ec781 /src
parent9af90b7231660b5c5670e41ad58c755d95d0fbaa (diff)
parent4a5bad572ae669f2c6da3299303840bf3852d5b3 (diff)
downloadsqlite-04cd7aa373d0218a766aa24987a99d16bcdcbac2.tar.gz
sqlite-04cd7aa373d0218a766aa24987a99d16bcdcbac2.zip
Merge trunk with this branch.
FossilOrigin-Name: dd62d2de6eb12dc1902d6df050c395b1dcac01b4
Diffstat (limited to 'src')
-rw-r--r--src/attach.c1
-rw-r--r--src/pager.c5
-rw-r--r--src/resolve.c17
-rw-r--r--src/shell.c81
-rw-r--r--src/wal.c2
5 files changed, 65 insertions, 41 deletions
diff --git a/src/attach.c b/src/attach.c
index 507b9c123..4fe97bace 100644
--- a/src/attach.c
+++ b/src/attach.c
@@ -325,6 +325,7 @@ static void codeAttach(
sqlite3* db = pParse->db;
int regArgs;
+ if( pParse->nErr ) goto attach_end;
memset(&sName, 0, sizeof(NameContext));
sName.pParse = pParse;
diff --git a/src/pager.c b/src/pager.c
index 71c4acdb9..04ce19547 100644
--- a/src/pager.c
+++ b/src/pager.c
@@ -4033,7 +4033,10 @@ int sqlite3PagerClose(Pager *pPager, sqlite3 *db){
/* pPager->errCode = 0; */
pPager->exclusiveMode = 0;
#ifndef SQLITE_OMIT_WAL
- sqlite3WalClose(pPager->pWal,db,pPager->ckptSyncFlags,pPager->pageSize,pTmp);
+ assert( db || pPager->pWal==0 );
+ sqlite3WalClose(pPager->pWal, db, pPager->ckptSyncFlags, pPager->pageSize,
+ (db && (db->flags & SQLITE_NoCkptOnClose) ? 0 : pTmp)
+ );
pPager->pWal = 0;
#endif
pager_reset(pPager);
diff --git a/src/resolve.c b/src/resolve.c
index f464b657f..dac73e5fa 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -400,6 +400,10 @@ static int lookupName(
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
return WRC_Abort;
}
+ if( sqlite3ExprVectorSize(pOrig)!=1 ){
+ sqlite3ErrorMsg(pParse, "row value misused");
+ return WRC_Abort;
+ }
resolveAlias(pParse, pEList, j, pExpr, "", nSubquery);
cnt = 1;
pMatch = 0;
@@ -776,6 +780,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
notValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr);
break;
}
+ case TK_BETWEEN:
case TK_EQ:
case TK_NE:
case TK_LT:
@@ -786,10 +791,17 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
case TK_ISNOT: {
int nLeft, nRight;
if( pParse->db->mallocFailed ) break;
- assert( pExpr->pRight!=0 );
assert( pExpr->pLeft!=0 );
nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
- nRight = sqlite3ExprVectorSize(pExpr->pRight);
+ if( pExpr->op==TK_BETWEEN ){
+ nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr);
+ if( nRight==nLeft ){
+ nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr);
+ }
+ }else{
+ assert( pExpr->pRight!=0 );
+ nRight = sqlite3ExprVectorSize(pExpr->pRight);
+ }
if( nLeft!=nRight ){
testcase( pExpr->op==TK_EQ );
testcase( pExpr->op==TK_NE );
@@ -799,6 +811,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_GE );
testcase( pExpr->op==TK_IS );
testcase( pExpr->op==TK_ISNOT );
+ testcase( pExpr->op==TK_BETWEEN );
sqlite3ErrorMsg(pParse, "row value misused");
}
break;
diff --git a/src/shell.c b/src/shell.c
index 6a7bee142..aaba1080e 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -1216,10 +1216,10 @@ static int shell_callback(
raw_printf(p->out," VALUES(");
}else if( p->cnt==0 && p->showHeader ){
for(i=0; i<nArg; i++){
- if( i>0 ) utf8_printf(p->out, ",");
+ if( i>0 ) raw_printf(p->out, ",");
output_quoted_string(p->out, azCol[i]);
}
- utf8_printf(p->out,"\n");
+ raw_printf(p->out,"\n");
}
p->cnt++;
for(i=0; i<nArg; i++){
@@ -3916,12 +3916,12 @@ static int do_meta_command(char *zLine, ShellState *p){
utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
}else{
utf8_printf(stdout, "%s;\n", zSql);
- utf8_printf(stdout,
+ raw_printf(stdout,
"WARNING: writing to an imposter table will corrupt the index!\n"
);
}
}else{
- utf8_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
+ raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
rc = 1;
}
sqlite3_free(zSql);
@@ -4782,7 +4782,7 @@ static int do_meta_command(char *zLine, ShellState *p){
output_reset(p);
p->out = output_file_open("testcase-out.txt");
if( p->out==0 ){
- utf8_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
+ raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
}
if( nArg>=2 ){
sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
@@ -5177,6 +5177,42 @@ static int line_is_complete(char *zSql, int nSql){
}
/*
+** Run a single line of SQL
+*/
+static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
+ int rc;
+ char *zErrMsg = 0;
+
+ open_db(p, 0);
+ if( p->backslashOn ) resolve_backslashes(zSql);
+ BEGIN_TIMER;
+ rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
+ END_TIMER;
+ if( rc || zErrMsg ){
+ char zPrefix[100];
+ if( in!=0 || !stdin_is_interactive ){
+ sqlite3_snprintf(sizeof(zPrefix), zPrefix,
+ "Error: near line %d:", startline);
+ }else{
+ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
+ }
+ if( zErrMsg!=0 ){
+ utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
+ sqlite3_free(zErrMsg);
+ zErrMsg = 0;
+ }else{
+ utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
+ }
+ return 1;
+ }else if( p->countChanges ){
+ raw_printf(p->out, "changes: %3d total_changes: %d\n",
+ sqlite3_changes(p->db), sqlite3_total_changes(p->db));
+ }
+ return 0;
+}
+
+
+/*
** Read input from *in and process it. If *in==0 then input
** is interactive - the user is typing it it. Otherwise, input
** is coming from a file or device. A prompt is issued and history
@@ -5192,7 +5228,6 @@ static int process_input(ShellState *p, FILE *in){
int nSql = 0; /* Bytes of zSql[] used */
int nAlloc = 0; /* Allocated zSql[] space */
int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */
- char *zErrMsg; /* Error message returned */
int rc; /* Error code */
int errCnt = 0; /* Number of errors seen */
int lineno = 0; /* Current line number */
@@ -5252,32 +5287,7 @@ static int process_input(ShellState *p, FILE *in){
}
if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
&& sqlite3_complete(zSql) ){
- p->cnt = 0;
- open_db(p, 0);
- if( p->backslashOn ) resolve_backslashes(zSql);
- BEGIN_TIMER;
- rc = shell_exec(p->db, zSql, shell_callback, p, &zErrMsg);
- END_TIMER;
- if( rc || zErrMsg ){
- char zPrefix[100];
- if( in!=0 || !stdin_is_interactive ){
- sqlite3_snprintf(sizeof(zPrefix), zPrefix,
- "Error: near line %d:", startline);
- }else{
- sqlite3_snprintf(sizeof(zPrefix), zPrefix, "Error:");
- }
- if( zErrMsg!=0 ){
- utf8_printf(stderr, "%s %s\n", zPrefix, zErrMsg);
- sqlite3_free(zErrMsg);
- zErrMsg = 0;
- }else{
- utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
- }
- errCnt++;
- }else if( p->countChanges ){
- raw_printf(p->out, "changes: %3d total_changes: %d\n",
- sqlite3_changes(p->db), sqlite3_total_changes(p->db));
- }
+ errCnt += runOneSqlLine(p, zSql, in, startline);
nSql = 0;
if( p->outCount ){
output_reset(p);
@@ -5288,11 +5298,8 @@ static int process_input(ShellState *p, FILE *in){
nSql = 0;
}
}
- if( nSql ){
- if( !_all_whitespace(zSql) ){
- utf8_printf(stderr, "Error: incomplete SQL: %s\n", zSql);
- errCnt++;
- }
+ if( nSql && !_all_whitespace(zSql) ){
+ runOneSqlLine(p, zSql, in, startline);
}
free(zSql);
free(zLine);
diff --git a/src/wal.c b/src/wal.c
index 50b95e416..d71ee81a5 100644
--- a/src/wal.c
+++ b/src/wal.c
@@ -1943,7 +1943,7 @@ int sqlite3WalClose(
**
** The EXCLUSIVE lock is not released before returning.
*/
- if( (db->flags & SQLITE_NoCkptOnClose)==0
+ if( zBuf!=0
&& SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE))
){
if( pWal->exclusiveMode==WAL_NORMAL_MODE ){