/ Check-in [4ff51325]
Login

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

Overview
Comment:Remove the SQLITE_ENABLE_TREE_EXPLAIN compile-time option. Add alternative debugging display routines: sqlite3TreeViewExpr(), sqlite3TreeViewExprList(), and sqlite3TreeViewSelect().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4ff51325d6b41d0c59e303b573700ec80c51d216
User & Date: drh 2014-09-30 12:33:33
Context
2014-09-30
13:46
Show tree diagrams of data structures in the debugging output when the 0x100 bit is set on sqlite3WhereTrace or sqlite3SelectTrace. check-in: 92e0b4bd user: drh tags: trunk
12:33
Remove the SQLITE_ENABLE_TREE_EXPLAIN compile-time option. Add alternative debugging display routines: sqlite3TreeViewExpr(), sqlite3TreeViewExprList(), and sqlite3TreeViewSelect(). check-in: 4ff51325 user: drh tags: trunk
2014-09-29
15:42
Fix the header comment in sqlite3VdbeDeletePriorOpcode(). No changes to code. check-in: 7fb16268 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

  3232   3232     assert( pExpr->op!=TK_REGISTER );
  3233   3233     sqlite3ExprCode(pParse, pExpr, target);
  3234   3234     iMem = ++pParse->nMem;
  3235   3235     sqlite3VdbeAddOp2(v, OP_Copy, target, iMem);
  3236   3236     exprToRegister(pExpr, iMem);
  3237   3237   }
  3238   3238   
  3239         -#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
         3239  +#ifdef SQLITE_DEBUG
  3240   3240   /*
  3241   3241   ** Generate a human-readable explanation of an expression tree.
  3242   3242   */
  3243         -void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
  3244         -  int op;                   /* The opcode being coded */
         3243  +void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
  3245   3244     const char *zBinOp = 0;   /* Binary operator */
  3246   3245     const char *zUniOp = 0;   /* Unary operator */
         3246  +  pView = sqlite3TreeViewPush(pView, moreToFollow);
  3247   3247     if( pExpr==0 ){
  3248         -    op = TK_NULL;
  3249         -  }else{
  3250         -    op = pExpr->op;
         3248  +    sqlite3TreeViewLine(pView, "nil");
         3249  +    sqlite3TreeViewPop(pView);
         3250  +    return;
  3251   3251     }
  3252         -  switch( op ){
         3252  +  switch( pExpr->op ){
  3253   3253       case TK_AGG_COLUMN: {
  3254         -      sqlite3ExplainPrintf(pOut, "AGG{%d:%d}",
         3254  +      sqlite3TreeViewLine(pView, "AGG{%d:%d}",
  3255   3255               pExpr->iTable, pExpr->iColumn);
  3256   3256         break;
  3257   3257       }
  3258   3258       case TK_COLUMN: {
  3259   3259         if( pExpr->iTable<0 ){
  3260   3260           /* This only happens when coding check constraints */
  3261         -        sqlite3ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn);
         3261  +        sqlite3TreeViewLine(pView, "COLUMN(%d)", pExpr->iColumn);
  3262   3262         }else{
  3263         -        sqlite3ExplainPrintf(pOut, "{%d:%d}",
         3263  +        sqlite3TreeViewLine(pView, "{%d:%d}",
  3264   3264                                pExpr->iTable, pExpr->iColumn);
  3265   3265         }
  3266   3266         break;
  3267   3267       }
  3268   3268       case TK_INTEGER: {
  3269   3269         if( pExpr->flags & EP_IntValue ){
  3270         -        sqlite3ExplainPrintf(pOut, "%d", pExpr->u.iValue);
         3270  +        sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue);
  3271   3271         }else{
  3272         -        sqlite3ExplainPrintf(pOut, "%s", pExpr->u.zToken);
         3272  +        sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken);
  3273   3273         }
  3274   3274         break;
  3275   3275       }
  3276   3276   #ifndef SQLITE_OMIT_FLOATING_POINT
  3277   3277       case TK_FLOAT: {
  3278         -      sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
         3278  +      sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
  3279   3279         break;
  3280   3280       }
  3281   3281   #endif
  3282   3282       case TK_STRING: {
  3283         -      sqlite3ExplainPrintf(pOut,"%Q", pExpr->u.zToken);
         3283  +      sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken);
  3284   3284         break;
  3285   3285       }
  3286   3286       case TK_NULL: {
  3287         -      sqlite3ExplainPrintf(pOut,"NULL");
         3287  +      sqlite3TreeViewLine(pView,"NULL");
  3288   3288         break;
  3289   3289       }
  3290   3290   #ifndef SQLITE_OMIT_BLOB_LITERAL
  3291   3291       case TK_BLOB: {
  3292         -      sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
         3292  +      sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
  3293   3293         break;
  3294   3294       }
  3295   3295   #endif
  3296   3296       case TK_VARIABLE: {
  3297         -      sqlite3ExplainPrintf(pOut,"VARIABLE(%s,%d)",
  3298         -                           pExpr->u.zToken, pExpr->iColumn);
         3297  +      sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)",
         3298  +                          pExpr->u.zToken, pExpr->iColumn);
  3299   3299         break;
  3300   3300       }
  3301   3301       case TK_REGISTER: {
  3302         -      sqlite3ExplainPrintf(pOut,"REGISTER(%d)", pExpr->iTable);
         3302  +      sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
  3303   3303         break;
  3304   3304       }
  3305   3305       case TK_AS: {
  3306         -      sqlite3ExplainExpr(pOut, pExpr->pLeft);
         3306  +      sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
         3307  +      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
         3308  +      break;
         3309  +    }
         3310  +    case TK_ID: {
         3311  +      sqlite3TreeViewLine(pView,"ID %Q", pExpr->u.zToken);
  3307   3312         break;
  3308   3313       }
  3309   3314   #ifndef SQLITE_OMIT_CAST
  3310   3315       case TK_CAST: {
  3311   3316         /* Expressions of the form:   CAST(pLeft AS token) */
  3312         -      const char *zAff = "unk";
  3313         -      switch( sqlite3AffinityType(pExpr->u.zToken, 0) ){
  3314         -        case SQLITE_AFF_TEXT:    zAff = "TEXT";     break;
  3315         -        case SQLITE_AFF_NONE:    zAff = "NONE";     break;
  3316         -        case SQLITE_AFF_NUMERIC: zAff = "NUMERIC";  break;
  3317         -        case SQLITE_AFF_INTEGER: zAff = "INTEGER";  break;
  3318         -        case SQLITE_AFF_REAL:    zAff = "REAL";     break;
  3319         -      }
  3320         -      sqlite3ExplainPrintf(pOut, "CAST-%s(", zAff);
  3321         -      sqlite3ExplainExpr(pOut, pExpr->pLeft);
  3322         -      sqlite3ExplainPrintf(pOut, ")");
         3317  +      sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
         3318  +      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
  3323   3319         break;
  3324   3320       }
  3325   3321   #endif /* SQLITE_OMIT_CAST */
  3326   3322       case TK_LT:      zBinOp = "LT";     break;
  3327   3323       case TK_LE:      zBinOp = "LE";     break;
  3328   3324       case TK_GT:      zBinOp = "GT";     break;
  3329   3325       case TK_GE:      zBinOp = "GE";     break;
................................................................................
  3348   3344       case TK_UPLUS:   zUniOp = "UPLUS";  break;
  3349   3345       case TK_BITNOT:  zUniOp = "BITNOT"; break;
  3350   3346       case TK_NOT:     zUniOp = "NOT";    break;
  3351   3347       case TK_ISNULL:  zUniOp = "ISNULL"; break;
  3352   3348       case TK_NOTNULL: zUniOp = "NOTNULL"; break;
  3353   3349   
  3354   3350       case TK_COLLATE: {
  3355         -      sqlite3ExplainExpr(pOut, pExpr->pLeft);
  3356         -      sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
         3351  +      sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
         3352  +      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
  3357   3353         break;
  3358   3354       }
  3359   3355   
  3360   3356       case TK_AGG_FUNCTION:
  3361   3357       case TK_FUNCTION: {
  3362   3358         ExprList *pFarg;       /* List of function arguments */
  3363   3359         if( ExprHasProperty(pExpr, EP_TokenOnly) ){
  3364   3360           pFarg = 0;
  3365   3361         }else{
  3366   3362           pFarg = pExpr->x.pList;
  3367   3363         }
  3368         -      if( op==TK_AGG_FUNCTION ){
  3369         -        sqlite3ExplainPrintf(pOut, "AGG_FUNCTION%d:%s(",
         3364  +      if( pExpr->op==TK_AGG_FUNCTION ){
         3365  +        sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
  3370   3366                                pExpr->op2, pExpr->u.zToken);
  3371   3367         }else{
  3372         -        sqlite3ExplainPrintf(pOut, "FUNCTION:%s(", pExpr->u.zToken);
         3368  +        sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
  3373   3369         }
  3374   3370         if( pFarg ){
  3375         -        sqlite3ExplainExprList(pOut, pFarg);
         3371  +        sqlite3TreeViewExprList(pView, pFarg, 0, 0);
  3376   3372         }
  3377         -      sqlite3ExplainPrintf(pOut, ")");
  3378   3373         break;
  3379   3374       }
  3380   3375   #ifndef SQLITE_OMIT_SUBQUERY
  3381   3376       case TK_EXISTS: {
  3382         -      sqlite3ExplainPrintf(pOut, "EXISTS(");
  3383         -      sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
  3384         -      sqlite3ExplainPrintf(pOut,")");
         3377  +      sqlite3TreeViewLine(pView, "EXISTS-expr");
         3378  +      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
  3385   3379         break;
  3386   3380       }
  3387   3381       case TK_SELECT: {
  3388         -      sqlite3ExplainPrintf(pOut, "(");
  3389         -      sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
  3390         -      sqlite3ExplainPrintf(pOut, ")");
         3382  +      sqlite3TreeViewLine(pView, "SELECT-expr");
         3383  +      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
  3391   3384         break;
  3392   3385       }
  3393   3386       case TK_IN: {
  3394         -      sqlite3ExplainPrintf(pOut, "IN(");
  3395         -      sqlite3ExplainExpr(pOut, pExpr->pLeft);
  3396         -      sqlite3ExplainPrintf(pOut, ",");
         3387  +      sqlite3TreeViewLine(pView, "IN");
         3388  +      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
  3397   3389         if( ExprHasProperty(pExpr, EP_xIsSelect) ){
  3398         -        sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
         3390  +        sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
  3399   3391         }else{
  3400         -        sqlite3ExplainExprList(pOut, pExpr->x.pList);
         3392  +        sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
  3401   3393         }
  3402         -      sqlite3ExplainPrintf(pOut, ")");
  3403   3394         break;
  3404   3395       }
  3405   3396   #endif /* SQLITE_OMIT_SUBQUERY */
  3406   3397   
  3407   3398       /*
  3408   3399       **    x BETWEEN y AND z
  3409   3400       **
................................................................................
  3415   3406       ** Y is stored in pExpr->pList->a[0].pExpr.
  3416   3407       ** Z is stored in pExpr->pList->a[1].pExpr.
  3417   3408       */
  3418   3409       case TK_BETWEEN: {
  3419   3410         Expr *pX = pExpr->pLeft;
  3420   3411         Expr *pY = pExpr->x.pList->a[0].pExpr;
  3421   3412         Expr *pZ = pExpr->x.pList->a[1].pExpr;
  3422         -      sqlite3ExplainPrintf(pOut, "BETWEEN(");
  3423         -      sqlite3ExplainExpr(pOut, pX);
  3424         -      sqlite3ExplainPrintf(pOut, ",");
  3425         -      sqlite3ExplainExpr(pOut, pY);
  3426         -      sqlite3ExplainPrintf(pOut, ",");
  3427         -      sqlite3ExplainExpr(pOut, pZ);
  3428         -      sqlite3ExplainPrintf(pOut, ")");
         3413  +      sqlite3TreeViewLine(pView, "BETWEEN");
         3414  +      sqlite3TreeViewExpr(pView, pX, 1);
         3415  +      sqlite3TreeViewExpr(pView, pY, 1);
         3416  +      sqlite3TreeViewExpr(pView, pZ, 0);
  3429   3417         break;
  3430   3418       }
  3431   3419       case TK_TRIGGER: {
  3432   3420         /* If the opcode is TK_TRIGGER, then the expression is a reference
  3433   3421         ** to a column in the new.* or old.* pseudo-tables available to
  3434   3422         ** trigger programs. In this case Expr.iTable is set to 1 for the
  3435   3423         ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
  3436   3424         ** is set to the column of the pseudo-table to read, or to -1 to
  3437   3425         ** read the rowid field.
  3438   3426         */
  3439         -      sqlite3ExplainPrintf(pOut, "%s(%d)", 
         3427  +      sqlite3TreeViewLine(pView, "%s(%d)", 
  3440   3428             pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
  3441   3429         break;
  3442   3430       }
  3443   3431       case TK_CASE: {
  3444         -      sqlite3ExplainPrintf(pOut, "CASE(");
  3445         -      sqlite3ExplainExpr(pOut, pExpr->pLeft);
  3446         -      sqlite3ExplainPrintf(pOut, ",");
  3447         -      sqlite3ExplainExprList(pOut, pExpr->x.pList);
         3432  +      sqlite3TreeViewLine(pView, "CASE");
         3433  +      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
         3434  +      sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
  3448   3435         break;
  3449   3436       }
  3450   3437   #ifndef SQLITE_OMIT_TRIGGER
  3451   3438       case TK_RAISE: {
  3452   3439         const char *zType = "unk";
  3453   3440         switch( pExpr->affinity ){
  3454   3441           case OE_Rollback:   zType = "rollback";  break;
  3455   3442           case OE_Abort:      zType = "abort";     break;
  3456   3443           case OE_Fail:       zType = "fail";      break;
  3457   3444           case OE_Ignore:     zType = "ignore";    break;
  3458   3445         }
  3459         -      sqlite3ExplainPrintf(pOut, "RAISE-%s(%s)", zType, pExpr->u.zToken);
         3446  +      sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
  3460   3447         break;
  3461   3448       }
  3462   3449   #endif
         3450  +    default: {
         3451  +      sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
         3452  +      break;
         3453  +    }
  3463   3454     }
  3464   3455     if( zBinOp ){
  3465         -    sqlite3ExplainPrintf(pOut,"%s(", zBinOp);
  3466         -    sqlite3ExplainExpr(pOut, pExpr->pLeft);
  3467         -    sqlite3ExplainPrintf(pOut,",");
  3468         -    sqlite3ExplainExpr(pOut, pExpr->pRight);
  3469         -    sqlite3ExplainPrintf(pOut,")");
         3456  +    sqlite3TreeViewLine(pView, "%s", zBinOp);
         3457  +    sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
         3458  +    sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
  3470   3459     }else if( zUniOp ){
  3471         -    sqlite3ExplainPrintf(pOut,"%s(", zUniOp);
  3472         -    sqlite3ExplainExpr(pOut, pExpr->pLeft);
  3473         -    sqlite3ExplainPrintf(pOut,")");
         3460  +    sqlite3TreeViewLine(pView, "%s", zUniOp);
         3461  +    sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
  3474   3462     }
         3463  +  sqlite3TreeViewPop(pView);
  3475   3464   }
  3476         -#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
         3465  +#endif /* SQLITE_DEBUG */
  3477   3466   
  3478         -#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
         3467  +#ifdef SQLITE_DEBUG
  3479   3468   /*
  3480   3469   ** Generate a human-readable explanation of an expression list.
  3481   3470   */
  3482         -void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){
         3471  +void sqlite3TreeViewExprList(
         3472  +  TreeView *pView,
         3473  +  const ExprList *pList,
         3474  +  u8 moreToFollow,
         3475  +  const char *zLabel
         3476  +){
  3483   3477     int i;
  3484         -  if( pList==0 || pList->nExpr==0 ){
  3485         -    sqlite3ExplainPrintf(pOut, "(empty-list)");
  3486         -    return;
  3487         -  }else if( pList->nExpr==1 ){
  3488         -    sqlite3ExplainExpr(pOut, pList->a[0].pExpr);
         3478  +  pView = sqlite3TreeViewPush(pView, moreToFollow);
         3479  +  if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
         3480  +  if( pList==0 ){
         3481  +    sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
  3489   3482     }else{
  3490         -    sqlite3ExplainPush(pOut);
         3483  +    sqlite3TreeViewLine(pView, "%s", zLabel);
  3491   3484       for(i=0; i<pList->nExpr; i++){
  3492         -      sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
  3493         -      sqlite3ExplainPush(pOut);
  3494         -      sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
  3495         -      sqlite3ExplainPop(pOut);
  3496         -      if( pList->a[i].zName ){
         3485  +      sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);
         3486  +#if 0
         3487  +     if( pList->a[i].zName ){
  3497   3488           sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
  3498   3489         }
  3499   3490         if( pList->a[i].bSpanIsTab ){
  3500   3491           sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
  3501   3492         }
  3502         -      if( i<pList->nExpr-1 ){
  3503         -        sqlite3ExplainNL(pOut);
  3504         -      }
         3493  +#endif
  3505   3494       }
  3506         -    sqlite3ExplainPop(pOut);
  3507   3495     }
         3496  +  sqlite3TreeViewPop(pView);
  3508   3497   }
  3509   3498   #endif /* SQLITE_DEBUG */
  3510   3499   
  3511   3500   /*
  3512   3501   ** Generate code that pushes the value of every element of the given
  3513   3502   ** expression list into a sequence of registers beginning at target.
  3514   3503   **

Changes to src/main.c.

  3323   3323       ** undo this setting.
  3324   3324       */
  3325   3325       case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
  3326   3326         sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
  3327   3327         break;
  3328   3328       }
  3329   3329   
  3330         -#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
  3331         -    /*   sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT,
  3332         -    **                        sqlite3_stmt*,const char**);
  3333         -    **
  3334         -    ** If compiled with SQLITE_ENABLE_TREE_EXPLAIN, each sqlite3_stmt holds
  3335         -    ** a string that describes the optimized parse tree.  This test-control
  3336         -    ** returns a pointer to that string.
  3337         -    */
  3338         -    case SQLITE_TESTCTRL_EXPLAIN_STMT: {
  3339         -      sqlite3_stmt *pStmt = va_arg(ap, sqlite3_stmt*);
  3340         -      const char **pzRet = va_arg(ap, const char**);
  3341         -      *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt);
  3342         -      break;
  3343         -    }
  3344         -#endif
  3345         -
  3346   3330       /*   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
  3347   3331       **
  3348   3332       ** Set or clear a flag that indicates that the database file is always well-
  3349   3333       ** formed and never corrupt.  This flag is clear by default, indicating that
  3350   3334       ** database files might have arbitrary corruption.  Setting the flag during
  3351   3335       ** testing causes certain assert() statements in the code to be activated
  3352   3336       ** that demonstrat invariants on well-formed database files.

Changes to src/parse.y.

   395    395   %endif  SQLITE_OMIT_VIEW
   396    396   
   397    397   //////////////////////// The SELECT statement /////////////////////////////////
   398    398   //
   399    399   cmd ::= select(X).  {
   400    400     SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
   401    401     sqlite3Select(pParse, X, &dest);
   402         -  sqlite3ExplainBegin(pParse->pVdbe);
   403         -  sqlite3ExplainSelect(pParse->pVdbe, X);
   404         -  sqlite3ExplainFinish(pParse->pVdbe);
   405    402     sqlite3SelectDelete(pParse->db, X);
   406    403   }
   407    404   
   408    405   %type select {Select*}
   409    406   %destructor select {sqlite3SelectDelete(pParse->db, $$);}
   410    407   %type selectnowith {Select*}
   411    408   %destructor selectnowith {sqlite3SelectDelete(pParse->db, $$);}

Changes to src/printf.c.

  1052   1052     va_end(ap);
  1053   1053     sqlite3StrAccumFinish(&acc);
  1054   1054     fprintf(stdout,"%s", zBuf);
  1055   1055     fflush(stdout);
  1056   1056   }
  1057   1057   #endif
  1058   1058   
         1059  +#ifdef SQLITE_DEBUG
         1060  +/*************************************************************************
         1061  +** Routines for implementing the "TreeView" display of hierarchical
         1062  +** data structures for debugging.
         1063  +**
         1064  +** The main entry points (coded elsewhere) are:
         1065  +**     sqlite3TreeViewExpr(0, pExpr, 0);
         1066  +**     sqlite3TreeViewExprList(0, pList, 0, 0);
         1067  +**     sqlite3TreeViewSelect(0, pSelect, 0);
         1068  +** Insert calls to those routines while debugging in order to display
         1069  +** a diagram of Expr, ExprList, and Select objects.
         1070  +**
         1071  +*/
         1072  +/* Add a new subitem to the tree.  The moreToFollow flag indicates that this
         1073  +** is not the last item in the tree. */
         1074  +TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
         1075  +  if( p==0 ){
         1076  +    p = sqlite3_malloc( sizeof(*p) );
         1077  +    if( p==0 ) return 0;
         1078  +    memset(p, 0, sizeof(*p));
         1079  +  }else{
         1080  +    p->iLevel++;
         1081  +  }
         1082  +  assert( moreToFollow==0 || moreToFollow==1 );
         1083  +  p->mLine &= ~(1<<p->iLevel);
         1084  +  p->mLine |= moreToFollow << p->iLevel;
         1085  +  return p;
         1086  +}
         1087  +/* Finished with one layer of the tree */
         1088  +void sqlite3TreeViewPop(TreeView *p){
         1089  +  if( p==0 ) return;
         1090  +  p->iLevel--;
         1091  +  if( p->iLevel<0 ) sqlite3_free(p);
         1092  +}
         1093  +/* Generate a single line of output for the tree, with a prefix that contains
         1094  +** all the appropriate tree lines */
         1095  +void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
         1096  +  va_list ap;
         1097  +  int i;
         1098  +  StrAccum acc;
         1099  +  char zBuf[500];
         1100  +  sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
         1101  +  acc.useMalloc = 0;
         1102  +  if( p ){
         1103  +    for(i=0; i<p->iLevel; i++){
         1104  +      sqlite3StrAccumAppend(&acc, (p->mLine & (1<<i))!=0 ? "|   " : "    ", 4);
         1105  +    }
         1106  +    sqlite3StrAccumAppend(&acc, (p->mLine & (1<<i))!=0 ? "|-- " : "'-- ", 4);
         1107  +  }
         1108  +  va_start(ap, zFormat);
         1109  +  sqlite3VXPrintf(&acc, 0, zFormat, ap);
         1110  +  va_end(ap);
         1111  +  if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
         1112  +  sqlite3StrAccumFinish(&acc);
         1113  +  fprintf(stdout,"%s", zBuf);
         1114  +  fflush(stdout);
         1115  +}
         1116  +/* Shorthand for starting a new tree item that consists of a single label */
         1117  +void sqlite3TreeViewItem(TreeView *p, const char *zLabel, u8 moreToFollow){
         1118  +  p = sqlite3TreeViewPush(p, moreToFollow);
         1119  +  sqlite3TreeViewLine(p, "%s", zLabel);
         1120  +}
         1121  +#endif /* SQLITE_DEBUG */
         1122  +
  1059   1123   /*
  1060   1124   ** variable-argument wrapper around sqlite3VXPrintf().
  1061   1125   */
  1062   1126   void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
  1063   1127     va_list ap;
  1064   1128     va_start(ap,zFormat);
  1065   1129     sqlite3VXPrintf(p, bFlags, zFormat, ap);
  1066   1130     va_end(ap);
  1067   1131   }

Changes to src/select.c.

  5413   5413   #if SELECTTRACE_ENABLED
  5414   5414     SELECTTRACE(1,pParse,p,("end processing\n"));
  5415   5415     pParse->nSelectIndent--;
  5416   5416   #endif
  5417   5417     return rc;
  5418   5418   }
  5419   5419   
  5420         -#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
         5420  +#ifdef SQLITE_DEBUG
  5421   5421   /*
  5422   5422   ** Generate a human-readable description of a the Select object.
  5423   5423   */
  5424         -static void explainOneSelect(Vdbe *pVdbe, Select *p){
  5425         -  sqlite3ExplainPrintf(pVdbe, "SELECT ");
  5426         -  if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
  5427         -    if( p->selFlags & SF_Distinct ){
  5428         -      sqlite3ExplainPrintf(pVdbe, "DISTINCT ");
  5429         -    }
  5430         -    if( p->selFlags & SF_Aggregate ){
  5431         -      sqlite3ExplainPrintf(pVdbe, "agg_flag ");
  5432         -    }
  5433         -    sqlite3ExplainNL(pVdbe);
  5434         -    sqlite3ExplainPrintf(pVdbe, "   ");
  5435         -  }
  5436         -  sqlite3ExplainExprList(pVdbe, p->pEList);
  5437         -  sqlite3ExplainNL(pVdbe);
         5424  +void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
         5425  +  pView = sqlite3TreeViewPush(pView, moreToFollow);
         5426  +  sqlite3TreeViewLine(pView, "SELECT%s%s",
         5427  +    ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
         5428  +    ((p->selFlags & SF_Aggregate) ? " agg_flag" : "")
         5429  +  );
         5430  +  sqlite3TreeViewExprList(pView, p->pEList, 1, "result-set");
  5438   5431     if( p->pSrc && p->pSrc->nSrc ){
  5439   5432       int i;
  5440         -    sqlite3ExplainPrintf(pVdbe, "FROM ");
  5441         -    sqlite3ExplainPush(pVdbe);
         5433  +    pView = sqlite3TreeViewPush(pView, 1);
         5434  +    sqlite3TreeViewLine(pView, "FROM");
  5442   5435       for(i=0; i<p->pSrc->nSrc; i++){
  5443   5436         struct SrcList_item *pItem = &p->pSrc->a[i];
  5444         -      sqlite3ExplainPrintf(pVdbe, "{%d,*} = ", pItem->iCursor);
  5445         -      if( pItem->pSelect ){
  5446         -        sqlite3ExplainSelect(pVdbe, pItem->pSelect);
  5447         -        if( pItem->pTab ){
  5448         -          sqlite3ExplainPrintf(pVdbe, " (tabname=%s)", pItem->pTab->zName);
  5449         -        }
         5437  +      StrAccum x;
         5438  +      char zLine[100];
         5439  +      sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
         5440  +      sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
         5441  +      if( pItem->zDatabase ){
         5442  +        sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
  5450   5443         }else if( pItem->zName ){
  5451         -        sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName);
         5444  +        sqlite3XPrintf(&x, 0, " %s", pItem->zName);
         5445  +      }
         5446  +      if( pItem->pTab ){
         5447  +        sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
  5452   5448         }
  5453   5449         if( pItem->zAlias ){
  5454         -        sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias);
         5450  +        sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
  5455   5451         }
  5456   5452         if( pItem->jointype & JT_LEFT ){
  5457         -        sqlite3ExplainPrintf(pVdbe, " LEFT-JOIN");
         5453  +        sqlite3XPrintf(&x, 0, " LEFT-JOIN");
         5454  +      }
         5455  +      sqlite3StrAccumFinish(&x);
         5456  +      sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); 
         5457  +      if( pItem->pSelect ){
         5458  +        sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
  5458   5459         }
  5459         -      sqlite3ExplainNL(pVdbe);
         5460  +      sqlite3TreeViewPop(pView);
  5460   5461       }
  5461         -    sqlite3ExplainPop(pVdbe);
         5462  +    sqlite3TreeViewPop(pView);
  5462   5463     }
  5463   5464     if( p->pWhere ){
  5464         -    sqlite3ExplainPrintf(pVdbe, "WHERE ");
  5465         -    sqlite3ExplainExpr(pVdbe, p->pWhere);
  5466         -    sqlite3ExplainNL(pVdbe);
         5465  +    sqlite3TreeViewItem(pView, "WHERE", 1);
         5466  +    sqlite3TreeViewExpr(pView, p->pWhere, 0);
         5467  +    sqlite3TreeViewPop(pView);
  5467   5468     }
  5468   5469     if( p->pGroupBy ){
  5469         -    sqlite3ExplainPrintf(pVdbe, "GROUPBY ");
  5470         -    sqlite3ExplainExprList(pVdbe, p->pGroupBy);
  5471         -    sqlite3ExplainNL(pVdbe);
         5470  +    sqlite3TreeViewExprList(pView, p->pGroupBy, 1, "GROUPBY");
  5472   5471     }
  5473   5472     if( p->pHaving ){
  5474         -    sqlite3ExplainPrintf(pVdbe, "HAVING ");
  5475         -    sqlite3ExplainExpr(pVdbe, p->pHaving);
  5476         -    sqlite3ExplainNL(pVdbe);
         5473  +    sqlite3TreeViewItem(pView, "HAVING", 1);
         5474  +    sqlite3TreeViewExpr(pView, p->pHaving, 0);
         5475  +    sqlite3TreeViewPop(pView);
  5477   5476     }
  5478   5477     if( p->pOrderBy ){
  5479         -    sqlite3ExplainPrintf(pVdbe, "ORDERBY ");
  5480         -    sqlite3ExplainExprList(pVdbe, p->pOrderBy);
  5481         -    sqlite3ExplainNL(pVdbe);
         5478  +    sqlite3TreeViewExprList(pView, p->pOrderBy, 1, "ORDERBY");
  5482   5479     }
  5483   5480     if( p->pLimit ){
  5484         -    sqlite3ExplainPrintf(pVdbe, "LIMIT ");
  5485         -    sqlite3ExplainExpr(pVdbe, p->pLimit);
  5486         -    sqlite3ExplainNL(pVdbe);
         5481  +    sqlite3TreeViewItem(pView, "LIMIT", 1);
         5482  +    sqlite3TreeViewExpr(pView, p->pLimit, 0);
         5483  +    sqlite3TreeViewPop(pView);
  5487   5484     }
  5488   5485     if( p->pOffset ){
  5489         -    sqlite3ExplainPrintf(pVdbe, "OFFSET ");
  5490         -    sqlite3ExplainExpr(pVdbe, p->pOffset);
  5491         -    sqlite3ExplainNL(pVdbe);
         5486  +    sqlite3TreeViewItem(pView, "OFFSET", 1);
         5487  +    sqlite3TreeViewExpr(pView, p->pOffset, 0);
         5488  +    sqlite3TreeViewPop(pView);
  5492   5489     }
  5493         -}
  5494         -void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
  5495         -  if( p==0 ){
  5496         -    sqlite3ExplainPrintf(pVdbe, "(null-select)");
  5497         -    return;
         5490  +  if( p->pPrior ){
         5491  +    const char *zOp = "UNION";
         5492  +    switch( p->op ){
         5493  +      case TK_ALL:         zOp = "UNION ALL";  break;
         5494  +      case TK_INTERSECT:   zOp = "INTERSECT";  break;
         5495  +      case TK_EXCEPT:      zOp = "EXCEPT";     break;
         5496  +    }
         5497  +    sqlite3TreeViewItem(pView, zOp, 1);
         5498  +    sqlite3TreeViewSelect(pView, p->pPrior, 1);
         5499  +    sqlite3TreeViewPop(pView);
  5498   5500     }
  5499         -  sqlite3ExplainPush(pVdbe);
  5500         -  while( p ){
  5501         -    explainOneSelect(pVdbe, p);
  5502         -    p = p->pNext;
  5503         -    if( p==0 ) break;
  5504         -    sqlite3ExplainNL(pVdbe);
  5505         -    sqlite3ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op));
  5506         -  }
  5507         -  sqlite3ExplainPrintf(pVdbe, "END");
  5508         -  sqlite3ExplainPop(pVdbe);
         5501  +  sqlite3TreeViewItem(pView, "END-SELECT", 0);
         5502  +  sqlite3TreeViewPop(pView);
         5503  +  sqlite3TreeViewPop(pView);
  5509   5504   }
  5510         -
  5511         -/* End of the structure debug printing code
  5512         -*****************************************************************************/
  5513         -#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
         5505  +#endif /* SQLITE_DEBUG */

Changes to src/shell.c.

  1349   1349               fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
  1350   1350             }
  1351   1351           }
  1352   1352           sqlite3_finalize(pExplain);
  1353   1353           sqlite3_free(zEQP);
  1354   1354         }
  1355   1355   
  1356         -      /* Output TESTCTRL_EXPLAIN text of requested */
  1357         -      if( pArg && pArg->mode==MODE_Explain ){
  1358         -        const char *zExplain = 0;
  1359         -        sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
  1360         -        if( zExplain && zExplain[0] ){
  1361         -          fprintf(pArg->out, "%s", zExplain);
  1362         -        }
  1363         -      }
  1364         -
  1365   1356         /* If the shell is currently in ".explain" mode, gather the extra
  1366   1357         ** data required to add indents to the output.*/
  1367   1358         if( pArg && pArg->mode==MODE_Explain ){
  1368   1359           explain_data_prepare(pArg, pStmt);
  1369   1360         }
  1370   1361   
  1371   1362         /* perform the first step.  this will tell us if we

Changes to src/sqlite.h.in.

  6201   6201   #define SQLITE_TESTCTRL_ASSERT                  12
  6202   6202   #define SQLITE_TESTCTRL_ALWAYS                  13
  6203   6203   #define SQLITE_TESTCTRL_RESERVE                 14
  6204   6204   #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
  6205   6205   #define SQLITE_TESTCTRL_ISKEYWORD               16
  6206   6206   #define SQLITE_TESTCTRL_SCRATCHMALLOC           17
  6207   6207   #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
  6208         -#define SQLITE_TESTCTRL_EXPLAIN_STMT            19
         6208  +#define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
  6209   6209   #define SQLITE_TESTCTRL_NEVER_CORRUPT           20
  6210   6210   #define SQLITE_TESTCTRL_VDBE_COVERAGE           21
  6211   6211   #define SQLITE_TESTCTRL_BYTEORDER               22
  6212   6212   #define SQLITE_TESTCTRL_ISINIT                  23
  6213   6213   #define SQLITE_TESTCTRL_SORTER_MMAP             24
  6214   6214   #define SQLITE_TESTCTRL_LAST                    24
  6215   6215   

Changes to src/sqliteInt.h.

   465    465   
   466    466   /*
   467    467   ** Macros to compute minimum and maximum of two numbers.
   468    468   */
   469    469   #define MIN(A,B) ((A)<(B)?(A):(B))
   470    470   #define MAX(A,B) ((A)>(B)?(A):(B))
   471    471   
          472  +/*
          473  +** Swap two objects of type TYPE.
          474  +*/
          475  +#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
          476  +
   472    477   /*
   473    478   ** Check to see if this machine uses EBCDIC.  (Yes, believe it or
   474    479   ** not, there are still machines out there that use EBCDIC.)
   475    480   */
   476    481   #if 'A' == '\301'
   477    482   # define SQLITE_EBCDIC 1
   478    483   #else
................................................................................
   851    856   typedef struct SQLiteThread SQLiteThread;
   852    857   typedef struct SelectDest SelectDest;
   853    858   typedef struct SrcList SrcList;
   854    859   typedef struct StrAccum StrAccum;
   855    860   typedef struct Table Table;
   856    861   typedef struct TableLock TableLock;
   857    862   typedef struct Token Token;
          863  +typedef struct TreeView TreeView;
   858    864   typedef struct Trigger Trigger;
   859    865   typedef struct TriggerPrg TriggerPrg;
   860    866   typedef struct TriggerStep TriggerStep;
   861    867   typedef struct UnpackedRecord UnpackedRecord;
   862    868   typedef struct VTable VTable;
   863    869   typedef struct VtabCtx VtabCtx;
   864    870   typedef struct Walker Walker;
................................................................................
  2919   2925       char *zName;                    /* Name of this CTE */
  2920   2926       ExprList *pCols;                /* List of explicit column names, or NULL */
  2921   2927       Select *pSelect;                /* The definition of this CTE */
  2922   2928       const char *zErr;               /* Error message for circular references */
  2923   2929     } a[1];
  2924   2930   };
  2925   2931   
         2932  +#ifdef SQLITE_DEBUG
         2933  +/*
         2934  +** An instance of the TreeView object is used for printing the content of
         2935  +** data structures on sqlite3DebugPrintf() using a tree-like view.
         2936  +*/
         2937  +struct TreeView {
         2938  +  int iLevel;             /* Which level of the tree we are on */
         2939  +  u64 mLine;              /* Mask of continuation lines to be drawn */
         2940  +};
         2941  +#endif /* SQLITE_DEBUG */
         2942  +
  2926   2943   /*
  2927   2944   ** Assuming zIn points to the first byte of a UTF-8 character,
  2928   2945   ** advance zIn to point to the first byte of the next UTF-8 character.
  2929   2946   */
  2930   2947   #define SQLITE_SKIP_UTF8(zIn) {                        \
  2931   2948     if( (*(zIn++))>=0xc0 ){                              \
  2932   2949       while( (*zIn & 0xc0)==0x80 ){ zIn++; }             \
................................................................................
  3083   3100   #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
  3084   3101     void sqlite3DebugPrintf(const char*, ...);
  3085   3102   #endif
  3086   3103   #if defined(SQLITE_TEST)
  3087   3104     void *sqlite3TestTextToPtr(const char*);
  3088   3105   #endif
  3089   3106   
  3090         -/* Output formatting for SQLITE_TESTCTRL_EXPLAIN */
  3091         -#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
  3092         -  void sqlite3ExplainBegin(Vdbe*);
  3093         -  void sqlite3ExplainPrintf(Vdbe*, const char*, ...);
  3094         -  void sqlite3ExplainNL(Vdbe*);
  3095         -  void sqlite3ExplainPush(Vdbe*);
  3096         -  void sqlite3ExplainPop(Vdbe*);
  3097         -  void sqlite3ExplainFinish(Vdbe*);
  3098         -  void sqlite3ExplainSelect(Vdbe*, Select*);
  3099         -  void sqlite3ExplainExpr(Vdbe*, Expr*);
  3100         -  void sqlite3ExplainExprList(Vdbe*, ExprList*);
  3101         -  const char *sqlite3VdbeExplanation(Vdbe*);
  3102         -#else
  3103         -# define sqlite3ExplainBegin(X)
  3104         -# define sqlite3ExplainSelect(A,B)
  3105         -# define sqlite3ExplainExpr(A,B)
  3106         -# define sqlite3ExplainExprList(A,B)
  3107         -# define sqlite3ExplainFinish(X)
  3108         -# define sqlite3VdbeExplanation(X) 0
         3107  +#if defined(SQLITE_DEBUG)
         3108  +  TreeView *sqlite3TreeViewPush(TreeView*,u8);
         3109  +  void sqlite3TreeViewPop(TreeView*);
         3110  +  void sqlite3TreeViewLine(TreeView*, const char*, ...);
         3111  +  void sqlite3TreeViewItem(TreeView*, const char*, u8);
         3112  +  void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
         3113  +  void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
         3114  +  void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
  3109   3115   #endif
  3110   3116   
  3111   3117   
  3112   3118   void sqlite3SetString(char **, sqlite3*, const char*, ...);
  3113   3119   void sqlite3ErrorMsg(Parse*, const char*, ...);
  3114   3120   int sqlite3Dequote(char*);
  3115   3121   int sqlite3KeywordCode(const unsigned char*, int);
................................................................................
  3124   3130   Expr *sqlite3Expr(sqlite3*,int,const char*);
  3125   3131   void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
  3126   3132   Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*, const Token*);
  3127   3133   Expr *sqlite3ExprAnd(sqlite3*,Expr*, Expr*);
  3128   3134   Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
  3129   3135   void sqlite3ExprAssignVarNumber(Parse*, Expr*);
  3130   3136   void sqlite3ExprDelete(sqlite3*, Expr*);
         3137  +void sqlite3ExprFactor(sqlite3*, Expr*, u8);
  3131   3138   ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
  3132   3139   void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
  3133   3140   void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
  3134   3141   void sqlite3ExprListDelete(sqlite3*, ExprList*);
  3135   3142   int sqlite3Init(sqlite3*, char**);
  3136   3143   int sqlite3InitCallback(void*, int, char**, char**);
  3137   3144   void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);

Changes to src/vdbeInt.h.

   356    356   #endif
   357    357     i64 iCurrentTime;       /* Value of julianday('now') for this statement */
   358    358     i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
   359    359     i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
   360    360     i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
   361    361     char *zSql;             /* Text of the SQL statement that generated this */
   362    362     void *pFree;            /* Free this when deleting the vdbe */
   363         -#ifdef SQLITE_ENABLE_TREE_EXPLAIN
   364         -  Explain *pExplain;      /* The explainer */
   365         -  char *zExplain;         /* Explanation of data structures */
   366         -#endif
   367    363     VdbeFrame *pFrame;      /* Parent frame */
   368    364     VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
   369    365     int nFrame;             /* Number of frames in pFrame list */
   370    366     u32 expmask;            /* Binding to these vars invalidates VM */
   371    367     SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
   372    368     int nOnceFlag;          /* Size of array aOnceFlag[] */
   373    369     u8 *aOnceFlag;          /* Flags for OP_Once */

Changes to src/vdbeaux.c.

  2674   2674       sqlite3DbFree(db, pSub);
  2675   2675     }
  2676   2676     for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
  2677   2677     vdbeFreeOpArray(db, p->aOp, p->nOp);
  2678   2678     sqlite3DbFree(db, p->aColName);
  2679   2679     sqlite3DbFree(db, p->zSql);
  2680   2680     sqlite3DbFree(db, p->pFree);
  2681         -#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
  2682         -  sqlite3DbFree(db, p->zExplain);
  2683         -  sqlite3DbFree(db, p->pExplain);
  2684         -#endif
  2685   2681   }
  2686   2682   
  2687   2683   /*
  2688   2684   ** Delete an entire VDBE.
  2689   2685   */
  2690   2686   void sqlite3VdbeDelete(Vdbe *p){
  2691   2687     sqlite3 *db;

Changes to src/vdbetrace.c.

   179    179         }
   180    180       }
   181    181     }
   182    182     return sqlite3StrAccumFinish(&out);
   183    183   }
   184    184   
   185    185   #endif /* #ifndef SQLITE_OMIT_TRACE */
   186         -
   187         -/*****************************************************************************
   188         -** The following code implements the data-structure explaining logic
   189         -** for the Vdbe.
   190         -*/
   191         -
   192         -#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
   193         -
   194         -/*
   195         -** Allocate a new Explain object
   196         -*/
   197         -void sqlite3ExplainBegin(Vdbe *pVdbe){
   198         -  if( pVdbe ){
   199         -    Explain *p;
   200         -    sqlite3BeginBenignMalloc();
   201         -    p = (Explain *)sqlite3MallocZero( sizeof(Explain) );
   202         -    if( p ){
   203         -      p->pVdbe = pVdbe;
   204         -      sqlite3_free(pVdbe->pExplain);
   205         -      pVdbe->pExplain = p;
   206         -      sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase),
   207         -                          SQLITE_MAX_LENGTH);
   208         -      p->str.useMalloc = 2;
   209         -    }else{
   210         -      sqlite3EndBenignMalloc();
   211         -    }
   212         -  }
   213         -}
   214         -
   215         -/*
   216         -** Return true if the Explain ends with a new-line.
   217         -*/
   218         -static int endsWithNL(Explain *p){
   219         -  return p && p->str.zText && p->str.nChar
   220         -           && p->str.zText[p->str.nChar-1]=='\n';
   221         -}
   222         -    
   223         -/*
   224         -** Append text to the indentation
   225         -*/
   226         -void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){
   227         -  Explain *p;
   228         -  if( pVdbe && (p = pVdbe->pExplain)!=0 ){
   229         -    va_list ap;
   230         -    if( p->nIndent && endsWithNL(p) ){
   231         -      int n = p->nIndent;
   232         -      if( n>ArraySize(p->aIndent) ) n = ArraySize(p->aIndent);
   233         -      sqlite3AppendSpace(&p->str, p->aIndent[n-1]);
   234         -    }   
   235         -    va_start(ap, zFormat);
   236         -    sqlite3VXPrintf(&p->str, SQLITE_PRINTF_INTERNAL, zFormat, ap);
   237         -    va_end(ap);
   238         -  }
   239         -}
   240         -
   241         -/*
   242         -** Append a '\n' if there is not already one.
   243         -*/
   244         -void sqlite3ExplainNL(Vdbe *pVdbe){
   245         -  Explain *p;
   246         -  if( pVdbe && (p = pVdbe->pExplain)!=0 && !endsWithNL(p) ){
   247         -    sqlite3StrAccumAppend(&p->str, "\n", 1);
   248         -  }
   249         -}
   250         -
   251         -/*
   252         -** Push a new indentation level.  Subsequent lines will be indented
   253         -** so that they begin at the current cursor position.
   254         -*/
   255         -void sqlite3ExplainPush(Vdbe *pVdbe){
   256         -  Explain *p;
   257         -  if( pVdbe && (p = pVdbe->pExplain)!=0 ){
   258         -    if( p->str.zText && p->nIndent<ArraySize(p->aIndent) ){
   259         -      const char *z = p->str.zText;
   260         -      int i = p->str.nChar-1;
   261         -      int x;
   262         -      while( i>=0 && z[i]!='\n' ){ i--; }
   263         -      x = (p->str.nChar - 1) - i;
   264         -      if( p->nIndent && x<p->aIndent[p->nIndent-1] ){
   265         -        x = p->aIndent[p->nIndent-1];
   266         -      }
   267         -      p->aIndent[p->nIndent] = x;
   268         -    }
   269         -    p->nIndent++;
   270         -  }
   271         -}
   272         -
   273         -/*
   274         -** Pop the indentation stack by one level.
   275         -*/
   276         -void sqlite3ExplainPop(Vdbe *p){
   277         -  if( p && p->pExplain ) p->pExplain->nIndent--;
   278         -}
   279         -
   280         -/*
   281         -** Free the indentation structure
   282         -*/
   283         -void sqlite3ExplainFinish(Vdbe *pVdbe){
   284         -  if( pVdbe && pVdbe->pExplain ){
   285         -    sqlite3_free(pVdbe->zExplain);
   286         -    sqlite3ExplainNL(pVdbe);
   287         -    pVdbe->zExplain = sqlite3StrAccumFinish(&pVdbe->pExplain->str);
   288         -    sqlite3_free(pVdbe->pExplain);
   289         -    pVdbe->pExplain = 0;
   290         -    sqlite3EndBenignMalloc();
   291         -  }
   292         -}
   293         -
   294         -/*
   295         -** Return the explanation of a virtual machine.
   296         -*/
   297         -const char *sqlite3VdbeExplanation(Vdbe *pVdbe){
   298         -  return (pVdbe && pVdbe->zExplain) ? pVdbe->zExplain : 0;
   299         -}
   300         -#endif /* defined(SQLITE_DEBUG) */

Changes to src/where.c.

   360    360     assert( TK_GT>TK_EQ && TK_GT<TK_GE );
   361    361     assert( TK_LT>TK_EQ && TK_LT<TK_GE );
   362    362     assert( TK_LE>TK_EQ && TK_LE<TK_GE );
   363    363     assert( TK_GE==TK_EQ+4 );
   364    364     return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
   365    365   }
   366    366   
   367         -/*
   368         -** Swap two objects of type TYPE.
   369         -*/
   370         -#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
   371         -
   372    367   /*
   373    368   ** Commute a comparison operator.  Expressions of the form "X op Y"
   374    369   ** are converted into "Y op X".
   375    370   **
   376    371   ** If left/right precedence rules come into play when determining the
   377    372   ** collating sequence, then COLLATE operators are adjusted to ensure
   378    373   ** that the collating sequence does not change.  For example:
................................................................................
  3756   3751         sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
  3757   3752         pTerm->wtFlags |= TERM_CODED;
  3758   3753       }
  3759   3754     }
  3760   3755   
  3761   3756     return pLevel->notReady;
  3762   3757   }
  3763         -
  3764         -#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
  3765         -/*
  3766         -** Generate "Explanation" text for a WhereTerm.
  3767         -*/
  3768         -static void whereExplainTerm(Vdbe *v, WhereTerm *pTerm){
  3769         -  char zType[4];
  3770         -  memcpy(zType, "...", 4);
  3771         -  if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
  3772         -  if( pTerm->eOperator & WO_EQUIV  ) zType[1] = 'E';
  3773         -  if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
  3774         -  sqlite3ExplainPrintf(v, "%s ", zType);
  3775         -  sqlite3ExplainExpr(v, pTerm->pExpr);
  3776         -}
  3777         -#endif /* WHERETRACE_ENABLED && SQLITE_ENABLE_TREE_EXPLAIN */
  3778         -
  3779   3758   
  3780   3759   #ifdef WHERETRACE_ENABLED
  3781   3760   /*
  3782   3761   ** Print a WhereLoop object for debugging purposes
  3783   3762   */
  3784   3763   static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
  3785   3764     WhereInfo *pWInfo = pWC->pWInfo;
................................................................................
  3815   3794     }
  3816   3795     if( p->wsFlags & WHERE_SKIPSCAN ){
  3817   3796       sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->u.btree.nSkip);
  3818   3797     }else{
  3819   3798       sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
  3820   3799     }
  3821   3800     sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
  3822         -#ifdef SQLITE_ENABLE_TREE_EXPLAIN
  3823         -  /* If the 0x100 bit of wheretracing is set, then show all of the constraint
  3824         -  ** expressions in the WhereLoop.aLTerm[] array.
  3825         -  */
  3826         -  if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){  /* WHERETRACE 0x100 */
  3827         -    int i;
  3828         -    Vdbe *v = pWInfo->pParse->pVdbe;
  3829         -    sqlite3ExplainBegin(v);
  3830         -    for(i=0; i<p->nLTerm; i++){
  3831         -      WhereTerm *pTerm = p->aLTerm[i];
  3832         -      if( pTerm==0 ) continue;
  3833         -      sqlite3ExplainPrintf(v, "  (%d) #%-2d ", i+1, (int)(pTerm-pWC->a));
  3834         -      sqlite3ExplainPush(v);
  3835         -      whereExplainTerm(v, pTerm);
  3836         -      sqlite3ExplainPop(v);
  3837         -      sqlite3ExplainNL(v);
  3838         -    }
  3839         -    sqlite3ExplainFinish(v);
  3840         -    sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
  3841         -  }
  3842         -#endif
  3843   3801   }
  3844   3802   #endif
  3845   3803   
  3846   3804   /*
  3847   3805   ** Convert bulk memory into a valid WhereLoop that can be passed
  3848   3806   ** to whereLoopClear harmlessly.
  3849   3807   */
................................................................................
  6168   6126         pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
  6169   6127         pWInfo->pOrderBy = pResultSet;
  6170   6128       }
  6171   6129     }
  6172   6130   
  6173   6131     /* Construct the WhereLoop objects */
  6174   6132     WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
  6175         -  /* Display all terms of the WHERE clause */
  6176         -#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
  6177         -  if( sqlite3WhereTrace & 0x100 ){
  6178         -    int i;
  6179         -    Vdbe *v = pParse->pVdbe;
  6180         -    sqlite3ExplainBegin(v);
  6181         -    for(i=0; i<sWLB.pWC->nTerm; i++){
  6182         -      sqlite3ExplainPrintf(v, "#%-2d ", i);
  6183         -      sqlite3ExplainPush(v);
  6184         -      whereExplainTerm(v, &sWLB.pWC->a[i]);
  6185         -      sqlite3ExplainPop(v);
  6186         -      sqlite3ExplainNL(v);
  6187         -    }
  6188         -    sqlite3ExplainFinish(v);
  6189         -    sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
  6190         -  }
  6191         -#endif
  6192   6133     if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
  6193   6134       rc = whereLoopAddAll(&sWLB);
  6194   6135       if( rc ) goto whereBeginError;
  6195   6136     
  6196   6137       /* Display all of the WhereLoop objects if wheretrace is enabled */
  6197   6138   #ifdef WHERETRACE_ENABLED /* !=0 */
  6198   6139       if( sqlite3WhereTrace ){