| 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 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 | 441 |
| 442 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | 442 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 443 { | 443 { |
| 444 u8 *pSpace; /* Allocated space not yet assigned */ | 444 u8 *pSpace; /* Allocated space not yet assigned */ |
| 445 int i; /* Used to iterate through p->aSample[] */ | 445 int i; /* Used to iterate through p->aSample[] */ |
| 446 | 446 |
| 447 p->iGet = -1; | 447 p->iGet = -1; |
| 448 p->mxSample = mxSample; | 448 p->mxSample = mxSample; |
| 449 p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1); | 449 p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1); |
| 450 p->current.anLt = &p->current.anEq[nColUp]; | 450 p->current.anLt = &p->current.anEq[nColUp]; |
| 451 p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[2])*0xd0944565; | 451 p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]); |
| 452 | 452 |
| 453 /* Set up the Stat4Accum.a[] and aBest[] arrays */ | 453 /* Set up the Stat4Accum.a[] and aBest[] arrays */ |
| 454 p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; | 454 p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; |
| 455 p->aBest = &p->a[mxSample]; | 455 p->aBest = &p->a[mxSample]; |
| 456 pSpace = (u8*)(&p->a[mxSample+nCol]); | 456 pSpace = (u8*)(&p->a[mxSample+nCol]); |
| 457 for(i=0; i<(mxSample+nCol); i++){ | 457 for(i=0; i<(mxSample+nCol); i++){ |
| 458 p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); | 458 p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 459 p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); | 459 p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 460 p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); | 460 p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 461 } | 461 } |
| (...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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_Function, 0, regStat4, regOut); | 946 sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4, regOut); |
| 947 sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF); | 947 sqlite3VdbeChangeP4(v, -1, (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 */ |
| (...skipping 26 matching lines...) Expand all Loading... |
| 983 | 983 |
| 984 pParse->nMem = MAX(pParse->nMem, iMem); | 984 pParse->nMem = MAX(pParse->nMem, iMem); |
| 985 v = sqlite3GetVdbe(pParse); | 985 v = sqlite3GetVdbe(pParse); |
| 986 if( v==0 || NEVER(pTab==0) ){ | 986 if( v==0 || NEVER(pTab==0) ){ |
| 987 return; | 987 return; |
| 988 } | 988 } |
| 989 if( pTab->tnum==0 ){ | 989 if( pTab->tnum==0 ){ |
| 990 /* Do not gather statistics on views or virtual tables */ | 990 /* Do not gather statistics on views or virtual tables */ |
| 991 return; | 991 return; |
| 992 } | 992 } |
| 993 if( sqlite3_strnicmp(pTab->zName, "sqlite_", 7)==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].zName ) ){ |
| 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++; |
| 1014 iIdxCur = iTab++; | 1014 iIdxCur = iTab++; |
| 1015 pParse->nTab = MAX(pParse->nTab, iTab); | 1015 pParse->nTab = MAX(pParse->nTab, iTab); |
| 1016 sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); | 1016 sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 1017 sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); | 1017 sqlite3VdbeLoadString(v, regTabname, pTab->zName); |
| 1018 | 1018 |
| 1019 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | 1019 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 1020 int nCol; /* Number of columns in pIdx. "N" */ | 1020 int nCol; /* Number of columns in pIdx. "N" */ |
| 1021 int addrRewind; /* Address of "OP_Rewind iIdxCur" */ | 1021 int addrRewind; /* Address of "OP_Rewind iIdxCur" */ |
| 1022 int addrNextRow; /* Address of "next_row:" */ | 1022 int addrNextRow; /* Address of "next_row:" */ |
| 1023 const char *zIdxName; /* Name of the index */ | 1023 const char *zIdxName; /* Name of the index */ |
| 1024 int nColTest; /* Number of columns to test for changes */ | 1024 int nColTest; /* Number of columns to test for changes */ |
| 1025 | 1025 |
| 1026 if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; | 1026 if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 1027 if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; | 1027 if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 1028 if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ | 1028 if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){ |
| 1029 nCol = pIdx->nKeyCol; | 1029 nCol = pIdx->nKeyCol; |
| 1030 zIdxName = pTab->zName; | 1030 zIdxName = pTab->zName; |
| 1031 nColTest = nCol - 1; | 1031 nColTest = nCol - 1; |
| 1032 }else{ | 1032 }else{ |
| 1033 nCol = pIdx->nColumn; | 1033 nCol = pIdx->nColumn; |
| 1034 zIdxName = pIdx->zName; | 1034 zIdxName = pIdx->zName; |
| 1035 nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; | 1035 nColTest = pIdx->uniqNotNull ? pIdx->nKeyCol-1 : nCol-1; |
| 1036 } | 1036 } |
| 1037 | 1037 |
| 1038 /* Populate the register containing the index name. */ | 1038 /* Populate the register containing the index name. */ |
| 1039 sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0); | 1039 sqlite3VdbeLoadString(v, regIdxname, zIdxName); |
| 1040 VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); | 1040 VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); |
| 1041 | 1041 |
| 1042 /* | 1042 /* |
| 1043 ** Pseudo-code for loop that calls stat_push(): | 1043 ** Pseudo-code for loop that calls stat_push(): |
| 1044 ** | 1044 ** |
| 1045 ** Rewind csr | 1045 ** Rewind csr |
| 1046 ** if eof(csr) goto end_of_scan; | 1046 ** if eof(csr) goto end_of_scan; |
| 1047 ** regChng = 0 | 1047 ** regChng = 0 |
| 1048 ** goto chng_addr_0; | 1048 ** goto chng_addr_0; |
| 1049 ** | 1049 ** |
| (...skipping 41 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_Function, 0, regStat4+1, regStat4); | 1101 sqlite3VdbeAddOp3(v, OP_Function0, 0, regStat4+1, regStat4); |
| 1102 sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF); | 1102 sqlite3VdbeChangeP4(v, -1, (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 ** |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 for(i=0; i<nColTest; i++){ | 1143 for(i=0; i<nColTest; i++){ |
| 1144 char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); | 1144 char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); |
| 1145 sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); | 1145 sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); |
| 1146 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); | 1146 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); |
| 1147 aGotoChng[i] = | 1147 aGotoChng[i] = |
| 1148 sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); | 1148 sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); |
| 1149 sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); | 1149 sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); |
| 1150 VdbeCoverage(v); | 1150 VdbeCoverage(v); |
| 1151 } | 1151 } |
| 1152 sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); | 1152 sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); |
| 1153 sqlite3VdbeAddOp2(v, OP_Goto, 0, endDistinctTest); | 1153 sqlite3VdbeGoto(v, endDistinctTest); |
| 1154 | 1154 |
| 1155 | 1155 |
| 1156 /* | 1156 /* |
| 1157 ** chng_addr_0: | 1157 ** chng_addr_0: |
| 1158 ** regPrev(0) = idx(0) | 1158 ** regPrev(0) = idx(0) |
| 1159 ** chng_addr_1: | 1159 ** chng_addr_1: |
| 1160 ** regPrev(1) = idx(1) | 1160 ** regPrev(1) = idx(1) |
| 1161 ** ... | 1161 ** ... |
| 1162 */ | 1162 */ |
| 1163 sqlite3VdbeJumpHere(v, addrNextRow-1); | 1163 sqlite3VdbeJumpHere(v, addrNextRow-1); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1179 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | 1179 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 1180 assert( regRowid==(regStat4+2) ); | 1180 assert( regRowid==(regStat4+2) ); |
| 1181 if( HasRowid(pTab) ){ | 1181 if( HasRowid(pTab) ){ |
| 1182 sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); | 1182 sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); |
| 1183 }else{ | 1183 }else{ |
| 1184 Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); | 1184 Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); |
| 1185 int j, k, regKey; | 1185 int j, k, regKey; |
| 1186 regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); | 1186 regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); |
| 1187 for(j=0; j<pPk->nKeyCol; j++){ | 1187 for(j=0; j<pPk->nKeyCol; j++){ |
| 1188 k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); | 1188 k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]); |
| 1189 assert( k>=0 && k<pTab->nCol ); |
| 1189 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); | 1190 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); |
| 1190 VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); | 1191 VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); |
| 1191 } | 1192 } |
| 1192 sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); | 1193 sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); |
| 1193 sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); | 1194 sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); |
| 1194 } | 1195 } |
| 1195 #endif | 1196 #endif |
| 1196 assert( regChng==(regStat4+1) ); | 1197 assert( regChng==(regStat4+1) ); |
| 1197 sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp); | 1198 sqlite3VdbeAddOp3(v, OP_Function0, 1, regStat4, regTemp); |
| 1198 sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); | 1199 sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); |
| 1199 sqlite3VdbeChangeP5(v, 2+IsStat34); | 1200 sqlite3VdbeChangeP5(v, 2+IsStat34); |
| 1200 sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); | 1201 sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); |
| 1201 | 1202 |
| 1202 /* Add the entry to the stat1 table. */ | 1203 /* Add the entry to the stat1 table. */ |
| 1203 callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); | 1204 callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); |
| 1204 assert( "BBB"[0]==SQLITE_AFF_TEXT ); | 1205 assert( "BBB"[0]==SQLITE_AFF_TEXT ); |
| 1205 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); | 1206 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); |
| 1206 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); | 1207 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
| 1207 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); | 1208 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1228 VdbeCoverage(v); | 1229 VdbeCoverage(v); |
| 1229 callStatGet(v, regStat4, STAT_GET_NEQ, regEq); | 1230 callStatGet(v, regStat4, STAT_GET_NEQ, regEq); |
| 1230 callStatGet(v, regStat4, STAT_GET_NLT, regLt); | 1231 callStatGet(v, regStat4, STAT_GET_NLT, regLt); |
| 1231 callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); | 1232 callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); |
| 1232 sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); | 1233 sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); |
| 1233 /* We know that the regSampleRowid row exists because it was read by | 1234 /* We know that the regSampleRowid row exists because it was read by |
| 1234 ** the previous loop. Thus the not-found jump of seekOp will never | 1235 ** the previous loop. Thus the not-found jump of seekOp will never |
| 1235 ** be taken */ | 1236 ** be taken */ |
| 1236 VdbeCoverageNeverTaken(v); | 1237 VdbeCoverageNeverTaken(v); |
| 1237 #ifdef SQLITE_ENABLE_STAT3 | 1238 #ifdef SQLITE_ENABLE_STAT3 |
| 1238 sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, | 1239 sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, 0, regSample); |
| 1239 pIdx->aiColumn[0], regSample); | |
| 1240 #else | 1240 #else |
| 1241 for(i=0; i<nCol; i++){ | 1241 for(i=0; i<nCol; i++){ |
| 1242 i16 iCol = pIdx->aiColumn[i]; | 1242 sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iTabCur, i, regCol+i); |
| 1243 sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i); | |
| 1244 } | 1243 } |
| 1245 sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample); | 1244 sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample); |
| 1246 #endif | 1245 #endif |
| 1247 sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp); | 1246 sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp); |
| 1248 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); | 1247 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); |
| 1249 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid); | 1248 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid); |
| 1250 sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */ | 1249 sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */ |
| 1251 sqlite3VdbeJumpHere(v, addrIsNull); | 1250 sqlite3VdbeJumpHere(v, addrIsNull); |
| 1252 } | 1251 } |
| 1253 #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ | 1252 #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1450 if( aLog ) aLog[i] = sqlite3LogEst(v); | 1449 if( aLog ) aLog[i] = sqlite3LogEst(v); |
| 1451 #else | 1450 #else |
| 1452 assert( aOut==0 ); | 1451 assert( aOut==0 ); |
| 1453 UNUSED_PARAMETER(aOut); | 1452 UNUSED_PARAMETER(aOut); |
| 1454 assert( aLog!=0 ); | 1453 assert( aLog!=0 ); |
| 1455 aLog[i] = sqlite3LogEst(v); | 1454 aLog[i] = sqlite3LogEst(v); |
| 1456 #endif | 1455 #endif |
| 1457 if( *z==' ' ) z++; | 1456 if( *z==' ' ) z++; |
| 1458 } | 1457 } |
| 1459 #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 | 1458 #ifndef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 1460 assert( pIndex!=0 ); | 1459 assert( pIndex!=0 ); { |
| 1461 #else | 1460 #else |
| 1462 if( pIndex ) | 1461 if( pIndex ){ |
| 1463 #endif | 1462 #endif |
| 1464 while( z[0] ){ | 1463 pIndex->bUnordered = 0; |
| 1465 if( sqlite3_strglob("unordered*", z)==0 ){ | 1464 pIndex->noSkipScan = 0; |
| 1466 pIndex->bUnordered = 1; | 1465 while( z[0] ){ |
| 1467 }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ | 1466 if( sqlite3_strglob("unordered*", z)==0 ){ |
| 1468 pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); | 1467 pIndex->bUnordered = 1; |
| 1468 }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ |
| 1469 pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); |
| 1470 }else if( sqlite3_strglob("noskipscan*", z)==0 ){ |
| 1471 pIndex->noSkipScan = 1; |
| 1472 } |
| 1473 #ifdef SQLITE_ENABLE_COSTMULT |
| 1474 else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ |
| 1475 pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); |
| 1476 } |
| 1477 #endif |
| 1478 while( z[0]!=0 && z[0]!=' ' ) z++; |
| 1479 while( z[0]==' ' ) z++; |
| 1469 } | 1480 } |
| 1470 #ifdef SQLITE_ENABLE_COSTMULT | |
| 1471 else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ | |
| 1472 pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); | |
| 1473 } | |
| 1474 #endif | |
| 1475 while( z[0]!=0 && z[0]!=' ' ) z++; | |
| 1476 while( z[0]==' ' ) z++; | |
| 1477 } | 1481 } |
| 1478 } | 1482 } |
| 1479 | 1483 |
| 1480 /* | 1484 /* |
| 1481 ** This callback is invoked once for each index when reading the | 1485 ** This callback is invoked once for each index when reading the |
| 1482 ** sqlite_stat1 table. | 1486 ** sqlite_stat1 table. |
| 1483 ** | 1487 ** |
| 1484 ** argv[0] = name of the table | 1488 ** argv[0] = name of the table |
| 1485 ** argv[1] = name of the index (might be NULL) | 1489 ** argv[1] = name of the index (might be NULL) |
| 1486 ** argv[2] = results of analysis - on integer for each column | 1490 ** argv[2] = results of analysis - on integer for each column |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1507 if( argv[1]==0 ){ | 1511 if( argv[1]==0 ){ |
| 1508 pIndex = 0; | 1512 pIndex = 0; |
| 1509 }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){ | 1513 }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){ |
| 1510 pIndex = sqlite3PrimaryKeyIndex(pTable); | 1514 pIndex = sqlite3PrimaryKeyIndex(pTable); |
| 1511 }else{ | 1515 }else{ |
| 1512 pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); | 1516 pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 1513 } | 1517 } |
| 1514 z = argv[2]; | 1518 z = argv[2]; |
| 1515 | 1519 |
| 1516 if( pIndex ){ | 1520 if( pIndex ){ |
| 1521 tRowcnt *aiRowEst = 0; |
| 1517 int nCol = pIndex->nKeyCol+1; | 1522 int nCol = pIndex->nKeyCol+1; |
| 1518 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | 1523 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 1519 tRowcnt * const aiRowEst = pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero( | 1524 /* Index.aiRowEst may already be set here if there are duplicate |
| 1520 sizeof(tRowcnt) * nCol | 1525 ** sqlite_stat1 entries for this index. In that case just clobber |
| 1521 ); | 1526 ** the old data with the new instead of allocating a new array. */ |
| 1522 if( aiRowEst==0 ) pInfo->db->mallocFailed = 1; | 1527 if( pIndex->aiRowEst==0 ){ |
| 1523 #else | 1528 pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); |
| 1524 tRowcnt * const aiRowEst = 0; | 1529 if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1; |
| 1530 } |
| 1531 aiRowEst = pIndex->aiRowEst; |
| 1525 #endif | 1532 #endif |
| 1526 pIndex->bUnordered = 0; | 1533 pIndex->bUnordered = 0; |
| 1527 decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); | 1534 decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex); |
| 1528 if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; | 1535 if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0]; |
| 1529 }else{ | 1536 }else{ |
| 1530 Index fakeIdx; | 1537 Index fakeIdx; |
| 1531 fakeIdx.szIdxRow = pTable->szTabRow; | 1538 fakeIdx.szIdxRow = pTable->szTabRow; |
| 1532 #ifdef SQLITE_ENABLE_COSTMULT | 1539 #ifdef SQLITE_ENABLE_COSTMULT |
| 1533 fakeIdx.pTable = pTable; | 1540 fakeIdx.pTable = pTable; |
| 1534 #endif | 1541 #endif |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1592 i64 nDist100; /* Number of distinct values in index */ | 1599 i64 nDist100; /* Number of distinct values in index */ |
| 1593 | 1600 |
| 1594 if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){ | 1601 if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){ |
| 1595 nRow = pFinal->anLt[iCol]; | 1602 nRow = pFinal->anLt[iCol]; |
| 1596 nDist100 = (i64)100 * pFinal->anDLt[iCol]; | 1603 nDist100 = (i64)100 * pFinal->anDLt[iCol]; |
| 1597 nSample--; | 1604 nSample--; |
| 1598 }else{ | 1605 }else{ |
| 1599 nRow = pIdx->aiRowEst[0]; | 1606 nRow = pIdx->aiRowEst[0]; |
| 1600 nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1]; | 1607 nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1]; |
| 1601 } | 1608 } |
| 1609 pIdx->nRowEst0 = nRow; |
| 1602 | 1610 |
| 1603 /* Set nSum to the number of distinct (iCol+1) field prefixes that | 1611 /* Set nSum to the number of distinct (iCol+1) field prefixes that |
| 1604 ** occur in the stat4 table for this index. Set sumEq to the sum of | 1612 ** occur in the stat4 table for this index. Set sumEq to the sum of |
| 1605 ** the nEq values for column iCol for the same set (adding the value | 1613 ** the nEq values for column iCol for the same set (adding the value |
| 1606 ** only once where there exist duplicate prefixes). */ | 1614 ** only once where there exist duplicate prefixes). */ |
| 1607 for(i=0; i<nSample; i++){ | 1615 for(i=0; i<nSample; i++){ |
| 1608 if( i==(pIdx->nSample-1) | 1616 if( i==(pIdx->nSample-1) |
| 1609 || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] | 1617 || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] |
| 1610 ){ | 1618 ){ |
| 1611 sumEq += aSample[i].anEq[iCol]; | 1619 sumEq += aSample[i].anEq[iCol]; |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1853 if( zSql==0 ){ | 1861 if( zSql==0 ){ |
| 1854 rc = SQLITE_NOMEM; | 1862 rc = SQLITE_NOMEM; |
| 1855 }else{ | 1863 }else{ |
| 1856 rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); | 1864 rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); |
| 1857 sqlite3DbFree(db, zSql); | 1865 sqlite3DbFree(db, zSql); |
| 1858 } | 1866 } |
| 1859 | 1867 |
| 1860 | 1868 |
| 1861 /* Load the statistics from the sqlite_stat4 table. */ | 1869 /* Load the statistics from the sqlite_stat4 table. */ |
| 1862 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | 1870 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 1863 if( rc==SQLITE_OK ){ | 1871 if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){ |
| 1864 int lookasideEnabled = db->lookaside.bEnabled; | 1872 int lookasideEnabled = db->lookaside.bEnabled; |
| 1865 db->lookaside.bEnabled = 0; | 1873 db->lookaside.bEnabled = 0; |
| 1866 rc = loadStat4(db, sInfo.zDatabase); | 1874 rc = loadStat4(db, sInfo.zDatabase); |
| 1867 db->lookaside.bEnabled = lookasideEnabled; | 1875 db->lookaside.bEnabled = lookasideEnabled; |
| 1868 } | 1876 } |
| 1869 for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ | 1877 for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
| 1870 Index *pIdx = sqliteHashData(i); | 1878 Index *pIdx = sqliteHashData(i); |
| 1871 sqlite3_free(pIdx->aiRowEst); | 1879 sqlite3_free(pIdx->aiRowEst); |
| 1872 pIdx->aiRowEst = 0; | 1880 pIdx->aiRowEst = 0; |
| 1873 } | 1881 } |
| 1874 #endif | 1882 #endif |
| 1875 | 1883 |
| 1876 if( rc==SQLITE_NOMEM ){ | 1884 if( rc==SQLITE_NOMEM ){ |
| 1877 db->mallocFailed = 1; | 1885 db->mallocFailed = 1; |
| 1878 } | 1886 } |
| 1879 return rc; | 1887 return rc; |
| 1880 } | 1888 } |
| 1881 | 1889 |
| 1882 | 1890 |
| 1883 #endif /* SQLITE_OMIT_ANALYZE */ | 1891 #endif /* SQLITE_OMIT_ANALYZE */ |
| OLD | NEW |