/ Check-in [0a4200f95c]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improved EXPLAIN indentation of a loop in the ANALYZE logic for STAT4. Mark the not-found jump of a seek operation in that loop as never taken.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0a4200f95cf46ad620b9fd91f4444114a0c74730
User & Date: drh 2014-03-06 13:38:37
Context
2014-03-06
18:16
Do not run corruptH.test in mmap mode. check-in: c0d54b4e41 user: dan tags: trunk
13:48
Merge the latest 3.8.4 tweaks from trunk. check-in: 1ed463d918 user: drh tags: sessions
13:38
Improved EXPLAIN indentation of a loop in the ANALYZE logic for STAT4. Mark the not-found jump of a seek operation in that loop as never taken. check-in: 0a4200f95c user: drh tags: trunk
12:36
Remove a branch that is never taken from where.c. check-in: 4a4997221f user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/analyze.c.

  1174   1174         callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
  1175   1175         addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
  1176   1176         VdbeCoverage(v);
  1177   1177         callStatGet(v, regStat4, STAT_GET_NEQ, regEq);
  1178   1178         callStatGet(v, regStat4, STAT_GET_NLT, regLt);
  1179   1179         callStatGet(v, regStat4, STAT_GET_NDLT, regDLt);
  1180   1180         sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0);
  1181         -      VdbeCoverage(v);
         1181  +      /* We know that the regSampleRowid row exists because it was read by
         1182  +      ** the previous loop.  Thus the not-found jump of seekOp will never
         1183  +      ** be taken */
         1184  +      VdbeCoverageNeverTaken(v);
  1182   1185   #ifdef SQLITE_ENABLE_STAT3
  1183   1186         sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, 
  1184   1187                                         pIdx->aiColumn[0], regSample);
  1185   1188   #else
  1186   1189         for(i=0; i<nCol; i++){
  1187   1190           i16 iCol = pIdx->aiColumn[i];
  1188   1191           sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
  1189   1192         }
  1190   1193         sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
  1191   1194   #endif
  1192   1195         sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
  1193   1196         sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
  1194   1197         sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
  1195         -      sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
         1198  +      sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
  1196   1199         sqlite3VdbeJumpHere(v, addrIsNull);
  1197   1200       }
  1198   1201   #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
  1199   1202   
  1200   1203       /* End of analysis */
  1201   1204       sqlite3VdbeJumpHere(v, addrRewind);
  1202   1205       sqlite3DbFree(db, aGotoChng);

Changes to src/shell.c.

  1180   1180   **     * For each "Next", "Prev", "VNext" or "VPrev" instruction, indent
  1181   1181   **       all opcodes that occur between the p2 jump destination and the opcode
  1182   1182   **       itself by 2 spaces.
  1183   1183   **
  1184   1184   **     * For each "Goto", if the jump destination is earlier in the program
  1185   1185   **       and ends on one of:
  1186   1186   **          Yield  SeekGt  SeekLt  RowSetRead  Rewind
         1187  +**       or if the P1 parameter is one instead of zero,
  1187   1188   **       then indent all opcodes between the earlier instruction
  1188   1189   **       and "Goto" by 2 spaces.
  1189   1190   */
  1190   1191   static void explain_data_prepare(struct callback_data *p, sqlite3_stmt *pSql){
  1191   1192     const char *zSql;               /* The text of the SQL statement */
  1192   1193     const char *z;                  /* Used to check if this is an EXPLAIN */
  1193   1194     int *abYield = 0;               /* True if op is an OP_Yield */
................................................................................
  1227   1228       abYield[iOp] = str_in_array(zOp, azYield);
  1228   1229       p->aiIndent[iOp] = 0;
  1229   1230       p->nIndent = iOp+1;
  1230   1231   
  1231   1232       if( str_in_array(zOp, azNext) ){
  1232   1233         for(i=p2op; i<iOp; i++) p->aiIndent[i] += 2;
  1233   1234       }
  1234         -    if( str_in_array(zOp, azGoto) && p2op<p->nIndent && abYield[p2op] ){
         1235  +    if( str_in_array(zOp, azGoto) && p2op<p->nIndent
         1236  +     && (abYield[p2op] || sqlite3_column_int(pSql, 2))
         1237  +    ){
  1235   1238         for(i=p2op+1; i<iOp; i++) p->aiIndent[i] += 2;
  1236   1239       }
  1237   1240     }
  1238   1241   
  1239   1242     p->iIndent = 0;
  1240   1243     sqlite3_free(abYield);
  1241   1244     sqlite3_reset(pSql);

Changes to src/vdbe.c.

   667    667   
   668    668   /* Opcode:  Goto * P2 * * *
   669    669   **
   670    670   ** An unconditional jump to address P2.
   671    671   ** The next instruction executed will be 
   672    672   ** the one at index P2 from the beginning of
   673    673   ** the program.
          674  +**
          675  +** The P1 parameter is not actually used by this opcode.  However, it
          676  +** is sometimes set to 1 instead of 0 as a hint to the command-line shell
          677  +** that this Goto is the bottom of a loop and that the lines from P2 down
          678  +** to the current line should be indented for EXPLAIN output.
   674    679   */
   675    680   case OP_Goto: {             /* jump */
   676    681     pc = pOp->p2 - 1;
   677    682   
   678    683     /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
   679    684     ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
   680    685     ** completion.  Check to see if sqlite3_interrupt() has been called