Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Always invoke the profile callback even if the statement does not run to completion. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
202479aa0a62067343e724487960b8a0 |
User & Date: | drh 2015-07-14 14:48:50.217 |
Context
2015-07-14
| ||
17:18 | Fix some harmless compiler warnings. (check-in: 3de030c904 user: mistachkin tags: trunk) | |
15:39 | Merge trunk changes, including the addition of FTS5 and pcache1 performance enhancements. (check-in: db4cbefb86 user: drh tags: sessions) | |
14:48 | Always invoke the profile callback even if the statement does not run to completion. (check-in: 202479aa0a user: drh tags: trunk) | |
00:36 | Refine cleaning of FTS5 files by Makefile targets. (check-in: e548d77b3c user: mistachkin tags: trunk) | |
Changes
Changes to src/vdbeapi.c.
︙ | ︙ | |||
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement"); return 1; }else{ return vdbeSafety(p); } } /* ** The following routine destroys a virtual machine that is created by ** the sqlite3_compile() routine. The integer returned is an SQLITE_ ** success/failure code that describes the result of executing the virtual ** machine. ** ** This routine sets the error code and string returned by ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ int sqlite3_finalize(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL ** pointer is a harmless no-op. */ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; sqlite3_mutex_enter(db->mutex); rc = sqlite3VdbeFinalize(v); rc = sqlite3ApiExit(db, rc); sqlite3LeaveMutexAndCloseZombie(db); } return rc; } | > > > > > > > > > > > > > > > > > > > > > > > > > > | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement"); return 1; }else{ return vdbeSafety(p); } } #ifndef SQLITE_OMIT_TRACE /* ** Invoke the profile callback. This routine is only called if we already ** know that the profile callback is defined and needs to be invoked. */ static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){ sqlite3_int64 iNow; assert( p->startTime>0 ); assert( db->xProfile!=0 ); assert( db->init.busy==0 ); assert( p->zSql!=0 ); sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); db->xProfile(db->pProfileArg, p->zSql, (iNow - p->startTime)*1000000); p->startTime = 0; } /* ** The checkProfileCallback(DB,P) macro checks to see if a profile callback ** is needed, and it invokes the callback if it is needed. */ # define checkProfileCallback(DB,P) \ if( ((P)->startTime)>0 ){ invokeProfileCallback(DB,P); } #else # define checkProfileCallback(DB,P) /*no-op*/ #endif /* ** The following routine destroys a virtual machine that is created by ** the sqlite3_compile() routine. The integer returned is an SQLITE_ ** success/failure code that describes the result of executing the virtual ** machine. ** ** This routine sets the error code and string returned by ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ int sqlite3_finalize(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL ** pointer is a harmless no-op. */ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; sqlite3_mutex_enter(db->mutex); checkProfileCallback(db, v); rc = sqlite3VdbeFinalize(v); rc = sqlite3ApiExit(db, rc); sqlite3LeaveMutexAndCloseZombie(db); } return rc; } |
︙ | ︙ | |||
90 91 92 93 94 95 96 | */ int sqlite3_reset(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; | > | > | | | | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | */ int sqlite3_reset(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3 *db = v->db; sqlite3_mutex_enter(db->mutex); checkProfileCallback(db, v); rc = sqlite3VdbeReset(v); sqlite3VdbeRewind(v); assert( (rc & (db->errMask))==rc ); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); } return rc; } /* ** Set all the parameters in the compiled SQL statement to NULL. */ |
︙ | ︙ | |||
445 446 447 448 449 450 451 452 453 454 455 456 457 458 | rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry); } } } #endif return rc; } /* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. ** ** This routine implements the bulk of the logic behind the sqlite_step() ** API. The only thing omitted is the automatic recompile if a | > | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 | rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry); } } } #endif return rc; } /* ** Execute the statement pStmt, either until a row of data is ready, the ** statement is completely executed or an error occurs. ** ** This routine implements the bulk of the logic behind the sqlite_step() ** API. The only thing omitted is the automatic recompile if a |
︙ | ︙ | |||
514 515 516 517 518 519 520 | } assert( db->nVdbeWrite>0 || db->autoCommit==0 || (db->nDeferredCons==0 && db->nDeferredImmCons==0) ); #ifndef SQLITE_OMIT_TRACE | | > > | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | } assert( db->nVdbeWrite>0 || db->autoCommit==0 || (db->nDeferredCons==0 && db->nDeferredImmCons==0) ); #ifndef SQLITE_OMIT_TRACE if( db->xProfile && !db->init.busy && p->zSql ){ sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); }else{ assert( p->startTime==0 ); } #endif db->nVdbeActive++; if( p->readOnly==0 ) db->nVdbeWrite++; if( p->bIsReader ) db->nVdbeRead++; p->pc = 0; |
︙ | ︙ | |||
539 540 541 542 543 544 545 | { db->nVdbeExec++; rc = sqlite3VdbeExec(p); db->nVdbeExec--; } #ifndef SQLITE_OMIT_TRACE | | < | < < < < | 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 | { db->nVdbeExec++; rc = sqlite3VdbeExec(p); db->nVdbeExec--; } #ifndef SQLITE_OMIT_TRACE /* If the statement completed successfully, invoke the profile callback */ if( rc!=SQLITE_ROW ) checkProfileCallback(db, p); #endif if( rc==SQLITE_DONE ){ assert( p->rc==SQLITE_OK ); p->rc = doWalCallbacks(db); if( p->rc!=SQLITE_OK ){ rc = SQLITE_ERROR; |
︙ | ︙ |
Changes to test/trace.test.
︙ | ︙ | |||
164 165 166 167 168 169 170 171 172 173 174 175 176 177 | set TRACE_OUT {} execsql {SELECT * FROM t1} } {1 2 2 3 2 3} do_test trace-4.5 { set TRACE_OUT } {{SELECT * FROM t1}} catch {sqlite3_finalize $STMT} # Trigger tracing. # ifcapable trigger { do_test trace-5.1 { db eval { CREATE TRIGGER r1t1 AFTER UPDATE ON t1 BEGIN | > > > > > > > > | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | set TRACE_OUT {} execsql {SELECT * FROM t1} } {1 2 2 3 2 3} do_test trace-4.5 { set TRACE_OUT } {{SELECT * FROM t1}} catch {sqlite3_finalize $STMT} # 3.8.11: Profile output even if the statement is not run to completion. do_test trace-4.6 { set TRACE_OUT {} db eval {SELECT * FROM t1} {} {if {$a>=1} break} set TRACE_OUT } {{SELECT * FROM t1}} # Trigger tracing. # ifcapable trigger { do_test trace-5.1 { db eval { CREATE TRIGGER r1t1 AFTER UPDATE ON t1 BEGIN |
︙ | ︙ |