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 |