diff options
author | dan <dan@noemail.net> | 2016-11-11 18:45:55 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2016-11-11 18:45:55 +0000 |
commit | 04cd7aa373d0218a766aa24987a99d16bcdcbac2 (patch) | |
tree | f44e1af007c5bd8eb814cac3bec1bea0476ec781 /src | |
parent | 9af90b7231660b5c5670e41ad58c755d95d0fbaa (diff) | |
parent | 4a5bad572ae669f2c6da3299303840bf3852d5b3 (diff) | |
download | sqlite-04cd7aa373d0218a766aa24987a99d16bcdcbac2.tar.gz sqlite-04cd7aa373d0218a766aa24987a99d16bcdcbac2.zip |
Merge trunk with this branch.
FossilOrigin-Name: dd62d2de6eb12dc1902d6df050c395b1dcac01b4
Diffstat (limited to 'src')
-rw-r--r-- | src/attach.c | 1 | ||||
-rw-r--r-- | src/pager.c | 5 | ||||
-rw-r--r-- | src/resolve.c | 17 | ||||
-rw-r--r-- | src/shell.c | 81 | ||||
-rw-r--r-- | src/wal.c | 2 |
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); @@ -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 ){ |