| 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 |