OLD | NEW |
1 /* | 1 /* |
2 ** 2005-07-08 | 2 ** 2005-07-08 |
3 ** | 3 ** |
4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
6 ** | 6 ** |
7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
10 ** | 10 ** |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 assert( sqlite3BtreeHoldsAllMutexes(db) ); | 203 assert( sqlite3BtreeHoldsAllMutexes(db) ); |
204 assert( sqlite3VdbeDb(v)==db ); | 204 assert( sqlite3VdbeDb(v)==db ); |
205 pDb = &db->aDb[iDb]; | 205 pDb = &db->aDb[iDb]; |
206 | 206 |
207 /* Create new statistic tables if they do not exist, or clear them | 207 /* Create new statistic tables if they do not exist, or clear them |
208 ** if they do already exist. | 208 ** if they do already exist. |
209 */ | 209 */ |
210 for(i=0; i<ArraySize(aTable); i++){ | 210 for(i=0; i<ArraySize(aTable); i++){ |
211 const char *zTab = aTable[i].zName; | 211 const char *zTab = aTable[i].zName; |
212 Table *pStat; | 212 Table *pStat; |
213 if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){ | 213 if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){ |
214 if( aTable[i].zCols ){ | 214 if( aTable[i].zCols ){ |
215 /* The sqlite_statN table does not exist. Create it. Note that a | 215 /* The sqlite_statN table does not exist. Create it. Note that a |
216 ** side-effect of the CREATE TABLE statement is to leave the rootpage | 216 ** side-effect of the CREATE TABLE statement is to leave the rootpage |
217 ** of the new table in register pParse->regRoot. This is important | 217 ** of the new table in register pParse->regRoot. This is important |
218 ** because the OpenWrite opcode below will be needing it. */ | 218 ** because the OpenWrite opcode below will be needing it. */ |
219 sqlite3NestedParse(pParse, | 219 sqlite3NestedParse(pParse, |
220 "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols | 220 "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols |
221 ); | 221 ); |
222 aRoot[i] = pParse->regRoot; | 222 aRoot[i] = pParse->regRoot; |
223 aCreateTbl[i] = OPFLAG_P2ISREG; | 223 aCreateTbl[i] = OPFLAG_P2ISREG; |
224 } | 224 } |
225 }else{ | 225 }else{ |
226 /* The table already exists. If zWhere is not NULL, delete all entries | 226 /* The table already exists. If zWhere is not NULL, delete all entries |
227 ** associated with the table zWhere. If zWhere is NULL, delete the | 227 ** associated with the table zWhere. If zWhere is NULL, delete the |
228 ** entire contents of the table. */ | 228 ** entire contents of the table. */ |
229 aRoot[i] = pStat->tnum; | 229 aRoot[i] = pStat->tnum; |
230 aCreateTbl[i] = 0; | 230 aCreateTbl[i] = 0; |
231 sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); | 231 sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); |
232 if( zWhere ){ | 232 if( zWhere ){ |
233 sqlite3NestedParse(pParse, | 233 sqlite3NestedParse(pParse, |
234 "DELETE FROM %Q.%s WHERE %s=%Q", | 234 "DELETE FROM %Q.%s WHERE %s=%Q", |
235 pDb->zName, zTab, zWhereType, zWhere | 235 pDb->zDbSName, zTab, zWhereType, zWhere |
236 ); | 236 ); |
237 }else{ | 237 }else{ |
238 /* The sqlite_stat[134] table already exists. Delete all rows. */ | 238 /* The sqlite_stat[134] table already exists. Delete all rows. */ |
239 sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); | 239 sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); |
240 } | 240 } |
241 } | 241 } |
242 } | 242 } |
243 | 243 |
244 /* Open the sqlite_stat[134] tables for writing. */ | 244 /* Open the sqlite_stat[134] tables for writing. */ |
245 for(i=0; aTable[i].zCols; i++){ | 245 for(i=0; aTable[i].zCols; i++){ |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 } | 306 } |
307 } | 307 } |
308 #endif | 308 #endif |
309 | 309 |
310 /* Initialize the BLOB value of a ROWID | 310 /* Initialize the BLOB value of a ROWID |
311 */ | 311 */ |
312 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | 312 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
313 static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){ | 313 static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){ |
314 assert( db!=0 ); | 314 assert( db!=0 ); |
315 if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); | 315 if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); |
316 p->u.aRowid = sqlite3DbMallocRaw(db, n); | 316 p->u.aRowid = sqlite3DbMallocRawNN(db, n); |
317 if( p->u.aRowid ){ | 317 if( p->u.aRowid ){ |
318 p->nRowid = n; | 318 p->nRowid = n; |
319 memcpy(p->u.aRowid, pData, n); | 319 memcpy(p->u.aRowid, pData, n); |
320 }else{ | 320 }else{ |
321 p->nRowid = 0; | 321 p->nRowid = 0; |
322 } | 322 } |
323 } | 323 } |
324 #endif | 324 #endif |
325 | 325 |
326 /* Initialize the INTEGER value of a ROWID. | 326 /* Initialize the INTEGER value of a ROWID. |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
471 ** only the pointer (the 2nd parameter) matters. The size of the object | 471 ** only the pointer (the 2nd parameter) matters. The size of the object |
472 ** (given by the 3rd parameter) is never used and can be any positive | 472 ** (given by the 3rd parameter) is never used and can be any positive |
473 ** value. */ | 473 ** value. */ |
474 sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor); | 474 sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor); |
475 } | 475 } |
476 static const FuncDef statInitFuncdef = { | 476 static const FuncDef statInitFuncdef = { |
477 2+IsStat34, /* nArg */ | 477 2+IsStat34, /* nArg */ |
478 SQLITE_UTF8, /* funcFlags */ | 478 SQLITE_UTF8, /* funcFlags */ |
479 0, /* pUserData */ | 479 0, /* pUserData */ |
480 0, /* pNext */ | 480 0, /* pNext */ |
481 statInit, /* xFunc */ | 481 statInit, /* xSFunc */ |
482 0, /* xStep */ | |
483 0, /* xFinalize */ | 482 0, /* xFinalize */ |
484 "stat_init", /* zName */ | 483 "stat_init", /* zName */ |
485 0, /* pHash */ | 484 {0} |
486 0 /* pDestructor */ | |
487 }; | 485 }; |
488 | 486 |
489 #ifdef SQLITE_ENABLE_STAT4 | 487 #ifdef SQLITE_ENABLE_STAT4 |
490 /* | 488 /* |
491 ** pNew and pOld are both candidate non-periodic samples selected for | 489 ** pNew and pOld are both candidate non-periodic samples selected for |
492 ** the same column (pNew->iCol==pOld->iCol). Ignoring this column and | 490 ** the same column (pNew->iCol==pOld->iCol). Ignoring this column and |
493 ** considering only any trailing columns and the sample hash value, this | 491 ** considering only any trailing columns and the sample hash value, this |
494 ** function returns true if sample pNew is to be preferred over pOld. | 492 ** function returns true if sample pNew is to be preferred over pOld. |
495 ** In other words, if we assume that the cardinalities of the selected | 493 ** In other words, if we assume that the cardinalities of the selected |
496 ** column for pNew and pOld are equal, is pNew to be preferred over pOld. | 494 ** column for pNew and pOld are equal, is pNew to be preferred over pOld. |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
772 } | 770 } |
773 } | 771 } |
774 } | 772 } |
775 #endif | 773 #endif |
776 } | 774 } |
777 static const FuncDef statPushFuncdef = { | 775 static const FuncDef statPushFuncdef = { |
778 2+IsStat34, /* nArg */ | 776 2+IsStat34, /* nArg */ |
779 SQLITE_UTF8, /* funcFlags */ | 777 SQLITE_UTF8, /* funcFlags */ |
780 0, /* pUserData */ | 778 0, /* pUserData */ |
781 0, /* pNext */ | 779 0, /* pNext */ |
782 statPush, /* xFunc */ | 780 statPush, /* xSFunc */ |
783 0, /* xStep */ | |
784 0, /* xFinalize */ | 781 0, /* xFinalize */ |
785 "stat_push", /* zName */ | 782 "stat_push", /* zName */ |
786 0, /* pHash */ | 783 {0} |
787 0 /* pDestructor */ | |
788 }; | 784 }; |
789 | 785 |
790 #define STAT_GET_STAT1 0 /* "stat" column of stat1 table */ | 786 #define STAT_GET_STAT1 0 /* "stat" column of stat1 table */ |
791 #define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */ | 787 #define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */ |
792 #define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */ | 788 #define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */ |
793 #define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ | 789 #define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ |
794 #define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ | 790 #define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ |
795 | 791 |
796 /* | 792 /* |
797 ** Implementation of the stat_get(P,J) SQL function. This routine is | 793 ** Implementation of the stat_get(P,J) SQL function. This routine is |
798 ** used to query statistical information that has been gathered into | 794 ** used to query statistical information that has been gathered into |
799 ** the Stat4Accum object by prior calls to stat_push(). The P parameter | 795 ** the Stat4Accum object by prior calls to stat_push(). The P parameter |
800 ** has type BLOB but it is really just a pointer to the Stat4Accum object. | 796 ** has type BLOB but it is really just a pointer to the Stat4Accum object. |
801 ** The content to returned is determined by the parameter J | 797 ** The content to returned is determined by the parameter J |
802 ** which is one of the STAT_GET_xxxx values defined above. | 798 ** which is one of the STAT_GET_xxxx values defined above. |
803 ** | 799 ** |
| 800 ** The stat_get(P,J) function is not available to generic SQL. It is |
| 801 ** inserted as part of a manually constructed bytecode program. (See |
| 802 ** the callStatGet() routine below.) It is guaranteed that the P |
| 803 ** parameter will always be a poiner to a Stat4Accum object, never a |
| 804 ** NULL. |
| 805 ** |
804 ** If neither STAT3 nor STAT4 are enabled, then J is always | 806 ** If neither STAT3 nor STAT4 are enabled, then J is always |
805 ** STAT_GET_STAT1 and is hence omitted and this routine becomes | 807 ** STAT_GET_STAT1 and is hence omitted and this routine becomes |
806 ** a one-parameter function, stat_get(P), that always returns the | 808 ** a one-parameter function, stat_get(P), that always returns the |
807 ** stat1 table entry information. | 809 ** stat1 table entry information. |
808 */ | 810 */ |
809 static void statGet( | 811 static void statGet( |
810 sqlite3_context *context, | 812 sqlite3_context *context, |
811 int argc, | 813 int argc, |
812 sqlite3_value **argv | 814 sqlite3_value **argv |
813 ){ | 815 ){ |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
919 #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ | 921 #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
920 #ifndef SQLITE_DEBUG | 922 #ifndef SQLITE_DEBUG |
921 UNUSED_PARAMETER( argc ); | 923 UNUSED_PARAMETER( argc ); |
922 #endif | 924 #endif |
923 } | 925 } |
924 static const FuncDef statGetFuncdef = { | 926 static const FuncDef statGetFuncdef = { |
925 1+IsStat34, /* nArg */ | 927 1+IsStat34, /* nArg */ |
926 SQLITE_UTF8, /* funcFlags */ | 928 SQLITE_UTF8, /* funcFlags */ |
927 0, /* pUserData */ | 929 0, /* pUserData */ |
928 0, /* pNext */ | 930 0, /* pNext */ |
929 statGet, /* xFunc */ | 931 statGet, /* xSFunc */ |
930 0, /* xStep */ | |
931 0, /* xFinalize */ | 932 0, /* xFinalize */ |
932 "stat_get", /* zName */ | 933 "stat_get", /* zName */ |
933 0, /* pHash */ | 934 {0} |
934 0 /* pDestructor */ | |
935 }; | 935 }; |
936 | 936 |
937 static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ | 937 static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ |
938 assert( regOut!=regStat4 && regOut!=regStat4+1 ); | 938 assert( regOut!=regStat4 && regOut!=regStat4+1 ); |
939 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | 939 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
940 sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1); | 940 sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1); |
941 #elif SQLITE_DEBUG | 941 #elif SQLITE_DEBUG |
942 assert( iParam==STAT_GET_STAT1 ); | 942 assert( iParam==STAT_GET_STAT1 ); |
943 #else | 943 #else |
944 UNUSED_PARAMETER( iParam ); | 944 UNUSED_PARAMETER( iParam ); |
945 #endif | 945 #endif |
946 sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4, regOut); | 946 sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4, regOut, |
947 sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF); | 947 (char*)&statGetFuncdef, P4_FUNCDEF); |
948 sqlite3VdbeChangeP5(v, 1 + IsStat34); | 948 sqlite3VdbeChangeP5(v, 1 + IsStat34); |
949 } | 949 } |
950 | 950 |
951 /* | 951 /* |
952 ** Generate code to do an analysis of all indices associated with | 952 ** Generate code to do an analysis of all indices associated with |
953 ** a single table. | 953 ** a single table. |
954 */ | 954 */ |
955 static void analyzeOneTable( | 955 static void analyzeOneTable( |
956 Parse *pParse, /* Parser context */ | 956 Parse *pParse, /* Parser context */ |
957 Table *pTab, /* Table whose indices are to be analyzed */ | 957 Table *pTab, /* Table whose indices are to be analyzed */ |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){ | 993 if( sqlite3_strlike("sqlite_%", pTab->zName, 0)==0 ){ |
994 /* Do not gather statistics on system tables */ | 994 /* Do not gather statistics on system tables */ |
995 return; | 995 return; |
996 } | 996 } |
997 assert( sqlite3BtreeHoldsAllMutexes(db) ); | 997 assert( sqlite3BtreeHoldsAllMutexes(db) ); |
998 iDb = sqlite3SchemaToIndex(db, pTab->pSchema); | 998 iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
999 assert( iDb>=0 ); | 999 assert( iDb>=0 ); |
1000 assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); | 1000 assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
1001 #ifndef SQLITE_OMIT_AUTHORIZATION | 1001 #ifndef SQLITE_OMIT_AUTHORIZATION |
1002 if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, | 1002 if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, |
1003 db->aDb[iDb].zName ) ){ | 1003 db->aDb[iDb].zDbSName ) ){ |
1004 return; | 1004 return; |
1005 } | 1005 } |
1006 #endif | 1006 #endif |
1007 | 1007 |
1008 /* Establish a read-lock on the table at the shared-cache level. | 1008 /* Establish a read-lock on the table at the shared-cache level. |
1009 ** Open a read-only cursor on the table. Also allocate a cursor number | 1009 ** Open a read-only cursor on the table. Also allocate a cursor number |
1010 ** to use for scanning indexes (iIdxCur). No index cursor is opened at | 1010 ** to use for scanning indexes (iIdxCur). No index cursor is opened at |
1011 ** this time though. */ | 1011 ** this time though. */ |
1012 sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); | 1012 sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
1013 iTabCur = iTab++; | 1013 iTabCur = iTab++; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 ** (3) the number of rows in the index, | 1091 ** (3) the number of rows in the index, |
1092 ** | 1092 ** |
1093 ** | 1093 ** |
1094 ** The third argument is only used for STAT3 and STAT4 | 1094 ** The third argument is only used for STAT3 and STAT4 |
1095 */ | 1095 */ |
1096 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | 1096 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
1097 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); | 1097 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); |
1098 #endif | 1098 #endif |
1099 sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); | 1099 sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); |
1100 sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2); | 1100 sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2); |
1101 sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4+1, regStat4); | 1101 sqlite3VdbeAddOp4(v, OP_Function0, 0, regStat4+1, regStat4, |
1102 sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF); | 1102 (char*)&statInitFuncdef, P4_FUNCDEF); |
1103 sqlite3VdbeChangeP5(v, 2+IsStat34); | 1103 sqlite3VdbeChangeP5(v, 2+IsStat34); |
1104 | 1104 |
1105 /* Implementation of the following: | 1105 /* Implementation of the following: |
1106 ** | 1106 ** |
1107 ** Rewind csr | 1107 ** Rewind csr |
1108 ** if eof(csr) goto end_of_scan; | 1108 ** if eof(csr) goto end_of_scan; |
1109 ** regChng = 0 | 1109 ** regChng = 0 |
1110 ** goto next_push_0; | 1110 ** goto next_push_0; |
1111 ** | 1111 ** |
1112 */ | 1112 */ |
1113 addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); | 1113 addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); |
1114 VdbeCoverage(v); | 1114 VdbeCoverage(v); |
1115 sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); | 1115 sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); |
1116 addrNextRow = sqlite3VdbeCurrentAddr(v); | 1116 addrNextRow = sqlite3VdbeCurrentAddr(v); |
1117 | 1117 |
1118 if( nColTest>0 ){ | 1118 if( nColTest>0 ){ |
1119 int endDistinctTest = sqlite3VdbeMakeLabel(v); | 1119 int endDistinctTest = sqlite3VdbeMakeLabel(v); |
1120 int *aGotoChng; /* Array of jump instruction addresses */ | 1120 int *aGotoChng; /* Array of jump instruction addresses */ |
1121 aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*nColTest); | 1121 aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest); |
1122 if( aGotoChng==0 ) continue; | 1122 if( aGotoChng==0 ) continue; |
1123 | 1123 |
1124 /* | 1124 /* |
1125 ** next_row: | 1125 ** next_row: |
1126 ** regChng = 0 | 1126 ** regChng = 0 |
1127 ** if( idx(0) != regPrev(0) ) goto chng_addr_0 | 1127 ** if( idx(0) != regPrev(0) ) goto chng_addr_0 |
1128 ** regChng = 1 | 1128 ** regChng = 1 |
1129 ** if( idx(1) != regPrev(1) ) goto chng_addr_1 | 1129 ** if( idx(1) != regPrev(1) ) goto chng_addr_1 |
1130 ** ... | 1130 ** ... |
1131 ** regChng = N | 1131 ** regChng = N |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); | 1188 k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); |
1189 assert( k>=0 && k<pTab->nCol ); | 1189 assert( k>=0 && k<pTab->nCol ); |
1190 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); | 1190 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); |
1191 VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); | 1191 VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); |
1192 } | 1192 } |
1193 sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); | 1193 sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); |
1194 sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); | 1194 sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); |
1195 } | 1195 } |
1196 #endif | 1196 #endif |
1197 assert( regChng==(regStat4+1) ); | 1197 assert( regChng==(regStat4+1) ); |
1198 sqlite3VdbeAddOp3(v, OP_Function0, 1, regStat4, regTemp); | 1198 sqlite3VdbeAddOp4(v, OP_Function0, 1, regStat4, regTemp, |
1199 sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); | 1199 (char*)&statPushFuncdef, P4_FUNCDEF); |
1200 sqlite3VdbeChangeP5(v, 2+IsStat34); | 1200 sqlite3VdbeChangeP5(v, 2+IsStat34); |
1201 sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); | 1201 sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); |
1202 | 1202 |
1203 /* Add the entry to the stat1 table. */ | 1203 /* Add the entry to the stat1 table. */ |
1204 callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); | 1204 callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); |
1205 assert( "BBB"[0]==SQLITE_AFF_TEXT ); | 1205 assert( "BBB"[0]==SQLITE_AFF_TEXT ); |
1206 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); | 1206 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); |
1207 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); | 1207 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
1208 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); | 1208 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); |
1209 sqlite3VdbeChangeP5(v, OPFLAG_APPEND); | 1209 sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1383 }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){ | 1383 }else if( (pTab = sqlite3LocateTable(pParse, 0, z, 0))!=0 ){ |
1384 analyzeTable(pParse, pTab, 0); | 1384 analyzeTable(pParse, pTab, 0); |
1385 } | 1385 } |
1386 sqlite3DbFree(db, z); | 1386 sqlite3DbFree(db, z); |
1387 } | 1387 } |
1388 } | 1388 } |
1389 }else{ | 1389 }else{ |
1390 /* Form 3: Analyze the fully qualified table name */ | 1390 /* Form 3: Analyze the fully qualified table name */ |
1391 iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); | 1391 iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); |
1392 if( iDb>=0 ){ | 1392 if( iDb>=0 ){ |
1393 zDb = db->aDb[iDb].zName; | 1393 zDb = db->aDb[iDb].zDbSName; |
1394 z = sqlite3NameFromToken(db, pTableName); | 1394 z = sqlite3NameFromToken(db, pTableName); |
1395 if( z ){ | 1395 if( z ){ |
1396 if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ | 1396 if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ |
1397 analyzeTable(pParse, pIdx->pTable, pIdx); | 1397 analyzeTable(pParse, pIdx->pTable, pIdx); |
1398 }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){ | 1398 }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){ |
1399 analyzeTable(pParse, pTab, 0); | 1399 analyzeTable(pParse, pTab, 0); |
1400 } | 1400 } |
1401 sqlite3DbFree(db, z); | 1401 sqlite3DbFree(db, z); |
1402 } | 1402 } |
1403 } | 1403 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1519 | 1519 |
1520 if( pIndex ){ | 1520 if( pIndex ){ |
1521 tRowcnt *aiRowEst = 0; | 1521 tRowcnt *aiRowEst = 0; |
1522 int nCol = pIndex->nKeyCol+1; | 1522 int nCol = pIndex->nKeyCol+1; |
1523 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | 1523 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
1524 /* Index.aiRowEst may already be set here if there are duplicate | 1524 /* Index.aiRowEst may already be set here if there are duplicate |
1525 ** sqlite_stat1 entries for this index. In that case just clobber | 1525 ** sqlite_stat1 entries for this index. In that case just clobber |
1526 ** the old data with the new instead of allocating a new array. */ | 1526 ** the old data with the new instead of allocating a new array. */ |
1527 if( pIndex->aiRowEst==0 ){ | 1527 if( pIndex->aiRowEst==0 ){ |
1528 pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); | 1528 pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); |
1529 if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1; | 1529 if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db); |
1530 } | 1530 } |
1531 aiRowEst = pIndex->aiRowEst; | 1531 aiRowEst = pIndex->aiRowEst; |
1532 #endif | 1532 #endif |
1533 pIndex->bUnordered = 0; | 1533 pIndex->bUnordered = 0; |
1534 decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); | 1534 decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); |
1535 if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; | 1535 if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
1536 }else{ | 1536 }else{ |
1537 Index fakeIdx; | 1537 Index fakeIdx; |
1538 fakeIdx.szIdxRow = pTable->szTabRow; | 1538 fakeIdx.szIdxRow = pTable->szTabRow; |
1539 #ifdef SQLITE_ENABLE_COSTMULT | 1539 #ifdef SQLITE_ENABLE_COSTMULT |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1614 ** only once where there exist duplicate prefixes). */ | 1614 ** only once where there exist duplicate prefixes). */ |
1615 for(i=0; i<nSample; i++){ | 1615 for(i=0; i<nSample; i++){ |
1616 if( i==(pIdx->nSample-1) | 1616 if( i==(pIdx->nSample-1) |
1617 || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] | 1617 || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] |
1618 ){ | 1618 ){ |
1619 sumEq += aSample[i].anEq[iCol]; | 1619 sumEq += aSample[i].anEq[iCol]; |
1620 nSum100 += 100; | 1620 nSum100 += 100; |
1621 } | 1621 } |
1622 } | 1622 } |
1623 | 1623 |
1624 if( nDist100>nSum100 ){ | 1624 if( nDist100>nSum100 && sumEq<nRow ){ |
1625 avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100); | 1625 avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100); |
1626 } | 1626 } |
1627 if( avgEq==0 ) avgEq = 1; | 1627 if( avgEq==0 ) avgEq = 1; |
1628 pIdx->aAvgEq[iCol] = avgEq; | 1628 pIdx->aAvgEq[iCol] = avgEq; |
1629 } | 1629 } |
1630 } | 1630 } |
1631 } | 1631 } |
1632 | 1632 |
1633 /* | 1633 /* |
1634 ** Look up an index by name. Or, if the name of a WITHOUT ROWID table | 1634 ** Look up an index by name. Or, if the name of a WITHOUT ROWID table |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1666 const char *zSql1, /* SQL statement 1 (see above) */ | 1666 const char *zSql1, /* SQL statement 1 (see above) */ |
1667 const char *zSql2, /* SQL statement 2 (see above) */ | 1667 const char *zSql2, /* SQL statement 2 (see above) */ |
1668 const char *zDb /* Database name (e.g. "main") */ | 1668 const char *zDb /* Database name (e.g. "main") */ |
1669 ){ | 1669 ){ |
1670 int rc; /* Result codes from subroutines */ | 1670 int rc; /* Result codes from subroutines */ |
1671 sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ | 1671 sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ |
1672 char *zSql; /* Text of the SQL statement */ | 1672 char *zSql; /* Text of the SQL statement */ |
1673 Index *pPrevIdx = 0; /* Previous index in the loop */ | 1673 Index *pPrevIdx = 0; /* Previous index in the loop */ |
1674 IndexSample *pSample; /* A slot in pIdx->aSample[] */ | 1674 IndexSample *pSample; /* A slot in pIdx->aSample[] */ |
1675 | 1675 |
1676 assert( db->lookaside.bEnabled==0 ); | 1676 assert( db->lookaside.bDisable ); |
1677 zSql = sqlite3MPrintf(db, zSql1, zDb); | 1677 zSql = sqlite3MPrintf(db, zSql1, zDb); |
1678 if( !zSql ){ | 1678 if( !zSql ){ |
1679 return SQLITE_NOMEM; | 1679 return SQLITE_NOMEM_BKPT; |
1680 } | 1680 } |
1681 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); | 1681 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
1682 sqlite3DbFree(db, zSql); | 1682 sqlite3DbFree(db, zSql); |
1683 if( rc ) return rc; | 1683 if( rc ) return rc; |
1684 | 1684 |
1685 while( sqlite3_step(pStmt)==SQLITE_ROW ){ | 1685 while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
1686 int nIdxCol = 1; /* Number of columns in stat4 records */ | 1686 int nIdxCol = 1; /* Number of columns in stat4 records */ |
1687 | 1687 |
1688 char *zIndex; /* Index name */ | 1688 char *zIndex; /* Index name */ |
1689 Index *pIdx; /* Pointer to the index object */ | 1689 Index *pIdx; /* Pointer to the index object */ |
(...skipping 19 matching lines...) Expand all Loading... |
1709 } | 1709 } |
1710 } | 1710 } |
1711 pIdx->nSampleCol = nIdxCol; | 1711 pIdx->nSampleCol = nIdxCol; |
1712 nByte = sizeof(IndexSample) * nSample; | 1712 nByte = sizeof(IndexSample) * nSample; |
1713 nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; | 1713 nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; |
1714 nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ | 1714 nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ |
1715 | 1715 |
1716 pIdx->aSample = sqlite3DbMallocZero(db, nByte); | 1716 pIdx->aSample = sqlite3DbMallocZero(db, nByte); |
1717 if( pIdx->aSample==0 ){ | 1717 if( pIdx->aSample==0 ){ |
1718 sqlite3_finalize(pStmt); | 1718 sqlite3_finalize(pStmt); |
1719 return SQLITE_NOMEM; | 1719 return SQLITE_NOMEM_BKPT; |
1720 } | 1720 } |
1721 pSpace = (tRowcnt*)&pIdx->aSample[nSample]; | 1721 pSpace = (tRowcnt*)&pIdx->aSample[nSample]; |
1722 pIdx->aAvgEq = pSpace; pSpace += nIdxCol; | 1722 pIdx->aAvgEq = pSpace; pSpace += nIdxCol; |
1723 for(i=0; i<nSample; i++){ | 1723 for(i=0; i<nSample; i++){ |
1724 pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol; | 1724 pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol; |
1725 pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; | 1725 pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; |
1726 pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol; | 1726 pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol; |
1727 } | 1727 } |
1728 assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) ); | 1728 assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) ); |
1729 } | 1729 } |
1730 rc = sqlite3_finalize(pStmt); | 1730 rc = sqlite3_finalize(pStmt); |
1731 if( rc ) return rc; | 1731 if( rc ) return rc; |
1732 | 1732 |
1733 zSql = sqlite3MPrintf(db, zSql2, zDb); | 1733 zSql = sqlite3MPrintf(db, zSql2, zDb); |
1734 if( !zSql ){ | 1734 if( !zSql ){ |
1735 return SQLITE_NOMEM; | 1735 return SQLITE_NOMEM_BKPT; |
1736 } | 1736 } |
1737 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); | 1737 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
1738 sqlite3DbFree(db, zSql); | 1738 sqlite3DbFree(db, zSql); |
1739 if( rc ) return rc; | 1739 if( rc ) return rc; |
1740 | 1740 |
1741 while( sqlite3_step(pStmt)==SQLITE_ROW ){ | 1741 while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
1742 char *zIndex; /* Index name */ | 1742 char *zIndex; /* Index name */ |
1743 Index *pIdx; /* Pointer to the index object */ | 1743 Index *pIdx; /* Pointer to the index object */ |
1744 int nCol = 1; /* Number of columns in index */ | 1744 int nCol = 1; /* Number of columns in index */ |
1745 | 1745 |
(...skipping 17 matching lines...) Expand all Loading... |
1763 /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. | 1763 /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. |
1764 ** This is in case the sample record is corrupted. In that case, the | 1764 ** This is in case the sample record is corrupted. In that case, the |
1765 ** sqlite3VdbeRecordCompare() may read up to two varints past the | 1765 ** sqlite3VdbeRecordCompare() may read up to two varints past the |
1766 ** end of the allocated buffer before it realizes it is dealing with | 1766 ** end of the allocated buffer before it realizes it is dealing with |
1767 ** a corrupt record. Adding the two 0x00 bytes prevents this from causing | 1767 ** a corrupt record. Adding the two 0x00 bytes prevents this from causing |
1768 ** a buffer overread. */ | 1768 ** a buffer overread. */ |
1769 pSample->n = sqlite3_column_bytes(pStmt, 4); | 1769 pSample->n = sqlite3_column_bytes(pStmt, 4); |
1770 pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); | 1770 pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); |
1771 if( pSample->p==0 ){ | 1771 if( pSample->p==0 ){ |
1772 sqlite3_finalize(pStmt); | 1772 sqlite3_finalize(pStmt); |
1773 return SQLITE_NOMEM; | 1773 return SQLITE_NOMEM_BKPT; |
1774 } | 1774 } |
1775 memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); | 1775 if( pSample->n ){ |
| 1776 memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); |
| 1777 } |
1776 pIdx->nSample++; | 1778 pIdx->nSample++; |
1777 } | 1779 } |
1778 rc = sqlite3_finalize(pStmt); | 1780 rc = sqlite3_finalize(pStmt); |
1779 if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); | 1781 if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); |
1780 return rc; | 1782 return rc; |
1781 } | 1783 } |
1782 | 1784 |
1783 /* | 1785 /* |
1784 ** Load content from the sqlite_stat4 and sqlite_stat3 tables into | 1786 ** Load content from the sqlite_stat4 and sqlite_stat3 tables into |
1785 ** the Index.aSample[] arrays of all indices. | 1787 ** the Index.aSample[] arrays of all indices. |
1786 */ | 1788 */ |
1787 static int loadStat4(sqlite3 *db, const char *zDb){ | 1789 static int loadStat4(sqlite3 *db, const char *zDb){ |
1788 int rc = SQLITE_OK; /* Result codes from subroutines */ | 1790 int rc = SQLITE_OK; /* Result codes from subroutines */ |
1789 | 1791 |
1790 assert( db->lookaside.bEnabled==0 ); | 1792 assert( db->lookaside.bDisable ); |
1791 if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ | 1793 if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ |
1792 rc = loadStatTbl(db, 0, | 1794 rc = loadStatTbl(db, 0, |
1793 "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", | 1795 "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", |
1794 "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", | 1796 "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", |
1795 zDb | 1797 zDb |
1796 ); | 1798 ); |
1797 } | 1799 } |
1798 | 1800 |
1799 if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){ | 1801 if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){ |
1800 rc = loadStatTbl(db, 1, | 1802 rc = loadStatTbl(db, 1, |
(...skipping 24 matching lines...) Expand all Loading... |
1825 ** table (if it is present) before returning. | 1827 ** table (if it is present) before returning. |
1826 ** | 1828 ** |
1827 ** If an OOM error occurs, this function always sets db->mallocFailed. | 1829 ** If an OOM error occurs, this function always sets db->mallocFailed. |
1828 ** This means if the caller does not care about other errors, the return | 1830 ** This means if the caller does not care about other errors, the return |
1829 ** code may be ignored. | 1831 ** code may be ignored. |
1830 */ | 1832 */ |
1831 int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ | 1833 int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ |
1832 analysisInfo sInfo; | 1834 analysisInfo sInfo; |
1833 HashElem *i; | 1835 HashElem *i; |
1834 char *zSql; | 1836 char *zSql; |
1835 int rc; | 1837 int rc = SQLITE_OK; |
1836 | 1838 |
1837 assert( iDb>=0 && iDb<db->nDb ); | 1839 assert( iDb>=0 && iDb<db->nDb ); |
1838 assert( db->aDb[iDb].pBt!=0 ); | 1840 assert( db->aDb[iDb].pBt!=0 ); |
1839 | 1841 |
1840 /* Clear any prior statistics */ | 1842 /* Clear any prior statistics */ |
1841 assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); | 1843 assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
1842 for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ | 1844 for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
1843 Index *pIdx = sqliteHashData(i); | 1845 Index *pIdx = sqliteHashData(i); |
1844 sqlite3DefaultRowEst(pIdx); | 1846 pIdx->aiRowLogEst[0] = 0; |
1845 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | 1847 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
1846 sqlite3DeleteIndexSamples(db, pIdx); | 1848 sqlite3DeleteIndexSamples(db, pIdx); |
1847 pIdx->aSample = 0; | 1849 pIdx->aSample = 0; |
1848 #endif | 1850 #endif |
1849 } | 1851 } |
1850 | 1852 |
1851 /* Check to make sure the sqlite_stat1 table exists */ | 1853 /* Load new statistics out of the sqlite_stat1 table */ |
1852 sInfo.db = db; | 1854 sInfo.db = db; |
1853 sInfo.zDatabase = db->aDb[iDb].zName; | 1855 sInfo.zDatabase = db->aDb[iDb].zDbSName; |
1854 if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){ | 1856 if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ |
1855 return SQLITE_ERROR; | 1857 zSql = sqlite3MPrintf(db, |
| 1858 "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); |
| 1859 if( zSql==0 ){ |
| 1860 rc = SQLITE_NOMEM_BKPT; |
| 1861 }else{ |
| 1862 rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); |
| 1863 sqlite3DbFree(db, zSql); |
| 1864 } |
1856 } | 1865 } |
1857 | 1866 |
1858 /* Load new statistics out of the sqlite_stat1 table */ | 1867 /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */ |
1859 zSql = sqlite3MPrintf(db, | 1868 assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
1860 "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); | 1869 for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
1861 if( zSql==0 ){ | 1870 Index *pIdx = sqliteHashData(i); |
1862 rc = SQLITE_NOMEM; | 1871 if( pIdx->aiRowLogEst[0]==0 ) sqlite3DefaultRowEst(pIdx); |
1863 }else{ | |
1864 rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); | |
1865 sqlite3DbFree(db, zSql); | |
1866 } | 1872 } |
1867 | 1873 |
1868 | |
1869 /* Load the statistics from the sqlite_stat4 table. */ | 1874 /* Load the statistics from the sqlite_stat4 table. */ |
1870 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | 1875 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
1871 if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ | 1876 if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ |
1872 int lookasideEnabled = db->lookaside.bEnabled; | 1877 db->lookaside.bDisable++; |
1873 db->lookaside.bEnabled = 0; | |
1874 rc = loadStat4(db, sInfo.zDatabase); | 1878 rc = loadStat4(db, sInfo.zDatabase); |
1875 db->lookaside.bEnabled = lookasideEnabled; | 1879 db->lookaside.bDisable--; |
1876 } | 1880 } |
1877 for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ | 1881 for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
1878 Index *pIdx = sqliteHashData(i); | 1882 Index *pIdx = sqliteHashData(i); |
1879 sqlite3_free(pIdx->aiRowEst); | 1883 sqlite3_free(pIdx->aiRowEst); |
1880 pIdx->aiRowEst = 0; | 1884 pIdx->aiRowEst = 0; |
1881 } | 1885 } |
1882 #endif | 1886 #endif |
1883 | 1887 |
1884 if( rc==SQLITE_NOMEM ){ | 1888 if( rc==SQLITE_NOMEM ){ |
1885 db->mallocFailed = 1; | 1889 sqlite3OomFault(db); |
1886 } | 1890 } |
1887 return rc; | 1891 return rc; |
1888 } | 1892 } |
1889 | 1893 |
1890 | 1894 |
1891 #endif /* SQLITE_OMIT_ANALYZE */ | 1895 #endif /* SQLITE_OMIT_ANALYZE */ |
OLD | NEW |