/ Check-in [6fdae9a6]
Login

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

Overview
Comment:Reduce the number of branches that need to be tested in the explainIndexRange() function of where.c.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: 6fdae9a635a43e1bf7e4a480de1413064732c6b0
User & Date: drh 2010-11-12 15:36:00
Context
2010-11-12
17:41
Add EXPLAIN QUERY PLAN test cases to check that the examples in the documentation work. check-in: 85fdad85 user: dan tags: experimental
15:36
Reduce the number of branches that need to be tested in the explainIndexRange() function of where.c. check-in: 6fdae9a6 user: drh tags: experimental
2010-11-11
17:48
Use "COMPOUND" instead of "COMPOSITE" in the EXPLAIN QUERY PLAN output to describe UNION, UNION ALL, EXCEPT and INTERSECT operations. check-in: 28643b85 user: dan tags: experimental
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/where.c.

  3127   3127       }
  3128   3128     }
  3129   3129     *pzAff = zAff;
  3130   3130     return regBase;
  3131   3131   }
  3132   3132   
  3133   3133   #ifndef SQLITE_OMIT_EXPLAIN
         3134  +/*
         3135  +** This routine is a helper for explainIndexRange() below
         3136  +**
         3137  +** pStr holds the text of an expression that we are building up one term
         3138  +** at a time.  This routine adds a new term to the end of the expression.
         3139  +** Terms are separated by AND so add the "AND" text for second and subsequent
         3140  +** terms only.
         3141  +*/
         3142  +static void explainAppendTerm(
         3143  +  StrAccum *pStr,             /* The text expression being built */
         3144  +  int iTerm,                  /* Index of this term.  First is zero */
         3145  +  const char *zColumn,        /* Name of the column */
         3146  +  const char *zOp             /* Name of the operator */
         3147  +){
         3148  +  if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5);
         3149  +  sqlite3StrAccumAppend(pStr, zColumn, -1);
         3150  +  sqlite3StrAccumAppend(pStr, zOp, 1);
         3151  +  sqlite3StrAccumAppend(pStr, "?", 1);
         3152  +}
         3153  +
  3134   3154   /*
  3135   3155   ** Argument pLevel describes a strategy for scanning table pTab. This 
  3136   3156   ** function returns a pointer to a string buffer containing a description
  3137   3157   ** of the subset of table rows scanned by the strategy in the form of an
  3138   3158   ** SQL expression. Or, if all rows are scanned, NULL is returned.
  3139   3159   **
  3140   3160   ** For example, if the query:
................................................................................
  3150   3170   ** It is the responsibility of the caller to free the buffer when it is
  3151   3171   ** no longer required.
  3152   3172   */
  3153   3173   static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){
  3154   3174     WherePlan *pPlan = &pLevel->plan;
  3155   3175     Index *pIndex = pPlan->u.pIdx;
  3156   3176     int nEq = pPlan->nEq;
  3157         -  char *zRet = 0;
  3158         -  int i;
         3177  +  int i, j;
         3178  +  Column *aCol = pTab->aCol;
         3179  +  int *aiColumn = pIndex->aiColumn;
         3180  +  StrAccum txt;
  3159   3181   
         3182  +  if( nEq==0 && (pPlan->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
         3183  +    return 0;
         3184  +  }
         3185  +  sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
         3186  +  sqlite3StrAccumAppend(&txt, " (", 2);
  3160   3187     for(i=0; i<nEq; i++){
  3161         -    zRet = sqlite3MAppendf(db, zRet, 
  3162         -        "%s%s%s=?", (zRet?zRet:""), (zRet?" AND ":""), 
  3163         -        pTab->aCol[pIndex->aiColumn[i]].zName
  3164         -    );
         3188  +    explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "=");
  3165   3189     }
  3166   3190   
         3191  +  j = i;
  3167   3192     if( pPlan->wsFlags&WHERE_BTM_LIMIT ){
  3168         -    zRet = sqlite3MAppendf(db, zRet,
  3169         -        "%s%s%s>?", (zRet?zRet:""), (zRet?" AND ":""),
  3170         -        pTab->aCol[pIndex->aiColumn[i]].zName
  3171         -    );
         3193  +    explainAppendTerm(&txt, i++, aCol[aiColumn[j]].zName, ">");
  3172   3194     }
  3173   3195     if( pPlan->wsFlags&WHERE_TOP_LIMIT ){
  3174         -    zRet = sqlite3MAppendf(db, zRet,
  3175         -        "%s%s%s<?", (zRet?zRet:""), (zRet?" AND ":""), 
  3176         -        pTab->aCol[pIndex->aiColumn[i]].zName
  3177         -    );
         3196  +    explainAppendTerm(&txt, i, aCol[aiColumn[j]].zName, "<");
  3178   3197     }
  3179         -
  3180         -  if( zRet ){
  3181         -    zRet = sqlite3MAppendf(db, zRet, " (%s)", zRet);
  3182         -  }
  3183         -
  3184         -  return zRet;
         3198  +  sqlite3StrAccumAppend(&txt, ")", 1);
         3199  +  return sqlite3StrAccumFinish(&txt);
  3185   3200   }
  3186   3201   
  3187   3202   /*
  3188   3203   ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
  3189   3204   ** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
  3190   3205   ** record is added to the output to describe the table scan strategy in 
  3191   3206   ** pLevel.