/ 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 Unified Diffs Ignore Whitespace Patch

Changes to src/where.c.

3127
3128
3129
3130
3131
3132
3133




















3134
3135
3136
3137
3138
3139
3140
....
3150
3151
3152
3153
3154
3155
3156
3157
3158



3159





3160
3161
3162
3163
3164

3165
3166

3167
3168
3169
3170
3171

3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184


3185
3186
3187
3188
3189
3190
3191
    }
  }
  *pzAff = zAff;
  return regBase;
}

#ifndef SQLITE_OMIT_EXPLAIN




















/*
** Argument pLevel describes a strategy for scanning table pTab. This 
** function returns a pointer to a string buffer containing a description
** of the subset of table rows scanned by the strategy in the form of an
** SQL expression. Or, if all rows are scanned, NULL is returned.
**
** For example, if the query:
................................................................................
** It is the responsibility of the caller to free the buffer when it is
** no longer required.
*/
static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){
  WherePlan *pPlan = &pLevel->plan;
  Index *pIndex = pPlan->u.pIdx;
  int nEq = pPlan->nEq;
  char *zRet = 0;
  int i;









  for(i=0; i<nEq; i++){
    zRet = sqlite3MAppendf(db, zRet, 
        "%s%s%s=?", (zRet?zRet:""), (zRet?" AND ":""), 
        pTab->aCol[pIndex->aiColumn[i]].zName
    );

  }


  if( pPlan->wsFlags&WHERE_BTM_LIMIT ){
    zRet = sqlite3MAppendf(db, zRet,
        "%s%s%s>?", (zRet?zRet:""), (zRet?" AND ":""),
        pTab->aCol[pIndex->aiColumn[i]].zName
    );

  }
  if( pPlan->wsFlags&WHERE_TOP_LIMIT ){
    zRet = sqlite3MAppendf(db, zRet,
        "%s%s%s<?", (zRet?zRet:""), (zRet?" AND ":""), 
        pTab->aCol[pIndex->aiColumn[i]].zName
    );
  }

  if( zRet ){
    zRet = sqlite3MAppendf(db, zRet, " (%s)", zRet);
  }

  return zRet;


}

/*
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
** record is added to the output to describe the table scan strategy in 
** pLevel.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







<
|
>
>
>

>
>
>
>
>

<
<
<
<
>


>

<
<
<
<
>


<
<
|
<

<
<
<
<
<
<
>
>







3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
....
3170
3171
3172
3173
3174
3175
3176

3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187




3188
3189
3190
3191
3192




3193
3194
3195


3196

3197






3198
3199
3200
3201
3202
3203
3204
3205
3206
    }
  }
  *pzAff = zAff;
  return regBase;
}

#ifndef SQLITE_OMIT_EXPLAIN
/*
** This routine is a helper for explainIndexRange() below
**
** pStr holds the text of an expression that we are building up one term
** at a time.  This routine adds a new term to the end of the expression.
** Terms are separated by AND so add the "AND" text for second and subsequent
** terms only.
*/
static void explainAppendTerm(
  StrAccum *pStr,             /* The text expression being built */
  int iTerm,                  /* Index of this term.  First is zero */
  const char *zColumn,        /* Name of the column */
  const char *zOp             /* Name of the operator */
){
  if( iTerm ) sqlite3StrAccumAppend(pStr, " AND ", 5);
  sqlite3StrAccumAppend(pStr, zColumn, -1);
  sqlite3StrAccumAppend(pStr, zOp, 1);
  sqlite3StrAccumAppend(pStr, "?", 1);
}

/*
** Argument pLevel describes a strategy for scanning table pTab. This 
** function returns a pointer to a string buffer containing a description
** of the subset of table rows scanned by the strategy in the form of an
** SQL expression. Or, if all rows are scanned, NULL is returned.
**
** For example, if the query:
................................................................................
** It is the responsibility of the caller to free the buffer when it is
** no longer required.
*/
static char *explainIndexRange(sqlite3 *db, WhereLevel *pLevel, Table *pTab){
  WherePlan *pPlan = &pLevel->plan;
  Index *pIndex = pPlan->u.pIdx;
  int nEq = pPlan->nEq;

  int i, j;
  Column *aCol = pTab->aCol;
  int *aiColumn = pIndex->aiColumn;
  StrAccum txt;

  if( nEq==0 && (pPlan->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
    return 0;
  }
  sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
  sqlite3StrAccumAppend(&txt, " (", 2);
  for(i=0; i<nEq; i++){




    explainAppendTerm(&txt, i, aCol[aiColumn[i]].zName, "=");
  }

  j = i;
  if( pPlan->wsFlags&WHERE_BTM_LIMIT ){




    explainAppendTerm(&txt, i++, aCol[aiColumn[j]].zName, ">");
  }
  if( pPlan->wsFlags&WHERE_TOP_LIMIT ){


    explainAppendTerm(&txt, i, aCol[aiColumn[j]].zName, "<");

  }






  sqlite3StrAccumAppend(&txt, ")", 1);
  return sqlite3StrAccumFinish(&txt);
}

/*
** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
** record is added to the output to describe the table scan strategy in 
** pLevel.