Refactor the interface to make it more easily extensible.

FossilOrigin-Name: 7955342da4a35b57e4ae26690b8d40f7bba20e8f
This commit is contained in:
drh 2014-11-03 16:35:55 +00:00
parent e2f771b047
commit d1a1c23423
5 changed files with 102 additions and 65 deletions

@ -1,5 +1,5 @@
C Add\sfurther\stests.\sFixes\sso\sthat\scompilation\swithout\sENABLE_STMT_SCANSTATUS\sworks.
D 2014-11-03T15:33:17.869
C Refactor\sthe\sinterface\sto\smake\sit\smore\seasily\sextensible.
D 2014-11-03T16:35:55.977
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in cf57f673d77606ab0f2d9627ca52a9ba1464146a
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -229,7 +229,7 @@ F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
F src/select.c 428165951748151e87a15295b7357221433e311b
F src/shell.c 282f8f5278e0c78eb442217531172ec9e1538796
F src/sqlite.h.in aeba29025ba5fc721a11c1b81ed8745f93029590
F src/sqlite.h.in a110c6320b3af8d7c0660fa1adbc530b6caa2d95
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
F src/sqliteInt.h 4f86ac648ea398c1bb3db036062934cde257ea23
@ -237,7 +237,7 @@ F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 81712116e826b0089bb221b018929536b2b5406f
F src/table.c f142bba7903e93ca8d113a5b8877a108ad1a27dc
F src/tclsqlite.c 7cdd4dd3c2a4183483feca260070d73d6e22cd47
F src/test1.c b53f4da2f386efa5c248716cd4bdc8344a87e952
F src/test1.c 5890094c09691fe9564cf0f0d5b22d35b3218c47
F src/test2.c 98049e51a17dc62606a99a9eb95ee477f9996712
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
@ -292,7 +292,7 @@ F src/vacuum.c 59f03f92bcff57faa6a8ca256eb29ccddfb0614a
F src/vdbe.c 175a360c56e75ce4eb2b60704fd7c011b93926f5
F src/vdbe.h d412bd01e89f0d69991b8f46601f96bc169d28f4
F src/vdbeInt.h 539ba284790e871f98be74a78cbdfcedfae22639
F src/vdbeapi.c addf446ecade237bebd7e9fe769bdfb9db8d9fb1
F src/vdbeapi.c 76d62888455e3d3ffeaf70911cefa94e76a4678a
F src/vdbeaux.c cf6b8152dd22155201d57c216e6266866b61da59
F src/vdbeblob.c 8b5442ff0954c44b45cbabbe2e94091a2e16fdef
F src/vdbemem.c 31d8eabb0cd78bfeab4e5124c7363c3e9e54db9f
@ -1211,7 +1211,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P f5313e0c680d9baebefb1cf50ddadedd4418a334
R b9cde6c71acdc4fef0c5c1ac03d62018
U dan
Z f0600457ea98c0c998694790015a9674
P a2303c719222f1effb51acc6b37930561148c00c
R cbd06b886fdee03f70c2bf18e1342ca1
U drh
Z 0328a60e2b5415c07361c47ade3f21c5

@ -1 +1 @@
a2303c719222f1effb51acc6b37930561148c00c
7955342da4a35b57e4ae26690b8d40f7bba20e8f

@ -7406,54 +7406,75 @@ int sqlite3_vtab_on_conflict(sqlite3 *);
/* #define SQLITE_ABORT 4 // Also an error code */
#define SQLITE_REPLACE 5
/* CAPI3REF: Prepared Statement Scan Status Opcodes
** KEYWORDS: {scanstatus option}
**
** The following constants can be used for the T parameter to the
** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a
** different metric for sqlite3_stmt_scanstatus() to return.
**
** <dl>
** [[SQLITE_SCANSTAT_NLOOP]] <td>SQLITE_SCANSTAT_NLOOP</dt>
** <dd>The [sqlite3_int64] variable pointed to by the T parameter will be set to the
** total number of times that the X-th loop has run.</dd>
**
** [[SQLITE_SCANSTAT_NVISIT]] <td>SQLITE_SCANSTAT_NVISIT</dt>
** <dd>The [sqlite3_int64] variable pointed to by the T parameter will be set to the
** total number of rows visited by the X-th loop.</dd>
**
** [[SQLITE_SCANSTAT_EST]] <td>SQLITE_SCANSTAT_EST</dt>
** <dd>The [sqlite3_int64] variable pointed to by the T parameter will be set to the
** query planner's estimate for the number of rows visited for each
** iteration of the X-th loop. If the query planner's estimate was accurate,
** then this value should be approximately NVISIT/NLOOP.
**
** [[SQLITE_SCANSTAT_NAME]] <td>SQLITE_SCANSTAT_NAME</dt>
** <dd>The "const char *" variable pointed to by the T parameter will be set to
** a zero-terminated UTF-8 string containing the name of the index or table used
** for the X-th loop.
**
** [[SQLITE_SCANSTAT_EXPLAIN]] <td>SQLITE_SCANSTAT_EXPLAIN</dt>
** <dd>The "const char *" variable pointed to by the T parameter will be set to
** a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN] description
** for the X-th loop.
** </dl>
*/
#define SQLITE_SCANSTAT_NLOOP 0
#define SQLITE_SCANSTAT_NVISIT 1
#define SQLITE_SCANSTAT_NEST 2
#define SQLITE_SCANSTAT_NAME 3
#define SQLITE_SCANSTAT_EXPLAIN 4
/*
** CAPI3REF: Prepared Statement Scan Statuses
** CAPI3REF: Prepared Statement Scan Status
**
** Return status data for a single loop within query pStmt.
**
** The "iScanStatusOp" parameter determines which status information to return.
** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior of
** this interface is undefined.
** The requested measurement is written into a variable pointed to by
** the "pOut" parameter.
** Parameter "idx" identifies the specific loop to retrieve statistics for.
** Loops are numbered starting from zero. If idx is out of range - less than
** zero or greater than or equal to the total number of loops used to implement
** the statement - a non-zero value is returned. In this case the final value
** of all five output parameters is undefined. Otherwise, if idx is in range,
** zero is returned and the output parameters set as follows:
** the statement - a non-zero value is returned and the variable that pOut
** points to is unchanged.
**
** <ul>
** <li> (*pnLoop) is set to the total number of times the loop has been run.
** <li> (*pnVisit) is set to the total number of rows visited by the loop.
** <li> (*pnEst) is set to the estimate of the number of rows visited
** by each run of the loop used by the SQL optimizer. Ideally, this
** value should be close to (*pnVisit)/(*pnLoop).
** <li> (*pzName) is set to point to a nul-terminated string containing the
** name of the index of table used by this loop.
** <li> (*pzExplain) is set to point to a nul-terminated string containing
** same text that would be returned for this loop by an EXPLAIN
** QUERY PLAN command.
** </ul>
**
** Output parameters *pzName and *pzExplain are set to point to buffers
** managed by the statement object. Both of these pointers may be invalidated
** by any API call on the same statement object, including an sqlite3_step()
** sqlite3_bind_*() call.
**
** Statistics may not be available for all loops in all statements. In cases
** where there exist loops with no available statistics, this function ignores
** them completely.
** Statistics might not be available for all loops in all statements. In cases
** where there exist loops with no available statistics, this function behaves
** as if the loop did not exist - it returns non-zero and leave the variable
** that pOut points to unchanged.
**
** This API is only available if the library is built with pre-processor
** symbol SQLITE_ENABLE_STMT_SCANSTATUS defined.
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt,
int idx, /* Index of loop to report on */
sqlite3_int64 *pnLoop, /* OUT: Number of times loop was run */
sqlite3_int64 *pnVisit, /* OUT: Number of rows visited (all loops) */
sqlite3_int64 *pnEst, /* OUT: Number of rows estimated (per loop) */
const char **pzName, /* OUT: Object name (table or index) */
const char **pzExplain /* OUT: EQP string */
);
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
int idx, /* Index of loop to report on */
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
void *pOut /* Result written here */
);
/*
** CAPI3REF: Zero Scan-Status Counters
@ -7461,7 +7482,7 @@ SQLITE_EXPERIMENTAL int sqlite3_stmt_scanstatus(
** Zero all sqlite3_stmt_scanstatus() related event counters.
**
** This API is only available if the library is built with pre-processor
** symbol SQLITE_ENABLE_STMT_SCANSTATUS defined.
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
*/
SQLITE_EXPERIMENTAL void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);

@ -2328,19 +2328,21 @@ static int test_stmt_scanstatus(
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR;
res = sqlite3_stmt_scanstatus(
pStmt, idx, &nLoop, &nVisit, &nEst, &zName, &zExplain
);
res = sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NLOOP, (void*)&nLoop);
if( res==0 ){
Tcl_Obj *pRet = Tcl_NewObj();
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nLoop", -1));
Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nLoop));
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nVisit", -1));
Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nVisit));
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_EST, (void*)&nEst);
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nEst", -1));
Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nEst));
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_NAME, (void*)&zName);
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("zName", -1));
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zName, -1));
sqlite3_stmt_scanstatus(pStmt, idx, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("zExplain", -1));
Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zExplain, -1));
Tcl_SetObjResult(interp, pRet);

@ -1481,27 +1481,42 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
** Return status data for a single loop within query pStmt.
*/
int sqlite3_stmt_scanstatus(
sqlite3_stmt *pStmt,
sqlite3_stmt *pStmt, /* Prepared statement being queried */
int idx, /* Index of loop to report on */
sqlite3_int64 *pnLoop, /* OUT: Number of times loop was run */
sqlite3_int64 *pnVisit, /* OUT: Number of rows visited (all loops) */
sqlite3_int64 *pnEst, /* OUT: Number of rows estimated (per loop) */
const char **pzName, /* OUT: Object name (table or index) */
const char **pzExplain /* OUT: EQP string */
int iScanStatusOp, /* Which metric to return */
void *pOut /* OUT: Write the answer here */
){
Vdbe *p = (Vdbe*)pStmt;
ScanStatus *pScan;
if( idx<0 || idx>=p->nScan ) return 1;
pScan = &p->aScan[idx];
if( pnLoop ) *pnLoop = p->anExec[pScan->addrLoop];
if( pnVisit ) *pnVisit = p->anExec[pScan->addrVisit];
if( pnEst ) *pnEst = pScan->nEst;
if( *pzName ) *pzName = pScan->zName;
if( *pzExplain ){
if( pScan->addrExplain ){
*pzExplain = p->aOp[ pScan->addrExplain ].p4.z;
}else{
*pzExplain = 0;
switch( iScanStatusOp ){
case SQLITE_SCANSTAT_NLOOP: {
*(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop];
break;
}
case SQLITE_SCANSTAT_NVISIT: {
*(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit];
break;
}
case SQLITE_SCANSTAT_EST: {
*(sqlite3_int64*)pOut = pScan->nEst;
break;
}
case SQLITE_SCANSTAT_NAME: {
*(const char**)pOut = pScan->zName
break;
}
case SQLITE_SCANSTAT_EXPLAIN: {
if( pScan->addrExplain ){
*(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z;
}else{
*(const char**)pOut = 0;
}
break;
}
default: {
return 1;
}
}
return 0;
@ -1515,4 +1530,3 @@ void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
memset(p->anExec, 0, p->nOp * sizeof(i64));
}
#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */