Add the SQLITE_ENABLE_STAT2 macro. If this is not defined at build-time, the stat2 table is not created, populated, or used.
FossilOrigin-Name: 362665e89c21fd603d9f8ad6c0ead590e885af7c
This commit is contained in:
parent
e275dc3fb8
commit
69188d9a66
24
manifest
24
manifest
@ -1,5 +1,5 @@
|
||||
C Change\sthe\ssqlite_stat2\sschema\sto\sbe\smore\sflexible.
|
||||
D 2009-08-18T16:24:59
|
||||
C Add\sthe\sSQLITE_ENABLE_STAT2\smacro.\sIf\sthis\sis\snot\sdefined\sat\sbuild-time,\sthe\sstat2\stable\sis\snot\screated,\spopulated,\sor\sused.
|
||||
D 2009-08-19T08:18:32
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in 0f7761c5d1c62ae7a841e3393ffaff1fa0f5c00a
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -100,7 +100,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||
F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
|
||||
F src/alter.c 8b42cace4f8e312de596807ba2685179da64fec4
|
||||
F src/analyze.c 7f086e4da3db68c9fad2a4d61d90a62683084a57
|
||||
F src/analyze.c 1a5bf2adeb31f603a34e769a49937100a6da240a
|
||||
F src/attach.c 13995348fc5a26cdd136a50806faf292aabc173f
|
||||
F src/auth.c 802a9439dfa0b8c208b10055cba400e82ef18025
|
||||
F src/backup.c 6f1c2d9862c8a3feb7739dfcca02c1f5352e37f3
|
||||
@ -163,7 +163,7 @@ F src/select.c 67b0778c9585905c8aa75aaa469e76ef3c1d315a
|
||||
F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb
|
||||
F src/sqlite.h.in a6850e9034df1336e8139c4d6964d7d2f0f52337
|
||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||
F src/sqliteInt.h a11d40fc24390e5e0665cf8b1addbe162b9f76c3
|
||||
F src/sqliteInt.h d1a1a37db2d1f597c69ad5884e3e9463a1bd0827
|
||||
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
|
||||
@ -181,7 +181,7 @@ F src/test_async.c 731d23f953ece5bf40ce87810cfb7607218953c5
|
||||
F src/test_autoext.c f53b0cdf7bf5f08100009572a5d65cdb540bd0ad
|
||||
F src/test_backup.c 1384a18985a5a2d275c2662e48473bf1542ebd08
|
||||
F src/test_btree.c 5adbba9b138988a3cf4d3b5424dbc7c85651da02
|
||||
F src/test_config.c 63d1b08809ca182ee75429573111b44735861c64
|
||||
F src/test_config.c 97d840717efcca8cad5e353debc69780ea8ad7ce
|
||||
F src/test_devsym.c 9f4bc2551e267ce7aeda195f3897d0f30c5228f4
|
||||
F src/test_func.c 26ac62d8ed7a9f45a1e05baffb1c1e55fe2a06f2
|
||||
F src/test_hexio.c 2f1122aa3f012fa0142ee3c36ce5c902a70cd12f
|
||||
@ -201,7 +201,7 @@ F src/test_wsd.c 3ae5101de6cbfda2720152ab659ea84079719241
|
||||
F src/tokenize.c af8a56e6a50c5042fc305bfa796275e9bf26ff2b
|
||||
F src/trigger.c 9bc5278d509d81ff0f9b52f0ce7239563d188e32
|
||||
F src/update.c 4da327f706c0d0dfedf4d92154b1b5688bdea0ac
|
||||
F src/utf.c 9b022ac1c1f306733d57daa0df0b8beb7c17e95e
|
||||
F src/utf.c 3ca2c9461b8e942c68da28bfccd448663f536a6f
|
||||
F src/util.c c2416f60ae704a8c4990e4909aa810f90cbffa07
|
||||
F src/vacuum.c 3fe0eebea6d2311c1c2ab2962887d11f7a4dcfb0
|
||||
F src/vdbe.c 464e2e30b1287554a23cdaa0b6b010a9dcb5eb29
|
||||
@ -213,7 +213,7 @@ F src/vdbeblob.c a3f3e0e877fc64ea50165eec2855f5ada4477611
|
||||
F src/vdbemem.c afd6ce02945e659f65642f290a37ccf4a88c4dcb
|
||||
F src/vtab.c aedd76e8670d5a5379f93804398d3ba960125547
|
||||
F src/walker.c 1edca756275f158b80f20eb6f104c8d3fcc96a04
|
||||
F src/where.c 9d4c2f178f842c1ed18c068880f324479ea2cb38
|
||||
F src/where.c 2e61e33f3649ef5940ef63ed285d37d03bc03dc5
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
|
||||
F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
|
||||
@ -223,7 +223,7 @@ F test/alter3.test 25b95a136708f22b87184fa6a4309eea03d65153
|
||||
F test/alter4.test 9386ffd1e9c7245f43eca412b2058d747509cc1f
|
||||
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
|
||||
F test/analyze.test ad5329098fe4de4a96852231d53e3e9e6283ad4b
|
||||
F test/analyze2.test 30987f595f9e34b95bae81794e99b5ca2be7e46c
|
||||
F test/analyze2.test f58acc55f582996dc68ec9d28ede4ebb68afd11f
|
||||
F test/async.test 8c75d31b8330f8b70cf2571b014d4476a063efdb
|
||||
F test/async2.test bf5e2ca2c96763b4cba3d016249ad7259a5603b6
|
||||
F test/async3.test 93edaa9122f498e56ea98c36c72abc407f4fb11e
|
||||
@ -233,7 +233,7 @@ F test/attach.test 1d1be27b9e4c654f9bb14d011a4a87753c0b197a
|
||||
F test/attach2.test a295d2d7061adcee5884ef4a93c7c96a82765437
|
||||
F test/attach3.test 7b92dc8e40c1ebca9732ca6f2d3fefbd46f196df
|
||||
F test/attachmalloc.test cf8cf17d183de357b1147a9baacbdfc85b940b61
|
||||
F test/auth.test 393be593c72bc452cd2fe6e026682752aa258559
|
||||
F test/auth.test 8e9a21d7321c9ad20d26f630acc02e15f2f2a3b6
|
||||
F test/auth2.test ee3ba272e2b975e913afc9b041ee75706e190005
|
||||
F test/auth3.test a4755e6a2a2fea547ffe63c874eb569e60a28eb5
|
||||
F test/autoinc.test 71bc5183c93ed5e2b8b3a71c218d777b55e4fffc
|
||||
@ -744,7 +744,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
||||
P dd96bda2a85c1d94fb4a0bf5f27e2977f7f7e42e
|
||||
R 3ad6c851396bbe27ea036387da51f58c
|
||||
P ded9dec6459baf21e01f63250db5ace57f390e7a
|
||||
R 183c0e0c3d4fd9f579a812122a3f1cb5
|
||||
U dan
|
||||
Z ea071f69e4d6383649120789bd868cdf
|
||||
Z 9353561137495233ae51d7a49e9232d2
|
||||
|
@ -1 +1 @@
|
||||
ded9dec6459baf21e01f63250db5ace57f390e7a
|
||||
362665e89c21fd603d9f8ad6c0ead590e885af7c
|
111
src/analyze.c
111
src/analyze.c
@ -18,12 +18,19 @@
|
||||
|
||||
/*
|
||||
** This routine generates code that opens the sqlite_stat1 table for
|
||||
** writing with cursor iStatCur. The sqlite_stat2 table is opened
|
||||
** for writing using cursor (iStatCur+1).
|
||||
** writing with cursor iStatCur. If the library was built with the
|
||||
** SQLITE_ENABLE_STAT2 macro defined, then the sqlite_stat2 table is
|
||||
** opened for writing using cursor (iStatCur+1)
|
||||
**
|
||||
** If the sqlite_stat1 tables does not previously exist, it is created.
|
||||
** If it does previously exist, all entires associated with table zWhere
|
||||
** are removed. If zWhere==0 then all entries are removed.
|
||||
** Similarly, if the sqlite_stat2 table does not exist and the library
|
||||
** is compiled with SQLITE_ENABLE_STAT2 defined, it is created.
|
||||
**
|
||||
** Argument zWhere may be a pointer to a buffer containing a table name,
|
||||
** or it may be a NULL pointer. If it is not NULL, then all entries in
|
||||
** the sqlite_stat1 and (if applicable) sqlite_stat2 tables associated
|
||||
** with the named table are deleted. If zWhere==0, then code is generated
|
||||
** to delete all stat table entries.
|
||||
*/
|
||||
static void openStatTable(
|
||||
Parse *pParse, /* Parsing context */
|
||||
@ -31,8 +38,16 @@ static void openStatTable(
|
||||
int iStatCur, /* Open the sqlite_stat1 table on this cursor */
|
||||
const char *zWhere /* Delete entries associated with this table */
|
||||
){
|
||||
const char *aName[] = { "sqlite_stat1", "sqlite_stat2" };
|
||||
const char *aCols[] = { "tbl,idx,stat", "tbl,idx,sampleno,sample" };
|
||||
static struct {
|
||||
const char *zName;
|
||||
const char *zCols;
|
||||
} aTable[] = {
|
||||
{ "sqlite_stat1", "tbl,idx,stat" },
|
||||
#ifdef SQLITE_ENABLE_STAT2
|
||||
{ "sqlite_stat2", "tbl,idx,sampleno,sample" },
|
||||
#endif
|
||||
};
|
||||
|
||||
int aRoot[] = {0, 0};
|
||||
int aCreateTbl[] = {0, 0};
|
||||
|
||||
@ -45,15 +60,16 @@ static void openStatTable(
|
||||
assert( sqlite3VdbeDb(v)==db );
|
||||
pDb = &db->aDb[iDb];
|
||||
|
||||
for(i=0; i<ArraySize(aName); i++){
|
||||
for(i=0; i<ArraySize(aTable); i++){
|
||||
const char *zTab = aTable[i].zName;
|
||||
Table *pStat;
|
||||
if( (pStat = sqlite3FindTable(db, aName[i], pDb->zName))==0 ){
|
||||
if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
|
||||
/* The sqlite_stat[12] table does not exist. Create it. Note that a
|
||||
** side-effect of the CREATE TABLE statement is to leave the rootpage
|
||||
** of the new table in register pParse->regRoot. This is important
|
||||
** because the OpenWrite opcode below will be needing it. */
|
||||
sqlite3NestedParse(pParse,
|
||||
"CREATE TABLE %Q.%s(%s)", pDb->zName, aName[i], aCols[i]
|
||||
"CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols
|
||||
);
|
||||
aRoot[i] = pParse->regRoot;
|
||||
aCreateTbl[i] = 1;
|
||||
@ -62,10 +78,10 @@ static void openStatTable(
|
||||
** associated with the table zWhere. If zWhere is NULL, delete the
|
||||
** entire contents of the table. */
|
||||
aRoot[i] = pStat->tnum;
|
||||
sqlite3TableLock(pParse, iDb, aRoot[i], 1, aName[i]);
|
||||
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
|
||||
if( zWhere ){
|
||||
sqlite3NestedParse(pParse,
|
||||
"DELETE FROM %Q.%s WHERE tbl=%Q", pDb->zName, aName[i], zWhere
|
||||
"DELETE FROM %Q.%s WHERE tbl=%Q", pDb->zName, zTab, zWhere
|
||||
);
|
||||
}else{
|
||||
/* The sqlite_stat[12] table already exists. Delete all rows. */
|
||||
@ -75,7 +91,7 @@ static void openStatTable(
|
||||
}
|
||||
|
||||
/* Open the sqlite_stat[12] tables for writing. */
|
||||
for(i=0; i<ArraySize(aName); i++){
|
||||
for(i=0; i<ArraySize(aTable); i++){
|
||||
sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
|
||||
sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
|
||||
sqlite3VdbeChangeP5(v, aCreateTbl[i]);
|
||||
@ -92,29 +108,30 @@ static void analyzeOneTable(
|
||||
int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */
|
||||
int iMem /* Available memory locations begin here */
|
||||
){
|
||||
Index *pIdx; /* An index to being analyzed */
|
||||
int iIdxCur; /* Index of VdbeCursor for index being analyzed */
|
||||
Vdbe *v; /* The virtual machine being built up */
|
||||
int i; /* Loop counter */
|
||||
int topOfLoop; /* The top of the loop */
|
||||
int endOfLoop; /* The end of the loop */
|
||||
int addr; /* The address of an instruction */
|
||||
int iDb; /* Index of database containing pTab */
|
||||
Index *pIdx; /* An index to being analyzed */
|
||||
int iIdxCur; /* Cursor open on index being analyzed */
|
||||
Vdbe *v; /* The virtual machine being built up */
|
||||
int i; /* Loop counter */
|
||||
int topOfLoop; /* The top of the loop */
|
||||
int endOfLoop; /* The end of the loop */
|
||||
int addr; /* The address of an instruction */
|
||||
int iDb; /* Index of database containing pTab */
|
||||
|
||||
|
||||
/* Assign the required registers. */
|
||||
int regTabname = iMem++; /* Register containing table name */
|
||||
int regIdxname = iMem++; /* Register containing index name */
|
||||
int regSampleno = iMem++; /* Register containing next sample number */
|
||||
int regCol = iMem++; /* Content of a column analyzed table */
|
||||
|
||||
int regSamplerecno = iMem++; /* Next sample index record number */
|
||||
int regRecno = iMem++; /* Register next index record number */
|
||||
int regRec = iMem++; /* Register holding completed record */
|
||||
int regTemp = iMem++; /* Temporary use register */
|
||||
int regTemp2 = iMem++; /* Temporary use register */
|
||||
int regRowid = iMem++; /* Rowid for the inserted record */
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT2
|
||||
int regTemp2 = iMem++; /* Temporary use register */
|
||||
int regSamplerecno = iMem++; /* Next sample index record number */
|
||||
int regRecno = iMem++; /* Register next index record number */
|
||||
int regCount = iMem++; /* Total number of records in table */
|
||||
#endif
|
||||
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
if( v==0 || NEVER(pTab==0) || pTab->pIndex==0 ){
|
||||
@ -149,14 +166,19 @@ static void analyzeOneTable(
|
||||
(char *)pKey, P4_KEYINFO_HANDOFF);
|
||||
VdbeComment((v, "%s", pIdx->zName));
|
||||
|
||||
/* Populate the registers containing the table and index names. */
|
||||
if( pTab->pIndex==pIdx ){
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT2
|
||||
/* If this iteration of the loop is generating code to analyze the
|
||||
** first index in the pTab->pIndex list, then register regCount has
|
||||
** not been populated. In this case populate it now. */
|
||||
if( pTab->pIndex==pIdx ){
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount);
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
|
||||
|
||||
/* Zero the regSampleno and regRecno registers. */
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, regSampleno);
|
||||
@ -171,6 +193,7 @@ static void analyzeOneTable(
|
||||
sqlite3VdbeAddOp3(v, OP_Lt, regSamplerecno, sqlite3VdbeCurrentAddr(v)+2,
|
||||
regCount);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, regSamplerecno);
|
||||
#endif
|
||||
|
||||
/* Memory cells are used as follows. All memory cell addresses are
|
||||
** offset by iMem. That is, cell 0 below is actually cell iMem, cell
|
||||
@ -204,8 +227,8 @@ static void analyzeOneTable(
|
||||
|
||||
for(i=0; i<nCol; i++){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
|
||||
#ifdef SQLITE_ENABLE_STAT2
|
||||
if( i==0 ){
|
||||
|
||||
/* Check if the record that cursor iIdxCur points to contains a
|
||||
** value that should be stored in the sqlite_stat2 table. If so,
|
||||
** store it. */
|
||||
@ -234,8 +257,11 @@ static void analyzeOneTable(
|
||||
sqlite3VdbeJumpHere(v, ne);
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, regRecno, 1);
|
||||
}
|
||||
|
||||
assert( sqlite3VdbeCurrentAddr(v)==(topOfLoop+14+2*i) );
|
||||
#else
|
||||
assert( sqlite3VdbeCurrentAddr(v)==(topOfLoop+2+2*i) );
|
||||
#endif
|
||||
|
||||
sqlite3VdbeAddOp3(v, OP_Ne, regCol, 0, iMem+nCol+i+1);
|
||||
|
||||
/**** TODO: add collating sequence *****/
|
||||
@ -243,7 +269,11 @@ static void analyzeOneTable(
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
|
||||
for(i=0; i<nCol; i++){
|
||||
#ifdef SQLITE_ENABLE_STAT2
|
||||
sqlite3VdbeJumpHere(v, topOfLoop+14+2*i);
|
||||
#else
|
||||
sqlite3VdbeJumpHere(v, topOfLoop+2+2*i);
|
||||
#endif
|
||||
sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
|
||||
}
|
||||
@ -495,6 +525,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
}
|
||||
|
||||
/* Load the statistics from the sqlite_stat2 table. */
|
||||
#ifdef SQLITE_ENABLE_STAT2
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_stmt *pStmt = 0;
|
||||
|
||||
@ -522,12 +553,11 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
int eType = sqlite3_column_type(pStmt, 2);
|
||||
|
||||
if( pIdx->aSample==0 ){
|
||||
pIdx->aSample = (IndexSample *)sqlite3DbMallocZero(db,
|
||||
sizeof(IndexSample)*SQLITE_INDEX_SAMPLES
|
||||
);
|
||||
if( pIdx->aSample==0 ){
|
||||
break;
|
||||
}
|
||||
static const int nByte = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES;
|
||||
pIdx->aSample = (IndexSample *)sqlite3DbMallocZero(db, nByte);
|
||||
if( pIdx->aSample==0 ){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( pIdx->aSample ){
|
||||
@ -535,10 +565,10 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
if( pSample->eType==SQLITE_TEXT || pSample->eType==SQLITE_BLOB ){
|
||||
sqlite3DbFree(db, pSample->u.z);
|
||||
}
|
||||
pSample->eType = eType;
|
||||
if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
|
||||
pSample->eType = eType;
|
||||
if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
|
||||
pSample->u.r = sqlite3_column_double(pStmt, 2);
|
||||
}else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
|
||||
}else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
|
||||
const char *z = (const char *)(
|
||||
(eType==SQLITE_BLOB) ?
|
||||
sqlite3_column_blob(pStmt, 2):
|
||||
@ -553,8 +583,8 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
if( pSample->u.z ){
|
||||
memcpy(pSample->u.z, z, n);
|
||||
}else{
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -564,6 +594,7 @@ int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
|
||||
}
|
||||
(void)sqlite3SafetyOn(db);
|
||||
}
|
||||
#endif
|
||||
|
||||
if( rc==SQLITE_NOMEM ){
|
||||
db->mallocFailed = 1;
|
||||
|
@ -2798,7 +2798,9 @@ void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
|
||||
void sqlite3ValueFree(sqlite3_value*);
|
||||
sqlite3_value *sqlite3ValueNew(sqlite3 *);
|
||||
char *sqlite3Utf16to8(sqlite3 *, const void*, int);
|
||||
#ifdef SQLITE_ENABLE_STAT2
|
||||
char *sqlite3Utf8to16(sqlite3 *, int, char *, int, int *);
|
||||
#endif
|
||||
int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
|
||||
void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
|
||||
#ifndef SQLITE_AMALGAMATION
|
||||
|
@ -396,6 +396,12 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
|
||||
Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT2
|
||||
Tcl_SetVar2(interp, "sqlite_options", "stat2", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "stat2", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#if !defined(SQLITE_ENABLE_LOCKING_STYLE)
|
||||
# if defined(__APPLE__)
|
||||
# define SQLITE_ENABLE_LOCKING_STYLE 1
|
||||
|
@ -464,6 +464,7 @@ char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte){
|
||||
** If a malloc failure occurs, NULL is returned and the db.mallocFailed
|
||||
** flag set.
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT2
|
||||
char *sqlite3Utf8to16(sqlite3 *db, int enc, char *z, int n, int *pnOut){
|
||||
Mem m;
|
||||
memset(&m, 0, sizeof(m));
|
||||
@ -477,6 +478,7 @@ char *sqlite3Utf8to16(sqlite3 *db, int enc, char *z, int n, int *pnOut){
|
||||
*pnOut = m.n;
|
||||
return m.z;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** pZ is a UTF-16 encoded unicode string at least nChar characters long.
|
||||
|
@ -1904,6 +1904,7 @@ static void bestVirtualIndex(
|
||||
** Or, if an OOM occurs while converting text values between encodings,
|
||||
** SQLITE_NOMEM is returned.
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT2
|
||||
static int whereRangeRegion(
|
||||
Parse *pParse, /* Database connection */
|
||||
Index *pIdx, /* Index to consider domain of */
|
||||
@ -1970,6 +1971,7 @@ static int whereRangeRegion(
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif /* #ifdef SQLITE_ENABLE_STAT2 */
|
||||
|
||||
/*
|
||||
** This function is used to estimate the number of rows that will be visited
|
||||
@ -2015,10 +2017,12 @@ static int whereRangeScanEst(
|
||||
WhereTerm *pUpper,
|
||||
int *piEst /* OUT: Return value */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT2
|
||||
sqlite3 *db = pParse->db;
|
||||
sqlite3_value *pLowerVal = 0;
|
||||
sqlite3_value *pUpperVal = 0;
|
||||
int rc = SQLITE_OK;
|
||||
|
||||
if( nEq==0 && p->aSample ){
|
||||
int iEst;
|
||||
@ -2053,8 +2057,8 @@ static int whereRangeScanEst(
|
||||
*piEst = iEst;
|
||||
return rc;
|
||||
}
|
||||
|
||||
fallback:
|
||||
#endif
|
||||
assert( pLower || pUpper );
|
||||
*piEst = (SQLITE_INDEX_SAMPLES-1) / ((pLower&&pUpper)?9:3);
|
||||
return rc;
|
||||
|
@ -14,9 +14,16 @@
|
||||
set testdir [file dirname $argv0]
|
||||
source $testdir/tester.tcl
|
||||
|
||||
sqlite3_db_config_lookaside db 0 0 0
|
||||
ifcapable !stat2 {
|
||||
finish_test
|
||||
return
|
||||
}
|
||||
|
||||
do_test analyze2-0.1 {
|
||||
proc eqp sql {
|
||||
uplevel execsql [list "EXPLAIN QUERY PLAN $sql"]
|
||||
}
|
||||
|
||||
do_test analyze2-1.1 {
|
||||
execsql { CREATE TABLE t1(x PRIMARY KEY) }
|
||||
for {set i 0} {$i < 1000} {incr i} {
|
||||
execsql { INSERT INTO t1 VALUES($i) }
|
||||
@ -37,7 +44,7 @@ do_test analyze2-0.1 {
|
||||
t1 sqlite_autoindex_t1_1 9 999 \
|
||||
]
|
||||
|
||||
do_test analyze2-0.2 {
|
||||
do_test analyze2-1.2 {
|
||||
execsql {
|
||||
DELETE FROM t1 WHERe x>9;
|
||||
ANALYZE;
|
||||
@ -45,7 +52,7 @@ do_test analyze2-0.2 {
|
||||
}
|
||||
} {t1 sqlite_autoindex_t1_1 {0 1 2 3 4 5 6 7 8 9}}
|
||||
|
||||
do_test analyze2-0.3 {
|
||||
do_test analyze2-1.3 {
|
||||
execsql {
|
||||
DELETE FROM t1 WHERE x>5;
|
||||
ANALYZE;
|
||||
@ -53,7 +60,7 @@ do_test analyze2-0.3 {
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test analyze2-0.4 {
|
||||
do_test analyze2-1.4 {
|
||||
execsql {
|
||||
DELETE FROM t1;
|
||||
ANALYZE;
|
||||
@ -61,10 +68,6 @@ do_test analyze2-0.4 {
|
||||
}
|
||||
} {}
|
||||
|
||||
proc eqp sql {
|
||||
uplevel execsql [list "EXPLAIN QUERY PLAN $sql"]
|
||||
}
|
||||
|
||||
do_test analyze2-1.1 {
|
||||
execsql {
|
||||
DROP TABLE t1;
|
||||
|
@ -2309,6 +2309,11 @@ ifcapable compound&&subquery {
|
||||
}
|
||||
}
|
||||
}
|
||||
ifcapable stat2 {
|
||||
set stat2 "sqlite_stat2 "
|
||||
} else {
|
||||
set stat2 ""
|
||||
}
|
||||
do_test auth-5.2 {
|
||||
execsql {
|
||||
SELECT name FROM (
|
||||
@ -2316,7 +2321,7 @@ ifcapable compound&&subquery {
|
||||
WHERE type='table'
|
||||
ORDER BY name
|
||||
}
|
||||
} {sqlite_stat1 sqlite_stat2 t1 t2 t3 t4}
|
||||
} "sqlite_stat1 ${stat2}t1 t2 t3 t4"
|
||||
}
|
||||
|
||||
# Ticket #3944
|
||||
|
Loading…
x
Reference in New Issue
Block a user