Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the experimental sqlite3_stmt_status() interface. (CVS 5781) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
de473efb35ffdf9a8222a70a84dfd7d3 |
User & Date: | drh 2008-10-07 23:46:38.000 |
Context
2008-10-08
| ||
17:58 | After an OP_NullRow is executed on a cursor, cause any subsequent OP_Next or OP_Prev to behave as if there were no more rows to traverse. Ticket #3424. (CVS 5782) (check-in: af679f6170 user: danielk1977 tags: trunk) | |
2008-10-07
| ||
23:46 | Add the experimental sqlite3_stmt_status() interface. (CVS 5781) (check-in: de473efb35 user: drh tags: trunk) | |
19:53 | Raise the hard upper bound on SQLITE_MAX_FUNCTION_ARG to 1000 from 100. The default upper bound is still 100, but it can now be raised as high as 1000 at compile-time. (CVS 5780) (check-in: 79df72ee83 user: drh tags: trunk) | |
Changes
Changes to src/sqlite.h.in.
︙ | ︙ | |||
26 27 28 29 30 31 32 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | ** on how SQLite interfaces are suppose to operate. ** ** The name of this file under configuration management is "sqlite.h.in". ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** ** @(#) $Id: sqlite.h.in,v 1.401 2008/10/07 23:46:38 drh Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ #include <stdarg.h> /* Needed for the definition of va_list */ /* ** Make sure we can call this stuff from C++. |
︙ | ︙ | |||
6212 6213 6214 6215 6216 6217 6218 | ** and it is possible that another thread might change the parameter ** in between the times when *pCurrent and *pHighwater are written. ** ** See also: [sqlite3_db_status()] */ SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); | < < < < < < < < < < < < < < < < < < < < < < < | 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 | ** and it is possible that another thread might change the parameter ** in between the times when *pCurrent and *pHighwater are written. ** ** See also: [sqlite3_db_status()] */ SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); /* ** CAPI3REF: Status Parameters {H17250} <H17200> ** EXPERIMENTAL ** ** These integer constants designate various run-time status parameters ** that can be returned by [sqlite3_status()]. |
︙ | ︙ | |||
6324 6325 6326 6327 6328 6329 6330 | #define SQLITE_STATUS_SCRATCH_OVERFLOW 4 #define SQLITE_STATUS_MALLOC_SIZE 5 #define SQLITE_STATUS_PARSER_STACK 6 #define SQLITE_STATUS_PAGECACHE_SIZE 7 #define SQLITE_STATUS_SCRATCH_SIZE 8 /* | > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 | #define SQLITE_STATUS_SCRATCH_OVERFLOW 4 #define SQLITE_STATUS_MALLOC_SIZE 5 #define SQLITE_STATUS_PARSER_STACK 6 #define SQLITE_STATUS_PAGECACHE_SIZE 7 #define SQLITE_STATUS_SCRATCH_SIZE 8 /* ** CAPI3REF: Database Connection Status {H17500} <S60200> ** EXPERIMENTAL ** ** This interface is used to retrieve runtime status information ** about a single [database connection]. The first argument is the ** database connection object to be interrogated. The second argument ** is the parameter to interrogate. Currently, the only allowed value ** for the second parameter is [SQLITE_DBSTATUS_LOOKASIDE_USED]. ** Additional options will likely appear in future releases of SQLite. ** ** The current value of the requested parameter is written into *pCur ** and the highest instantaneous value is written into *pHiwtr. If ** the resetFlg is true, then the highest instantaneous value is ** reset back down to the current value. ** ** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. */ SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); /* ** CAPI3REF: Status Parameters for database connections {H17520} <H17500> ** EXPERIMENTAL ** ** Status verbs for [sqlite3_db_status()]. ** ** <dl> ** <dt>SQLITE_DBSTATUS_LOOKASIDE_USED</dt> ** <dd>This parameter returns the number of lookaside memory slots currently ** checked out.</dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 /* ** CAPI3REF: Prepared Statement Status {H17550} <S60200> ** EXPERIMENTAL ** ** Each prepared statement maintains various ** [SQLITE_STMTSTATUS_SORT | counters] that measure the number ** of times it has performed specific operations. These counters can ** be used to monitor the performance characteristics of the prepared ** statements. For example, if the number of table steps greatly exceeds ** the number of table searches or result rows, that would tend to indicate ** that the prepared statement is using a full table scan rather than ** an index. ** ** This interface is used to retrieve and reset counter values from ** a [prepared statement]. The first argument is the prepared statement ** object to be interrogated. The second argument ** is an integer code for a specific [SQLITE_STMTSTATUS_SORT | counter] ** to be interrogated. ** The current value of the requested counter is returned. ** If the resetFlg is true, then the counter is reset to zero after this ** interface call returns. ** ** See also: [sqlite3_status()] and [sqlite3_db_status()]. */ SQLITE_EXPERIMENTAL int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); /* ** CAPI3REF: Status Parameters for prepared statements {H17570} <H17550> ** EXPERIMENTAL ** ** These preprocessor macros define integer codes that name counter ** values associated with the [sqlite3_stmt_status()] interface. ** The meanings of the various counters are as follows: ** ** <dl> ** <dt>SQLITE_STMTSTATUS_FULLSCAN_STEP</dt> ** <dd>This is the number of times that SQLite has stepped forward in ** a table as part of a full table scan. Large numbers for this counter ** may indicate opportunities for performance improvement through ** careful use of indices.</dd> ** ** <dt>SQLITE_STMTSTATUS_SORT</dt> ** <dd>This is the number of sort operations that have occurred. ** A non-zero value in this counter may indicate an opportunity to ** improvement performance through careful use of indices.</dd> ** ** </dl> */ #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1 #define SQLITE_STMTSTATUS_SORT 2 /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif |
Changes to src/sqliteInt.h.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Internal interface definitions for SQLite. ** ** @(#) $Id: sqliteInt.h,v 1.779 2008/10/07 23:46:38 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build |
︙ | ︙ | |||
465 466 467 468 469 470 471 472 473 474 475 476 477 478 | ** In the usually case where WSD is supported, the SQLITE_WSD and GLOBAL ** macros become no-ops and have zero performance impact. */ #ifdef SQLITE_OMIT_WSD #define SQLITE_WSD const #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v))) #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config) #else #define SQLITE_WSD #define GLOBAL(t,v) v #define sqlite3GlobalConfig sqlite3Config #endif /* | > > | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 | ** In the usually case where WSD is supported, the SQLITE_WSD and GLOBAL ** macros become no-ops and have zero performance impact. */ #ifdef SQLITE_OMIT_WSD #define SQLITE_WSD const #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v))) #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config) int sqlite3_wsd_init(int N, int J); void *sqlite3_wsd_find(void *K, int L); #else #define SQLITE_WSD #define GLOBAL(t,v) v #define sqlite3GlobalConfig sqlite3Config #endif /* |
︙ | ︙ | |||
1492 1493 1494 1495 1496 1497 1498 | Index *pIdx; /* Index used. NULL if no index */ int iTabCur; /* The VDBE cursor used to access the table */ int iIdxCur; /* The VDBE cursor used to acesss pIdx */ int brk; /* Jump here to break out of the loop */ int nxt; /* Jump here to start the next IN combination */ int cont; /* Jump here to continue with the next loop cycle */ int top; /* First instruction of interior of the loop */ | | | 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 | Index *pIdx; /* Index used. NULL if no index */ int iTabCur; /* The VDBE cursor used to access the table */ int iIdxCur; /* The VDBE cursor used to acesss pIdx */ int brk; /* Jump here to break out of the loop */ int nxt; /* Jump here to start the next IN combination */ int cont; /* Jump here to continue with the next loop cycle */ int top; /* First instruction of interior of the loop */ int op, p1, p2, p5; /* Opcode used to terminate the loop */ int nEq; /* Number of == or IN constraints on this loop */ int nIn; /* Number of IN operators constraining this loop */ struct InLoop { int iCur; /* The VDBE cursor used by this IN operator */ int topAddr; /* Top of the IN loop */ } *aInLoop; /* Information about each nested IN operator */ sqlite3_index_info *pBestIdx; /* Index information for this level */ |
︙ | ︙ |
Changes to src/tclsqlite.c.
︙ | ︙ | |||
8 9 10 11 12 13 14 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite. Append this file to sqlite3.c and ** compile the whole thing to build a TCL-enabled version of SQLite. ** | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** A TCL Interface to SQLite. Append this file to sqlite3.c and ** compile the whole thing to build a TCL-enabled version of SQLite. ** ** $Id: tclsqlite.c,v 1.227 2008/10/07 23:46:38 drh Exp $ */ #include "tcl.h" #include <errno.h> /* ** Some additional include files are needed if this file is not ** appended to the amalgamation. |
︙ | ︙ | |||
113 114 115 116 117 118 119 120 121 122 123 124 125 126 | int rc; /* Return code of most recent sqlite3_exec() */ Tcl_Obj *pCollateNeeded; /* Collation needed script */ SqlPreparedStmt *stmtList; /* List of prepared statements*/ SqlPreparedStmt *stmtLast; /* Last statement in the list */ int maxStmt; /* The next maximum number of stmtList */ int nStmt; /* Number of statements in stmtList */ IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */ }; struct IncrblobChannel { sqlite3_blob *pBlob; /* sqlite3 blob handle */ SqliteDb *pDb; /* Associated database connection */ int iSeek; /* Current seek offset */ Tcl_Channel channel; /* Channel identifier */ | > | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | int rc; /* Return code of most recent sqlite3_exec() */ Tcl_Obj *pCollateNeeded; /* Collation needed script */ SqlPreparedStmt *stmtList; /* List of prepared statements*/ SqlPreparedStmt *stmtLast; /* Last statement in the list */ int maxStmt; /* The next maximum number of stmtList */ int nStmt; /* Number of statements in stmtList */ IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */ int nStep, nSort; /* Statistics for most recent operation */ }; struct IncrblobChannel { sqlite3_blob *pBlob; /* sqlite3 blob handle */ SqliteDb *pDb; /* Associated database connection */ int iSeek; /* Current seek offset */ Tcl_Channel channel; /* Channel identifier */ |
︙ | ︙ | |||
973 974 975 976 977 978 979 | "changes", "close", "collate", "collation_needed", "commit_hook", "complete", "copy", "enable_load_extension","errorcode", "eval", "exists", "function", "incrblob", "interrupt", "last_insert_rowid", "nullvalue", "onecolumn", "profile", "progress", "rekey", "rollback_hook", | | > | < | | > | 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 | "changes", "close", "collate", "collation_needed", "commit_hook", "complete", "copy", "enable_load_extension","errorcode", "eval", "exists", "function", "incrblob", "interrupt", "last_insert_rowid", "nullvalue", "onecolumn", "profile", "progress", "rekey", "rollback_hook", "status", "timeout", "total_changes", "trace", "transaction", "update_hook", "version", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BUSY, DB_CACHE, DB_CHANGES, DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, DB_COMMIT_HOOK, DB_COMPLETE, DB_COPY, DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE, DB_EVAL, DB_EXISTS, DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN, DB_PROFILE, DB_PROGRESS, DB_REKEY, DB_ROLLBACK_HOOK, DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, DB_TRACE, DB_TRANSACTION, DB_UPDATE_HOOK, DB_VERSION }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); return TCL_ERROR; } |
︙ | ︙ | |||
1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 | i = nCol; }else{ Tcl_ListObjAppendElement(interp, pRet, pVal); } } if( pScript ){ rc = Tcl_EvalObjEx(interp, pScript, 0); if( rc==TCL_CONTINUE ){ rc = TCL_OK; } } } if( rc==TCL_BREAK ){ | > > > > | 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 | i = nCol; }else{ Tcl_ListObjAppendElement(interp, pRet, pVal); } } if( pScript ){ pDb->nStep = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, 0); pDb->nSort = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_SORT, 0); rc = Tcl_EvalObjEx(interp, pScript, 0); if( rc==TCL_CONTINUE ){ rc = TCL_OK; } } } if( rc==TCL_BREAK ){ |
︙ | ︙ | |||
1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 | Tcl_Free((char*)apParm); } /* Reset the statement. If the result code is SQLITE_SCHEMA, then ** flush the statement cache and try the statement again. */ rc2 = sqlite3_reset(pStmt); if( SQLITE_OK!=rc2 ){ /* If a run-time error occurs, report the error and stop reading ** the SQL */ Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db))); sqlite3_finalize(pStmt); rc = TCL_ERROR; | > > > > | 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 | Tcl_Free((char*)apParm); } /* Reset the statement. If the result code is SQLITE_SCHEMA, then ** flush the statement cache and try the statement again. */ rc2 = sqlite3_reset(pStmt); pDb->nStep = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, 1); pDb->nSort = sqlite3_stmt_status(pStmt, SQLITE_STMTSTATUS_SORT, 1); if( SQLITE_OK!=rc2 ){ /* If a run-time error occurs, report the error and stop reading ** the SQL */ Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db))); sqlite3_finalize(pStmt); rc = TCL_ERROR; |
︙ | ︙ | |||
2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 | Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); rc = TCL_ERROR; } #endif break; } /* ** $db timeout MILLESECONDS ** ** Delay for the number of milliseconds specified when a file is locked. */ case DB_TIMEOUT: { int ms; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 | Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); rc = TCL_ERROR; } #endif break; } /* ** $db status (step|sort) ** ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or ** SQLITE_STMTSTATUS_SORT for the most recent eval. */ case DB_STATUS: { int ms; int v; const char *zOp; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "(step|sort)"); return TCL_ERROR; } zOp = Tcl_GetString(objv[2]); if( strcmp(zOp, "step")==0 ){ v = pDb->nStep; }else if( strcmp(zOp, "sort")==0 ){ v = pDb->nSort; }else{ Tcl_AppendResult(interp, "bad argument: should be step or sort", (char*)0); return TCL_ERROR; } Tcl_SetObjResult(interp, Tcl_NewIntObj(v)); break; } /* ** $db timeout MILLESECONDS ** ** Delay for the number of milliseconds specified when a file is locked. */ case DB_TIMEOUT: { int ms; |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing all sorts of SQLite interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.327 2008/10/07 23:46:38 drh Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> /* |
︙ | ︙ | |||
1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 | db = StmtToDb(pStmt); } rc = sqlite3_finalize(pStmt); Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; return TCL_OK; } /* ** Usage: sqlite3_next_stmt DB STMT ** ** Return the next statment in sequence after STMT. */ static int test_next_stmt( | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 | db = StmtToDb(pStmt); } rc = sqlite3_finalize(pStmt); Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; return TCL_OK; } /* ** Usage: sqlite3_stmt_status STMT CODE RESETFLAG ** ** Get the value of a status counter from a statement. */ static int test_stmt_status( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int iValue; int i, op, resetFlag; const char *zOpName; sqlite3_stmt *pStmt; static const struct { const char *zName; int op; } aOp[] = { { "SQLITE_STMTSTATUS_FULLSCAN_STEP", SQLITE_STMTSTATUS_FULLSCAN_STEP }, { "SQLITE_STMTSTATUS_SORT", SQLITE_STMTSTATUS_SORT }, }; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "STMT PARAMETER RESETFLAG"); return TCL_ERROR; } if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; zOpName = Tcl_GetString(objv[2]); for(i=0; i<ArraySize(aOp); i++){ if( strcmp(aOp[i].zName, zOpName)==0 ){ op = aOp[i].op; break; } } if( i>=ArraySize(aOp) ){ if( Tcl_GetIntFromObj(interp, objv[2], &op) ) return TCL_ERROR; } if( Tcl_GetBooleanFromObj(interp, objv[3], &resetFlag) ) return TCL_ERROR; iValue = sqlite3_stmt_status(pStmt, op, resetFlag); Tcl_SetObjResult(interp, Tcl_NewIntObj(iValue)); return TCL_OK; } /* ** Usage: sqlite3_next_stmt DB STMT ** ** Return the next statment in sequence after STMT. */ static int test_next_stmt( |
︙ | ︙ | |||
4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 | { "sqlite3_prepare", test_prepare ,0 }, { "sqlite3_prepare16", test_prepare16 ,0 }, { "sqlite3_prepare_v2", test_prepare_v2 ,0 }, { "sqlite3_prepare_tkt3134", test_prepare_tkt3134, 0}, { "sqlite3_prepare16_v2", test_prepare16_v2 ,0 }, { "sqlite3_finalize", test_finalize ,0 }, { "sqlite3_reset", test_reset ,0 }, { "sqlite3_expired", test_expired ,0 }, { "sqlite3_transfer_bindings", test_transfer_bind ,0 }, { "sqlite3_changes", test_changes ,0 }, { "sqlite3_step", test_step ,0 }, { "sqlite3_next_stmt", test_next_stmt ,0 }, | > | 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 | { "sqlite3_prepare", test_prepare ,0 }, { "sqlite3_prepare16", test_prepare16 ,0 }, { "sqlite3_prepare_v2", test_prepare_v2 ,0 }, { "sqlite3_prepare_tkt3134", test_prepare_tkt3134, 0}, { "sqlite3_prepare16_v2", test_prepare16_v2 ,0 }, { "sqlite3_finalize", test_finalize ,0 }, { "sqlite3_stmt_status", test_stmt_status ,0 }, { "sqlite3_reset", test_reset ,0 }, { "sqlite3_expired", test_expired ,0 }, { "sqlite3_transfer_bindings", test_transfer_bind ,0 }, { "sqlite3_changes", test_changes ,0 }, { "sqlite3_step", test_step ,0 }, { "sqlite3_next_stmt", test_next_stmt ,0 }, |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.781 2008/10/07 23:46:38 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 | ** correctly optimizing out sorts. */ case OP_Sort: { /* jump */ #ifdef SQLITE_TEST sqlite3_sort_count++; sqlite3_search_count--; #endif /* Fall through into OP_Rewind */ } /* Opcode: Rewind P1 P2 * * * ** ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. | > | 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 | ** correctly optimizing out sorts. */ case OP_Sort: { /* jump */ #ifdef SQLITE_TEST sqlite3_sort_count++; sqlite3_search_count--; #endif p->aCounter[SQLITE_STMTSTATUS_SORT-1]++; /* Fall through into OP_Rewind */ } /* Opcode: Rewind P1 P2 * * * ** ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. |
︙ | ︙ | |||
3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 | assert( pC->deferredMoveto==0 ); rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) : sqlite3BtreePrevious(pCrsr, &res); pC->nullRow = res; pC->cacheStatus = CACHE_STALE; if( res==0 ){ pc = pOp->p2 - 1; #ifdef SQLITE_TEST sqlite3_search_count++; #endif } pC->rowidIsValid = 0; break; } | > | 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 | assert( pC->deferredMoveto==0 ); rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) : sqlite3BtreePrevious(pCrsr, &res); pC->nullRow = res; pC->cacheStatus = CACHE_STALE; if( res==0 ){ pc = pOp->p2 - 1; if( pOp->p5 ) p->aCounter[pOp->p5-1]++; #ifdef SQLITE_TEST sqlite3_search_count++; #endif } pC->rowidIsValid = 0; break; } |
︙ | ︙ | |||
3856 3857 3858 3859 3860 3861 3862 | assert( pC->deferredMoveto==0 ); pC->cacheStatus = CACHE_STALE; } } break; } | | | 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 | assert( pC->deferredMoveto==0 ); pC->cacheStatus = CACHE_STALE; } } break; } /* Opcode: IdxDelete P1 P2 P3 * * ** ** The content of P3 registers starting at register P2 form ** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. */ case OP_IdxDelete: { int i = pOp->p1; |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** This is the header file for information that is private to the ** VDBE. This information used to all be at the top of the single ** source code file "vdbe.c". When that file became too big (over ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** This is the header file for information that is private to the ** VDBE. This information used to all be at the top of the single ** source code file "vdbe.c". When that file became too big (over ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. ** ** $Id: vdbeInt.h,v 1.155 2008/10/07 23:46:38 drh Exp $ */ #ifndef _VDBEINT_H_ #define _VDBEINT_H_ /* ** intToKey() and keyToInt() used to transform the rowid. But with ** the latest versions of the design they are no-ops. |
︙ | ︙ | |||
319 320 321 322 323 324 325 326 327 328 | u8 expired; /* True if the VM needs to be recompiled */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 inVtabMethod; /* See comments above */ int nChange; /* Number of db changes made since last reset */ i64 startTime; /* Time when query started - used for profiling */ int btreeMask; /* Bitmask of db->aDb[] entries referenced */ BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */ int nSql; /* Number of bytes in zSql */ char *zSql; /* Text of the SQL statement that generated this */ #ifdef SQLITE_DEBUG | > | | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | u8 expired; /* True if the VM needs to be recompiled */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 inVtabMethod; /* See comments above */ int nChange; /* Number of db changes made since last reset */ i64 startTime; /* Time when query started - used for profiling */ int btreeMask; /* Bitmask of db->aDb[] entries referenced */ BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */ int aCounter[2]; /* Counters used by sqlite3_stmt_status() */ int nSql; /* Number of bytes in zSql */ char *zSql; /* Text of the SQL statement that generated this */ #ifdef SQLITE_DEBUG FILE *trace; /* Write an execution trace here, if not NULL */ #endif int openedStatement; /* True if this VM has opened a statement journal */ #ifdef SQLITE_SSE int fetchId; /* Statement number used by sqlite3_fetch_statement */ int lru; /* Counter used for LRU cache replacement */ #endif #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT |
︙ | ︙ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** ** This file contains code use to implement APIs that are part of the ** VDBE. ** ** $Id: vdbeapi.c,v 1.145 2008/10/07 23:46:38 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" #if 0 && defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) /* ** The following structure contains pointers to the end points of a |
︙ | ︙ | |||
1281 1282 1283 1284 1285 1286 1287 | pNext = (sqlite3_stmt*)pDb->pVdbe; }else{ pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext; } sqlite3_mutex_leave(pDb->mutex); return pNext; } | > > > > > > > > > > | 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 | pNext = (sqlite3_stmt*)pDb->pVdbe; }else{ pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext; } sqlite3_mutex_leave(pDb->mutex); return pNext; } /* ** Return the value of a status counter for a prepared statement */ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ Vdbe *pVdbe = (Vdbe*)pStmt; int v = pVdbe->aCounter[op-1]; if( resetFlag ) pVdbe->aCounter[op-1] = 0; return v; } |
Changes to src/where.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is responsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** | | | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. This module is responsible for ** generating the code that loops through a table looking for applicable ** rows. Indices are selected and used to speed the search when doing ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** ** $Id: where.c,v 1.325 2008/10/07 23:46:38 drh Exp $ */ #include "sqliteInt.h" /* ** The number of bits in a Bitmask. "BMS" means "BitMask Size". */ #define BMS (sizeof(Bitmask)*8) |
︙ | ︙ | |||
2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 | ** scan of the entire table. */ assert( omitTable==0 ); assert( bRev==0 ); pLevel->op = OP_Next; pLevel->p1 = iCur; pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, OP_Rewind, iCur, brk); } notReady &= ~getMask(&maskSet, iCur); /* Insert code to test every subexpression that can be completely ** computed using the current set of tables. */ for(pTerm=wc.a, j=wc.nTerm; j>0; j--, pTerm++){ | > | 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 | ** scan of the entire table. */ assert( omitTable==0 ); assert( bRev==0 ); pLevel->op = OP_Next; pLevel->p1 = iCur; pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, OP_Rewind, iCur, brk); pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; } notReady &= ~getMask(&maskSet, iCur); /* Insert code to test every subexpression that can be completely ** computed using the current set of tables. */ for(pTerm=wc.a, j=wc.nTerm; j>0; j--, pTerm++){ |
︙ | ︙ | |||
2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 | */ sqlite3ExprClearColumnCache(pParse, -1); for(i=pTabList->nSrc-1; i>=0; i--){ pLevel = &pWInfo->a[i]; sqlite3VdbeResolveLabel(v, pLevel->cont); if( pLevel->op!=OP_Noop ){ sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2); } if( pLevel->nIn ){ struct InLoop *pIn; int j; sqlite3VdbeResolveLabel(v, pLevel->nxt); for(j=pLevel->nIn, pIn=&pLevel->aInLoop[j-1]; j>0; j--, pIn--){ sqlite3VdbeJumpHere(v, pIn->topAddr+1); | > | 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 | */ sqlite3ExprClearColumnCache(pParse, -1); for(i=pTabList->nSrc-1; i>=0; i--){ pLevel = &pWInfo->a[i]; sqlite3VdbeResolveLabel(v, pLevel->cont); if( pLevel->op!=OP_Noop ){ sqlite3VdbeAddOp2(v, pLevel->op, pLevel->p1, pLevel->p2); sqlite3VdbeChangeP5(v, pLevel->p5); } if( pLevel->nIn ){ struct InLoop *pIn; int j; sqlite3VdbeResolveLabel(v, pLevel->nxt); for(j=pLevel->nIn, pIn=&pLevel->aInLoop[j-1]; j>0; j--, pIn--){ sqlite3VdbeJumpHere(v, pIn->topAddr+1); |
︙ | ︙ |
Changes to test/where.test.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the use of indices in WHERE clases. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 2001 September 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the use of indices in WHERE clases. # # $Id: where.test,v 1.49 2008/10/07 23:46:38 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Build some test data # do_test where-1.0 { |
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 | do_test where-1.1.1 { count {SELECT x, y, w FROM t1 WHERE w=10} } {3 121 10 3} do_test where-1.1.2 { set sqlite_query_plan } {t1 i1w} do_test where-1.1.3 { count {SELECT x, y, w AS abc FROM t1 WHERE abc=10} } {3 121 10 3} | > > > > > > > > > > > > | > > > | 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 | do_test where-1.1.1 { count {SELECT x, y, w FROM t1 WHERE w=10} } {3 121 10 3} do_test where-1.1.2 { set sqlite_query_plan } {t1 i1w} do_test where-1.1.3 { db status step } {0} do_test where-1.1.4 { db eval {SELECT x, y, w FROM t1 WHERE +w=10} } {3 121 10} do_test where-1.1.5 { db status step } {99} do_test where-1.1.6 { set sqlite_query_plan } {t1 {}} do_test where-1.1.7 { count {SELECT x, y, w AS abc FROM t1 WHERE abc=10} } {3 121 10 3} do_test where-1.1.8 { set sqlite_query_plan } {t1 i1w} do_test where-1.1.9 { db status step } {0} do_test where-1.2.1 { count {SELECT x, y, w FROM t1 WHERE w=11} } {3 144 11 3} do_test where-1.2.2 { count {SELECT x, y, w AS abc FROM t1 WHERE abc=11} } {3 144 11 3} do_test where-1.3.1 { |
︙ | ︙ | |||
443 444 445 446 447 448 449 | # opcode was executed. If an OP_Sort did occur, then "sort" is appended # to the result. If no OP_Sort happened, then "nosort" is appended. # # This procedure is used to check to make sure sorting is or is not # occurring as expected. # proc cksort {sql} { | < | | 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 | # opcode was executed. If an OP_Sort did occur, then "sort" is appended # to the result. If no OP_Sort happened, then "nosort" is appended. # # This procedure is used to check to make sure sorting is or is not # occurring as expected. # proc cksort {sql} { set data [execsql $sql] if {[db status sort]} {set x sort} {set x nosort} lappend data $x return $data } # Check out the logic that attempts to implement the ORDER BY clause # using an index rather than by sorting. # do_test where-6.1 { |
︙ | ︙ |
Changes to test/where2.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the use of indices in WHERE clauses # based on recent changes to the optimizer. # | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this file is testing the use of indices in WHERE clauses # based on recent changes to the optimizer. # # $Id: where2.test,v 1.14 2008/10/07 23:46:39 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Build some test data # do_test where2-1.0 { |
︙ | ︙ | |||
54 55 56 57 58 59 60 | # opcode was executed. If an OP_Sort did occur, then "sort" is appended # to the result. If no OP_Sort happened, then "nosort" is appended. # # This procedure is used to check to make sure sorting is or is not # occurring as expected. # proc cksort {sql} { | < | | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | # opcode was executed. If an OP_Sort did occur, then "sort" is appended # to the result. If no OP_Sort happened, then "nosort" is appended. # # This procedure is used to check to make sure sorting is or is not # occurring as expected. # proc cksort {sql} { set data [execsql $sql] if {[db status sort]} {set x sort} {set x nosort} lappend data $x return $data } # This procedure executes the SQL. Then it appends to the result the # "sort" or "nosort" keyword (as in the cksort procedure above) then # it appends the ::sqlite_query_plan variable. |
︙ | ︙ |