Add support for PRAGMA analyze_limit and approximate analysis.
FossilOrigin-Name: 812547525d35df975f40cbbeb604cc9cd2dec809c1ca083cbb139fe59ffa1d73
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
C Merge\sthe\sbytecode\sand\stables_used\stable-valued\sfunctions.\s\sRequires\n-DSQLITE_ENABLE_BYTECODE_VTAB\sat\scompile-time.
|
||||
D 2020-05-02T00:31:00.975
|
||||
C Add\ssupport\sfor\sPRAGMA\sanalyze_limit\sand\sapproximate\sanalysis.
|
||||
D 2020-05-02T03:46:32.798
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -468,19 +468,19 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c fa2c3be9b0ebecfafb7062072a0ae6eda126d3e5a9fd51b2eded5acd95dc783c
|
||||
F src/analyze.c 831bb090988477a00d3b4c000746e1b0454dcc93b10b793e6ebe1c47f25d193a
|
||||
F src/analyze.c f71fb976b1bc8e62320e4932f979e56f535237b1579e07b392b22f9a1ccbba42
|
||||
F src/attach.c ff2daea0fe62080192e3f262670e4f61f5a86c1e7bea9cec34e960fe79852aa1
|
||||
F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
|
||||
F src/backup.c 5e617c087f1c2d6005c2ec694ce80d6e16bc68d906e1b1c556d7c7c2228b636b
|
||||
F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
|
||||
F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
|
||||
F src/btree.c 02376eb7d49ccf31b53c2504f045ad74687c142a5c15ca837516e59e737867dc
|
||||
F src/btree.h 32672fa1aa74a7e9ab3aae822f94ffc8e732b1eb005988dc2283f91dc7573398
|
||||
F src/btree.c 3383ad76753193c3529318ba30db41747663639428d2f6cb7cbcd8034d4a99cd
|
||||
F src/btree.h 989ef3c33413549e3e148f3dcb46c030f317dac130dc86809ba6b9aa4b16c72a
|
||||
F src/btreeInt.h 887cdd2ea7f4a65143074a8a7c8928b0546f8c18dda3c06a408ce7992cbab0c0
|
||||
F src/build.c ec6c0bda1e43ef55e5f5121a77ba19fac51fc6585f95ce2da795bcedcf6e8f36
|
||||
F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
|
||||
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
|
||||
F src/ctime.c 6892999ee100bd72b64f84dd7a8f737817d72872648705fbf8ed9575e1f1dd1a
|
||||
F src/ctime.c e98518d2d3d4029a13c805e07313fb60c877be56db76e90dd5f3af73085d0ce6
|
||||
F src/date.c b29b349d277e3d579dcc295b24c0a2caed83fd8f090a9f7cbe6070c0fd662384
|
||||
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
|
||||
F src/dbstat.c 793deaf88a0904f88285d93d6713c636d55ede0ffd9f08d10f4ea825531d367f
|
||||
@@ -526,19 +526,19 @@ F src/parse.y c8eff38606f443d5ba245263fa7abc05e4116d95656e050c4b78e9bfbf931add
|
||||
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
|
||||
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||
F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a
|
||||
F src/pragma.c 5fd004b89c77319008ddff6d65dcc83ccca9584d3048f4f66b108b5906a20dba
|
||||
F src/pragma.h 9473160d220416456b40f27323bb4b316d4e4e08ffbf8bf88c5f7045d49c38e5
|
||||
F src/pragma.c 85f763714b192cc26a236e3ec020a9155fe8da248af21eae86c0d1f0f49a0753
|
||||
F src/pragma.h 8168e588536bffd95319451f34e9a754dc37d205ebe433031a7813c5b286beae
|
||||
F src/prepare.c 8d4d6c8aa6afefc48027c54b41cdf134b4d6bc2fc4badbe483ad7fd9e1728a28
|
||||
F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4
|
||||
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
|
||||
F src/resolve.c d36a2b1639e1c33d7b508abfd3452a63e7fd81737f6f3940bfef085fca6f21f4
|
||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||
F src/select.c c310de94bf67315054587c18a16e7a3e3dc3a98dc79168f0c2b776548d43f6cd
|
||||
F src/select.c 1720bff2168491ca79af81a03bd18c0383f61d845c6e17caff9d25aabc4ab435
|
||||
F src/shell.c.in cf2d24f54412c06e5fb34af7fabc748651125e1dceac29b740e91f06d23447b6
|
||||
F src/sqlite.h.in b20d5dc52765ff82f3701395a7e670611ddf138ee0ae84482452ad3a0b5f24b5
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 2d1af80082edffd71c6f96f70ad1ce6a4fb46615ad10291fc77fe0dea9ff0197
|
||||
F src/sqliteInt.h 0f3848c46310d197246003f052985b72d1cdbfc0b31e069db76cb5231062fa1d
|
||||
F src/sqliteInt.h 1f6909cd268d1cda2f04914d150997b17afd8ff7e5cf1930cc1f88d337a49f74
|
||||
F src/sqliteLimit.h 95cb8479ca459496d9c1c6a9f76b38aee12203a56ce1092fe13e50ae2454c032
|
||||
F src/status.c 9ff2210207c6c3b4d9631a8241a7d45ab1b26a0e9c84cb07a9b5ce2de9a3b278
|
||||
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
|
||||
@@ -605,7 +605,7 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
|
||||
F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7
|
||||
F src/util.c 3b6cedf7a0c69bd6e1acce832873952d416212d6293b18d03064e07d7a9b5118
|
||||
F src/vacuum.c f25d3b39681595e321a8a4e7fca3e5971cb14a401213d0742c9bf7d4ce8c2a1a
|
||||
F src/vdbe.c 972999395eee88702091fb5d50cf4effd07889c371807d222a7f517388e6378e
|
||||
F src/vdbe.c f55fe7dbffae72e1cd5861e9ea3b55d50b70d863eebce3aebf11e1271ceae796
|
||||
F src/vdbe.h 07b8c636a87df8b6e58f29d6badd7f10d5844353deff1d7c88ed1c2bfe3bbd35
|
||||
F src/vdbeInt.h 571413068b5ac07e2ed8ca7a02fa529622fd5455ae6981498376e5e492d2e5ef
|
||||
F src/vdbeapi.c d176ee7251d5344de7bb2a0d2dd0fe536834e5843d9bc2389e0f5cdcd5374141
|
||||
@@ -1796,7 +1796,7 @@ F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a89
|
||||
F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c
|
||||
F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21
|
||||
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
|
||||
F tool/mkpragmatab.tcl 62663c65d9191aada624a787e1ee3420f268a3c27999ad0ffb77a6918ddc1e52
|
||||
F tool/mkpragmatab.tcl d348a4bf71ac068bddf89326562071cbbd962273d88f9b5e5d622f3e73b78bdf
|
||||
F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712
|
||||
F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
|
||||
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
|
||||
@@ -1863,8 +1863,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 853703cd6d44d6dd48ef5eda6523e374b8ebdf7c338ddaad31c15a40a8b3fd9b baa720e4a88f268ed95337daab5f434fd3263b00f09101cddc6424765bf3b722
|
||||
R 8a6312f86dfd0f2dc1b9dbd32625eb27
|
||||
T +closed baa720e4a88f268ed95337daab5f434fd3263b00f09101cddc6424765bf3b722
|
||||
P d09bcce37f1eaf084e3b07eb4a23653ea1f370cdd290ce3875408186adf87022 77a55c394d2c313a5710229bee9262457dcfc6620e6500f9f526c5f6acf87cef
|
||||
R 4ed29fc45141d3045a102a3aecbc1dee
|
||||
T +closed 77a55c394d2c313a5710229bee9262457dcfc6620e6500f9f526c5f6acf87cef
|
||||
U drh
|
||||
Z 757d78e9720a98d9f46cefa09a4228d8
|
||||
Z 44d724364acf9e8bd25af4207bb5887c
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
d09bcce37f1eaf084e3b07eb4a23653ea1f370cdd290ce3875408186adf87022
|
||||
812547525d35df975f40cbbeb604cc9cd2dec809c1ca083cbb139fe59ffa1d73
|
||||
+131
-84
@@ -188,6 +188,11 @@ static void openStatTable(
|
||||
Vdbe *v = sqlite3GetVdbe(pParse);
|
||||
int aRoot[ArraySize(aTable)];
|
||||
u8 aCreateTbl[ArraySize(aTable)];
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
const int nToOpen = OptimizationEnabled(db,SQLITE_Stat4) ? 2 : 1;
|
||||
#else
|
||||
const int nToOpen = 1;
|
||||
#endif
|
||||
|
||||
if( v==0 ) return;
|
||||
assert( sqlite3BtreeHoldsAllMutexes(db) );
|
||||
@@ -200,8 +205,9 @@ static void openStatTable(
|
||||
for(i=0; i<ArraySize(aTable); i++){
|
||||
const char *zTab = aTable[i].zName;
|
||||
Table *pStat;
|
||||
aCreateTbl[i] = 0;
|
||||
if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
|
||||
if( aTable[i].zCols ){
|
||||
if( i<nToOpen ){
|
||||
/* The sqlite_statN 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
|
||||
@@ -217,7 +223,6 @@ static void openStatTable(
|
||||
** associated with the table zWhere. If zWhere is NULL, delete the
|
||||
** entire contents of the table. */
|
||||
aRoot[i] = pStat->tnum;
|
||||
aCreateTbl[i] = 0;
|
||||
sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
|
||||
if( zWhere ){
|
||||
sqlite3NestedParse(pParse,
|
||||
@@ -236,7 +241,7 @@ static void openStatTable(
|
||||
}
|
||||
|
||||
/* Open the sqlite_stat[134] tables for writing. */
|
||||
for(i=0; aTable[i].zCols; i++){
|
||||
for(i=0; i<nToOpen; i++){
|
||||
assert( i<ArraySize(aTable) );
|
||||
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
|
||||
sqlite3VdbeChangeP5(v, aCreateTbl[i]);
|
||||
@@ -275,9 +280,12 @@ struct StatSample {
|
||||
};
|
||||
struct StatAccum {
|
||||
sqlite3 *db; /* Database connection, for malloc() */
|
||||
tRowcnt nRow; /* Number of rows in the entire table */
|
||||
tRowcnt nEst; /* Estimated number of rows */
|
||||
tRowcnt nRow; /* Number of rows visited so far */
|
||||
int nLimit; /* Analysis row-scan limit */
|
||||
int nCol; /* Number of columns in index + pk/rowid */
|
||||
int nKeyCol; /* Number of index columns w/o the pk/rowid */
|
||||
u8 nSkipAhead; /* Number of times of skip-ahead */
|
||||
StatSample current; /* Current row as a StatSample */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
tRowcnt nPSample; /* How often to do a periodic sample */
|
||||
@@ -357,27 +365,28 @@ static void sampleCopy(StatAccum *p, StatSample *pTo, StatSample *pFrom){
|
||||
static void statAccumDestructor(void *pOld){
|
||||
StatAccum *p = (StatAccum*)pOld;
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
int i;
|
||||
for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
|
||||
for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
|
||||
sampleClear(p->db, &p->current);
|
||||
if( p->mxSample ){
|
||||
int i;
|
||||
for(i=0; i<p->nCol; i++) sampleClear(p->db, p->aBest+i);
|
||||
for(i=0; i<p->mxSample; i++) sampleClear(p->db, p->a+i);
|
||||
sampleClear(p->db, &p->current);
|
||||
}
|
||||
#endif
|
||||
sqlite3DbFree(p->db, p);
|
||||
}
|
||||
|
||||
/*
|
||||
** Implementation of the stat_init(N,K,C) SQL function. The three parameters
|
||||
** Implementation of the stat_init(N,K,C,L) SQL function. The four parameters
|
||||
** are:
|
||||
** N: The number of columns in the index including the rowid/pk (note 1)
|
||||
** K: The number of columns in the index excluding the rowid/pk.
|
||||
** C: The number of rows in the index (note 2)
|
||||
** C: Estimated number of rows in the index
|
||||
** L: A limit on the number of rows to scan, or 0 for no-limit
|
||||
**
|
||||
** Note 1: In the special case of the covering index that implements a
|
||||
** WITHOUT ROWID table, N is the number of PRIMARY KEY columns, not the
|
||||
** total number of columns in the table.
|
||||
**
|
||||
** Note 2: C is only used for STAT4.
|
||||
**
|
||||
** For indexes on ordinary rowid tables, N==K+1. But for indexes on
|
||||
** WITHOUT ROWID tables, N=K+P where P is the number of columns in the
|
||||
** PRIMARY KEY of the table. The covering index that implements the
|
||||
@@ -398,9 +407,10 @@ static void statInit(
|
||||
int nKeyCol; /* Number of key columns */
|
||||
int nColUp; /* nCol rounded up for alignment */
|
||||
int n; /* Bytes of space to allocate */
|
||||
sqlite3 *db; /* Database connection */
|
||||
sqlite3 *db = sqlite3_context_db_handle(context); /* Database connection */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
int mxSample = SQLITE_STAT4_SAMPLES;
|
||||
/* Maximum number of samples. 0 if STAT4 data is not collected */
|
||||
int mxSample = OptimizationEnabled(db,SQLITE_Stat4) ?SQLITE_STAT4_SAMPLES :0;
|
||||
#endif
|
||||
|
||||
/* Decode the three function arguments */
|
||||
@@ -415,13 +425,14 @@ static void statInit(
|
||||
/* Allocate the space required for the StatAccum object */
|
||||
n = sizeof(*p)
|
||||
+ sizeof(tRowcnt)*nColUp /* StatAccum.anEq */
|
||||
+ sizeof(tRowcnt)*nColUp /* StatAccum.anDLt */
|
||||
+ sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
+ sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
|
||||
+ sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
|
||||
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample)
|
||||
if( mxSample ){
|
||||
n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */
|
||||
+ sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */
|
||||
+ sizeof(tRowcnt)*3*nColUp*(nCol+mxSample);
|
||||
}
|
||||
#endif
|
||||
;
|
||||
db = sqlite3_context_db_handle(context);
|
||||
p = sqlite3DbMallocZero(db, n);
|
||||
if( p==0 ){
|
||||
@@ -430,20 +441,23 @@ static void statInit(
|
||||
}
|
||||
|
||||
p->db = db;
|
||||
p->nEst = sqlite3_value_int64(argv[2]);
|
||||
p->nRow = 0;
|
||||
p->nLimit = sqlite3_value_int64(argv[3]);
|
||||
p->nCol = nCol;
|
||||
p->nKeyCol = nKeyCol;
|
||||
p->nSkipAhead = 0;
|
||||
p->current.anDLt = (tRowcnt*)&p[1];
|
||||
p->current.anEq = &p->current.anDLt[nColUp];
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
{
|
||||
p->mxSample = p->nLimit==0 ? mxSample : 0;
|
||||
if( mxSample ){
|
||||
u8 *pSpace; /* Allocated space not yet assigned */
|
||||
int i; /* Used to iterate through p->aSample[] */
|
||||
|
||||
p->iGet = -1;
|
||||
p->mxSample = mxSample;
|
||||
p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
|
||||
p->nPSample = (tRowcnt)(p->nEst/(mxSample/3+1) + 1);
|
||||
p->current.anLt = &p->current.anEq[nColUp];
|
||||
p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
|
||||
|
||||
@@ -471,7 +485,7 @@ static void statInit(
|
||||
sqlite3_result_blob(context, p, sizeof(*p), statAccumDestructor);
|
||||
}
|
||||
static const FuncDef statInitFuncdef = {
|
||||
2+IsStat4, /* nArg */
|
||||
4, /* nArg */
|
||||
SQLITE_UTF8, /* funcFlags */
|
||||
0, /* pUserData */
|
||||
0, /* pNext */
|
||||
@@ -675,10 +689,13 @@ static void samplePushPrevious(StatAccum *p, int iChng){
|
||||
** R Rowid for the current row. Might be a key record for
|
||||
** WITHOUT ROWID tables.
|
||||
**
|
||||
** This SQL function always returns NULL. It's purpose it to accumulate
|
||||
** statistical data and/or samples in the StatAccum object about the
|
||||
** index being analyzed. The stat_get() SQL function will later be used to
|
||||
** extract relevant information for constructing the sqlite_statN tables.
|
||||
** The purpose of this routine is to collect statistical data and/or
|
||||
** samples from the index being analyzed into the StatAccum object.
|
||||
** The stat_get() SQL function will be used afterwards to
|
||||
** retrieve the information gathered.
|
||||
**
|
||||
** This SQL function usually returns NULL, but might return an integer
|
||||
** if it wants the byte-code to do special processing.
|
||||
**
|
||||
** The R parameter is only used for STAT4
|
||||
*/
|
||||
@@ -704,7 +721,7 @@ static void statPush(
|
||||
}else{
|
||||
/* Second and subsequent calls get processed here */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
samplePushPrevious(p, iChng);
|
||||
if( p->mxSample ) samplePushPrevious(p, iChng);
|
||||
#endif
|
||||
|
||||
/* Update anDLt[], anLt[] and anEq[] to reflect the values that apply
|
||||
@@ -715,26 +732,25 @@ static void statPush(
|
||||
for(i=iChng; i<p->nCol; i++){
|
||||
p->current.anDLt[i]++;
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
p->current.anLt[i] += p->current.anEq[i];
|
||||
if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i];
|
||||
#endif
|
||||
p->current.anEq[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
p->nRow++;
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
|
||||
sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
|
||||
}else{
|
||||
sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
|
||||
sqlite3_value_blob(argv[2]));
|
||||
}
|
||||
p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
{
|
||||
tRowcnt nLt = p->current.anLt[p->nCol-1];
|
||||
if( p->mxSample ){
|
||||
tRowcnt nLt;
|
||||
if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){
|
||||
sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2]));
|
||||
}else{
|
||||
sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]),
|
||||
sqlite3_value_blob(argv[2]));
|
||||
}
|
||||
p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345;
|
||||
|
||||
nLt = p->current.anLt[p->nCol-1];
|
||||
/* Check if this is to be a periodic sample. If so, add it. */
|
||||
if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){
|
||||
p->current.isPSample = 1;
|
||||
@@ -750,9 +766,14 @@ static void statPush(
|
||||
sampleCopy(p, &p->aBest[i], &p->current);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else
|
||||
#endif
|
||||
if( p->nLimit && p->nRow>p->nLimit*(p->nSkipAhead+1) ){
|
||||
p->nSkipAhead++;
|
||||
sqlite3_result_int(context, p->current.anDLt[0]>0);
|
||||
}
|
||||
}
|
||||
|
||||
static const FuncDef statPushFuncdef = {
|
||||
2+IsStat4, /* nArg */
|
||||
SQLITE_UTF8, /* funcFlags */
|
||||
@@ -804,6 +825,7 @@ static void statGet(
|
||||
|| eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT
|
||||
|| eCall==STAT_GET_NDLT
|
||||
);
|
||||
assert( eCall==STAT_GET_STAT1 || p->mxSample );
|
||||
if( eCall==STAT_GET_STAT1 )
|
||||
#else
|
||||
assert( argc==1 );
|
||||
@@ -839,7 +861,8 @@ static void statGet(
|
||||
return;
|
||||
}
|
||||
|
||||
sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
|
||||
sqlite3_snprintf(24, zRet, "%llu",
|
||||
p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
|
||||
z = zRet + sqlite3Strlen30(zRet);
|
||||
for(i=0; i<p->nKeyCol; i++){
|
||||
u64 nDistinct = p->current.anDLt[i] + 1;
|
||||
@@ -915,16 +938,16 @@ static const FuncDef statGetFuncdef = {
|
||||
{0}
|
||||
};
|
||||
|
||||
static void callStatGet(Parse *pParse, int regStat4, int iParam, int regOut){
|
||||
static void callStatGet(Parse *pParse, int regStat, int iParam, int regOut){
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat4+1);
|
||||
sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat+1);
|
||||
#elif SQLITE_DEBUG
|
||||
assert( iParam==STAT_GET_STAT1 );
|
||||
#else
|
||||
UNUSED_PARAMETER( iParam );
|
||||
#endif
|
||||
assert( regOut!=regStat4 && regOut!=regStat4+1 );
|
||||
sqlite3VdbeAddFunctionCall(pParse, 0, regStat4, regOut, 1+IsStat4,
|
||||
assert( regOut!=regStat && regOut!=regStat+1 );
|
||||
sqlite3VdbeAddFunctionCall(pParse, 0, regStat, regOut, 1+IsStat4,
|
||||
&statGetFuncdef, 0);
|
||||
}
|
||||
|
||||
@@ -950,12 +973,11 @@ static void analyzeOneTable(
|
||||
int iDb; /* Index of database containing pTab */
|
||||
u8 needTableCnt = 1; /* True to count the table */
|
||||
int regNewRowid = iMem++; /* Rowid for the inserted record */
|
||||
int regStat4 = iMem++; /* Register to hold StatAccum object */
|
||||
int regStat = iMem++; /* Register to hold StatAccum object */
|
||||
int regChng = iMem++; /* Index of changed index field */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
int regRowid = iMem++; /* Rowid argument passed to stat_push() */
|
||||
#endif
|
||||
int regTemp = iMem++; /* Temporary use register */
|
||||
int regTemp2 = iMem++; /* Second temporary use register */
|
||||
int regTabname = iMem++; /* Register containing table name */
|
||||
int regIdxname = iMem++; /* Register containing index name */
|
||||
int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */
|
||||
@@ -1083,17 +1105,26 @@ static void analyzeOneTable(
|
||||
** (1) the number of columns in the index including the rowid
|
||||
** (or for a WITHOUT ROWID table, the number of PK columns),
|
||||
** (2) the number of columns in the key without the rowid/pk
|
||||
** (3) the number of rows in the index,
|
||||
**
|
||||
**
|
||||
** The third argument is only used for STAT4
|
||||
** (3) estimated number of rows in the index,
|
||||
*/
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat+1);
|
||||
assert( regRowid==regStat+2 );
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regRowid);
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
|
||||
if( OptimizationEnabled(db, SQLITE_Stat4) ){
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regTemp);
|
||||
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
|
||||
VdbeCoverage(v);
|
||||
}else
|
||||
#endif
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
|
||||
sqlite3VdbeAddFunctionCall(pParse, 0, regStat4+1, regStat4, 2+IsStat4,
|
||||
{
|
||||
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp3(v, OP_Count, iIdxCur, regTemp, 1);
|
||||
}
|
||||
assert( regTemp2==regStat+4 );
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, db->nAnalysisLimit, regTemp2);
|
||||
sqlite3VdbeAddFunctionCall(pParse, 0, regStat+1, regStat, 4,
|
||||
&statInitFuncdef, 0);
|
||||
|
||||
/* Implementation of the following:
|
||||
@@ -1104,8 +1135,6 @@ static void analyzeOneTable(
|
||||
** goto next_push_0;
|
||||
**
|
||||
*/
|
||||
addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
|
||||
addrNextRow = sqlite3VdbeCurrentAddr(v);
|
||||
|
||||
@@ -1138,6 +1167,7 @@ static void analyzeOneTable(
|
||||
char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
|
||||
sqlite3VdbeAddOp2(v, OP_Integer, i, regChng);
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp);
|
||||
VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
|
||||
aGotoChng[i] =
|
||||
sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ);
|
||||
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
|
||||
@@ -1158,6 +1188,7 @@ static void analyzeOneTable(
|
||||
for(i=0; i<nColTest; i++){
|
||||
sqlite3VdbeJumpHere(v, aGotoChng[i]);
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i);
|
||||
VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
|
||||
}
|
||||
sqlite3VdbeResolveLabel(v, endDistinctTest);
|
||||
sqlite3DbFree(db, aGotoChng);
|
||||
@@ -1171,30 +1202,46 @@ static void analyzeOneTable(
|
||||
** if !eof(csr) goto next_row;
|
||||
*/
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
assert( regRowid==(regStat4+2) );
|
||||
if( HasRowid(pTab) ){
|
||||
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
|
||||
}else{
|
||||
Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
|
||||
int j, k, regKey;
|
||||
regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
|
||||
for(j=0; j<pPk->nKeyCol; j++){
|
||||
k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
|
||||
assert( k>=0 && k<pIdx->nColumn );
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
|
||||
VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName));
|
||||
if( OptimizationEnabled(db, SQLITE_Stat4) ){
|
||||
assert( regRowid==(regStat+2) );
|
||||
if( HasRowid(pTab) ){
|
||||
sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid);
|
||||
}else{
|
||||
Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
|
||||
int j, k, regKey;
|
||||
regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol);
|
||||
for(j=0; j<pPk->nKeyCol; j++){
|
||||
k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]);
|
||||
assert( k>=0 && k<pIdx->nColumn );
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j);
|
||||
VdbeComment((v, "%s.column(%d)", pIdx->zName, i));
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
|
||||
sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
|
||||
}
|
||||
sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid);
|
||||
sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol);
|
||||
}
|
||||
#endif
|
||||
assert( regChng==(regStat4+1) );
|
||||
sqlite3VdbeAddFunctionCall(pParse, 1, regStat4, regTemp, 2+IsStat4,
|
||||
&statPushFuncdef, 0);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
|
||||
assert( regChng==(regStat+1) );
|
||||
{
|
||||
sqlite3VdbeAddFunctionCall(pParse, 1, regStat, regTemp, 2+IsStat4,
|
||||
&statPushFuncdef, 0);
|
||||
if( db->nAnalysisLimit ){
|
||||
int j1, j2, j3;
|
||||
j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regTemp); VdbeCoverage(v);
|
||||
j2 = sqlite3VdbeAddOp1(v, OP_If, regTemp); VdbeCoverage(v);
|
||||
j3 = sqlite3VdbeAddOp4Int(v, OP_SeekGT, iIdxCur, 0, regPrev, 1);
|
||||
VdbeCoverage(v);
|
||||
sqlite3VdbeJumpHere(v, j1);
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
|
||||
sqlite3VdbeJumpHere(v, j2);
|
||||
sqlite3VdbeJumpHere(v, j3);
|
||||
}else{
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the entry to the stat1 table. */
|
||||
callStatGet(pParse, regStat4, STAT_GET_STAT1, regStat1);
|
||||
callStatGet(pParse, regStat, STAT_GET_STAT1, regStat1);
|
||||
assert( "BBB"[0]==SQLITE_AFF_TEXT );
|
||||
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
|
||||
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
|
||||
@@ -1206,7 +1253,7 @@ static void analyzeOneTable(
|
||||
|
||||
/* Add the entries to the stat4 table. */
|
||||
#ifdef SQLITE_ENABLE_STAT4
|
||||
{
|
||||
if( OptimizationEnabled(db, SQLITE_Stat4) && db->nAnalysisLimit==0 ){
|
||||
int regEq = regStat1;
|
||||
int regLt = regStat1+1;
|
||||
int regDLt = regStat1+2;
|
||||
@@ -1220,12 +1267,12 @@ static void analyzeOneTable(
|
||||
pParse->nMem = MAX(pParse->nMem, regCol+nCol);
|
||||
|
||||
addrNext = sqlite3VdbeCurrentAddr(v);
|
||||
callStatGet(pParse, regStat4, STAT_GET_ROWID, regSampleRowid);
|
||||
callStatGet(pParse, regStat, STAT_GET_ROWID, regSampleRowid);
|
||||
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
|
||||
VdbeCoverage(v);
|
||||
callStatGet(pParse, regStat4, STAT_GET_NEQ, regEq);
|
||||
callStatGet(pParse, regStat4, STAT_GET_NLT, regLt);
|
||||
callStatGet(pParse, regStat4, STAT_GET_NDLT, regDLt);
|
||||
callStatGet(pParse, regStat, STAT_GET_NEQ, regEq);
|
||||
callStatGet(pParse, regStat, STAT_GET_NLT, regLt);
|
||||
callStatGet(pParse, regStat, STAT_GET_NDLT, regDLt);
|
||||
sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
|
||||
VdbeCoverage(v);
|
||||
for(i=0; i<nCol; i++){
|
||||
|
||||
@@ -9512,7 +9512,6 @@ int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_BTREECOUNT
|
||||
/*
|
||||
** The first argument, pCur, is a cursor opened on some b-tree. Count the
|
||||
** number of entries in the b-tree and write the result to *pnEntry.
|
||||
@@ -9585,7 +9584,6 @@ int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){
|
||||
/* An error has occurred. Return an error code. */
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Return the pager associated with a BTree. This routine is used for
|
||||
|
||||
@@ -336,9 +336,7 @@ int sqlite3BtreeCursorIsValid(BtCursor*);
|
||||
#endif
|
||||
int sqlite3BtreeCursorIsValidNN(BtCursor*);
|
||||
|
||||
#ifndef SQLITE_OMIT_BTREECOUNT
|
||||
int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_TEST
|
||||
int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
|
||||
|
||||
@@ -514,9 +514,6 @@ static const char * const sqlite3azCompileOpt[] = {
|
||||
#if SQLITE_OMIT_BLOB_LITERAL
|
||||
"OMIT_BLOB_LITERAL",
|
||||
#endif
|
||||
#if SQLITE_OMIT_BTREECOUNT
|
||||
"OMIT_BTREECOUNT",
|
||||
#endif
|
||||
#if SQLITE_OMIT_CAST
|
||||
"OMIT_CAST",
|
||||
#endif
|
||||
|
||||
+19
-2
@@ -1729,7 +1729,6 @@ void sqlite3Pragma(
|
||||
}
|
||||
sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v);
|
||||
sqlite3VdbeJumpHere(v, loopTop-1);
|
||||
#ifndef SQLITE_OMIT_BTREECOUNT
|
||||
if( !isQuick ){
|
||||
sqlite3VdbeLoadString(v, 2, "wrong # of entries in index ");
|
||||
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
|
||||
@@ -1743,7 +1742,6 @@ void sqlite3Pragma(
|
||||
sqlite3VdbeJumpHere(v, addr);
|
||||
}
|
||||
}
|
||||
#endif /* SQLITE_OMIT_BTREECOUNT */
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -2178,6 +2176,25 @@ void sqlite3Pragma(
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** PRAGMA analysis_limit
|
||||
** PRAGMA analysis_limit = N
|
||||
**
|
||||
** Configure the maximum number of rows that ANALYZE will examine
|
||||
** in each index that it looks at. Return the new limit.
|
||||
*/
|
||||
case PragTyp_ANALYSIS_LIMIT: {
|
||||
sqlite3_int64 N;
|
||||
if( zRight
|
||||
&& sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
|
||||
&& N>=0
|
||||
){
|
||||
db->nAnalysisLimit = (int)(N&0x7fffffff);
|
||||
}
|
||||
returnSingleInt(v, db->nAnalysisLimit);
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
|
||||
/*
|
||||
** Report the current state of file logs for all databases
|
||||
|
||||
+50
-44
@@ -6,49 +6,50 @@
|
||||
|
||||
/* The various pragma types */
|
||||
#define PragTyp_ACTIVATE_EXTENSIONS 0
|
||||
#define PragTyp_HEADER_VALUE 1
|
||||
#define PragTyp_AUTO_VACUUM 2
|
||||
#define PragTyp_FLAG 3
|
||||
#define PragTyp_BUSY_TIMEOUT 4
|
||||
#define PragTyp_CACHE_SIZE 5
|
||||
#define PragTyp_CACHE_SPILL 6
|
||||
#define PragTyp_CASE_SENSITIVE_LIKE 7
|
||||
#define PragTyp_COLLATION_LIST 8
|
||||
#define PragTyp_COMPILE_OPTIONS 9
|
||||
#define PragTyp_DATA_STORE_DIRECTORY 10
|
||||
#define PragTyp_DATABASE_LIST 11
|
||||
#define PragTyp_DEFAULT_CACHE_SIZE 12
|
||||
#define PragTyp_ENCODING 13
|
||||
#define PragTyp_FOREIGN_KEY_CHECK 14
|
||||
#define PragTyp_FOREIGN_KEY_LIST 15
|
||||
#define PragTyp_FUNCTION_LIST 16
|
||||
#define PragTyp_HARD_HEAP_LIMIT 17
|
||||
#define PragTyp_INCREMENTAL_VACUUM 18
|
||||
#define PragTyp_INDEX_INFO 19
|
||||
#define PragTyp_INDEX_LIST 20
|
||||
#define PragTyp_INTEGRITY_CHECK 21
|
||||
#define PragTyp_JOURNAL_MODE 22
|
||||
#define PragTyp_JOURNAL_SIZE_LIMIT 23
|
||||
#define PragTyp_LOCK_PROXY_FILE 24
|
||||
#define PragTyp_LOCKING_MODE 25
|
||||
#define PragTyp_PAGE_COUNT 26
|
||||
#define PragTyp_MMAP_SIZE 27
|
||||
#define PragTyp_MODULE_LIST 28
|
||||
#define PragTyp_OPTIMIZE 29
|
||||
#define PragTyp_PAGE_SIZE 30
|
||||
#define PragTyp_PRAGMA_LIST 31
|
||||
#define PragTyp_SECURE_DELETE 32
|
||||
#define PragTyp_SHRINK_MEMORY 33
|
||||
#define PragTyp_SOFT_HEAP_LIMIT 34
|
||||
#define PragTyp_SYNCHRONOUS 35
|
||||
#define PragTyp_TABLE_INFO 36
|
||||
#define PragTyp_TEMP_STORE 37
|
||||
#define PragTyp_TEMP_STORE_DIRECTORY 38
|
||||
#define PragTyp_THREADS 39
|
||||
#define PragTyp_WAL_AUTOCHECKPOINT 40
|
||||
#define PragTyp_WAL_CHECKPOINT 41
|
||||
#define PragTyp_LOCK_STATUS 42
|
||||
#define PragTyp_STATS 43
|
||||
#define PragTyp_ANALYSIS_LIMIT 1
|
||||
#define PragTyp_HEADER_VALUE 2
|
||||
#define PragTyp_AUTO_VACUUM 3
|
||||
#define PragTyp_FLAG 4
|
||||
#define PragTyp_BUSY_TIMEOUT 5
|
||||
#define PragTyp_CACHE_SIZE 6
|
||||
#define PragTyp_CACHE_SPILL 7
|
||||
#define PragTyp_CASE_SENSITIVE_LIKE 8
|
||||
#define PragTyp_COLLATION_LIST 9
|
||||
#define PragTyp_COMPILE_OPTIONS 10
|
||||
#define PragTyp_DATA_STORE_DIRECTORY 11
|
||||
#define PragTyp_DATABASE_LIST 12
|
||||
#define PragTyp_DEFAULT_CACHE_SIZE 13
|
||||
#define PragTyp_ENCODING 14
|
||||
#define PragTyp_FOREIGN_KEY_CHECK 15
|
||||
#define PragTyp_FOREIGN_KEY_LIST 16
|
||||
#define PragTyp_FUNCTION_LIST 17
|
||||
#define PragTyp_HARD_HEAP_LIMIT 18
|
||||
#define PragTyp_INCREMENTAL_VACUUM 19
|
||||
#define PragTyp_INDEX_INFO 20
|
||||
#define PragTyp_INDEX_LIST 21
|
||||
#define PragTyp_INTEGRITY_CHECK 22
|
||||
#define PragTyp_JOURNAL_MODE 23
|
||||
#define PragTyp_JOURNAL_SIZE_LIMIT 24
|
||||
#define PragTyp_LOCK_PROXY_FILE 25
|
||||
#define PragTyp_LOCKING_MODE 26
|
||||
#define PragTyp_PAGE_COUNT 27
|
||||
#define PragTyp_MMAP_SIZE 28
|
||||
#define PragTyp_MODULE_LIST 29
|
||||
#define PragTyp_OPTIMIZE 30
|
||||
#define PragTyp_PAGE_SIZE 31
|
||||
#define PragTyp_PRAGMA_LIST 32
|
||||
#define PragTyp_SECURE_DELETE 33
|
||||
#define PragTyp_SHRINK_MEMORY 34
|
||||
#define PragTyp_SOFT_HEAP_LIMIT 35
|
||||
#define PragTyp_SYNCHRONOUS 36
|
||||
#define PragTyp_TABLE_INFO 37
|
||||
#define PragTyp_TEMP_STORE 38
|
||||
#define PragTyp_TEMP_STORE_DIRECTORY 39
|
||||
#define PragTyp_THREADS 40
|
||||
#define PragTyp_WAL_AUTOCHECKPOINT 41
|
||||
#define PragTyp_WAL_CHECKPOINT 42
|
||||
#define PragTyp_LOCK_STATUS 43
|
||||
#define PragTyp_STATS 44
|
||||
|
||||
/* Property flags associated with various pragma. */
|
||||
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
|
||||
@@ -139,6 +140,11 @@ static const PragmaName aPragmaName[] = {
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#endif
|
||||
{/* zName: */ "analysis_limit",
|
||||
/* ePragTyp: */ PragTyp_ANALYSIS_LIMIT,
|
||||
/* ePragFlg: */ PragFlg_Result0,
|
||||
/* ColNames: */ 0, 0,
|
||||
/* iArg: */ 0 },
|
||||
#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
|
||||
{/* zName: */ "application_id",
|
||||
/* ePragTyp: */ PragTyp_HEADER_VALUE,
|
||||
@@ -639,4 +645,4 @@ static const PragmaName aPragmaName[] = {
|
||||
/* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
|
||||
#endif
|
||||
};
|
||||
/* Number of pragmas: 66 on by default, 76 total. */
|
||||
/* Number of pragmas: 67 on by default, 77 total. */
|
||||
|
||||
+1
-4
@@ -6663,7 +6663,6 @@ int sqlite3Select(
|
||||
|
||||
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
|
||||
else {
|
||||
#ifndef SQLITE_OMIT_BTREECOUNT
|
||||
Table *pTab;
|
||||
if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
|
||||
/* If isSimpleCount() returns a pointer to a Table structure, then
|
||||
@@ -6721,9 +6720,7 @@ int sqlite3Select(
|
||||
sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
|
||||
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
|
||||
explainSimpleCount(pParse, pTab, pBest);
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_BTREECOUNT */
|
||||
{
|
||||
}else{
|
||||
int regAcc = 0; /* "populate accumulators" flag */
|
||||
|
||||
/* If there are accumulator registers but no min() or max() functions
|
||||
|
||||
@@ -1539,6 +1539,7 @@ struct sqlite3 {
|
||||
BusyHandler busyHandler; /* Busy callback */
|
||||
Db aDbStatic[2]; /* Static space for the 2 default backends */
|
||||
Savepoint *pSavepoint; /* List of active savepoints */
|
||||
int nAnalysisLimit; /* Number of index rows to ANALYZE */
|
||||
int busyTimeout; /* Busy handler timeout, in msec */
|
||||
int nSavepoint; /* Number of non-transaction savepoints */
|
||||
int nStatement; /* Number of nested statement-transactions */
|
||||
|
||||
+13
-7
@@ -3187,13 +3187,16 @@ case OP_MakeRecord: {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Opcode: Count P1 P2 * * *
|
||||
/* Opcode: Count P1 P2 p3 * *
|
||||
** Synopsis: r[P2]=count()
|
||||
**
|
||||
** Store the number of entries (an integer value) in the table or index
|
||||
** opened by cursor P1 in register P2
|
||||
** opened by cursor P1 in register P2.
|
||||
**
|
||||
** If P3==0, then an exact count is obtained, which involves visiting
|
||||
** every btree page of the table. But if P3 is non-zero, an estimate
|
||||
** is returned based on the current cursor position.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_BTREECOUNT
|
||||
case OP_Count: { /* out2 */
|
||||
i64 nEntry;
|
||||
BtCursor *pCrsr;
|
||||
@@ -3201,14 +3204,17 @@ case OP_Count: { /* out2 */
|
||||
assert( p->apCsr[pOp->p1]->eCurType==CURTYPE_BTREE );
|
||||
pCrsr = p->apCsr[pOp->p1]->uc.pCursor;
|
||||
assert( pCrsr );
|
||||
nEntry = 0; /* Not needed. Only used to silence a warning. */
|
||||
rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
if( pOp->p3 ){
|
||||
nEntry = sqlite3BtreeRowCountEst(pCrsr);
|
||||
}else{
|
||||
nEntry = 0; /* Not needed. Only used to silence a warning. */
|
||||
rc = sqlite3BtreeCount(db, pCrsr, &nEntry);
|
||||
if( rc ) goto abort_due_to_error;
|
||||
}
|
||||
pOut = out2Prerelease(p, pOp);
|
||||
pOut->u.i = nEntry;
|
||||
goto check_for_interrupt;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Opcode: Savepoint P1 * * P4 *
|
||||
**
|
||||
|
||||
@@ -382,6 +382,9 @@ set pragma_def {
|
||||
NAME: threads
|
||||
FLAG: Result0
|
||||
|
||||
NAME: analysis_limit
|
||||
FLAG: Result0
|
||||
|
||||
NAME: optimize
|
||||
FLAG: Result1 NeedSchema
|
||||
|
||||
|
||||
Reference in New Issue
Block a user