SQLite

Check-in [5ce05757aa]
Login

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

Overview
Comment:Improvements to the new syntax-tree output routines: Omit the "END SELECT" mark and instead terminate the graph at the last item. Increase the maximum tree depth to 100.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5ce05757aac80b99c3b2141cd301809f8e28e661
User & Date: drh 2014-09-30 19:04:41.396
Context
2014-10-01
12:01
Avoid ever writing before the start of an allocated buffer in the DIRECT_OVERFLOW_READ code. Fix for [e3a290961a6]. (check-in: c3c15d20c6 user: dan tags: trunk)
01:52
Merge the latest enhancements from trunk. (check-in: 2695772c98 user: drh tags: sessions)
01:46
Merge the latest enhancements from trunk. (check-in: 2078454ac9 user: drh tags: apple-osx)
2014-09-30
21:24
Draw the TreeView debugging graphs using unicode box-drawing characters. (Closed-Leaf check-in: 0efc6859d1 user: drh tags: box-character-graph)
19:04
Improvements to the new syntax-tree output routines: Omit the "END SELECT" mark and instead terminate the graph at the last item. Increase the maximum tree depth to 100. (check-in: 5ce05757aa user: drh tags: trunk)
17:31
Enable the query planner to deal with WHERE clauses that have OR terms nested within AND terms that are nested within OR terms. Also remove an unused function declaration. (check-in: b6b289182f user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/printf.c.
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
    p = sqlite3_malloc( sizeof(*p) );
    if( p==0 ) return 0;
    memset(p, 0, sizeof(*p));
  }else{
    p->iLevel++;
  }
  assert( moreToFollow==0 || moreToFollow==1 );
  p->mLine &= ~(1<<p->iLevel);
  p->mLine |= moreToFollow << p->iLevel;
  return p;
}
/* Finished with one layer of the tree */
void sqlite3TreeViewPop(TreeView *p){
  if( p==0 ) return;
  p->iLevel--;
  if( p->iLevel<0 ) sqlite3_free(p);
}
/* Generate a single line of output for the tree, with a prefix that contains
** all the appropriate tree lines */
void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
  va_list ap;
  int i;
  StrAccum acc;
  char zBuf[500];
  sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
  acc.useMalloc = 0;
  if( p ){
    for(i=0; i<p->iLevel; i++){
      sqlite3StrAccumAppend(&acc, (p->mLine & (1<<i))!=0 ? "|   " : "    ", 4);
    }
    sqlite3StrAccumAppend(&acc, (p->mLine & (1<<i))!=0 ? "|-- " : "'-- ", 4);
  }
  va_start(ap, zFormat);
  sqlite3VXPrintf(&acc, 0, zFormat, ap);
  va_end(ap);
  if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
  sqlite3StrAccumFinish(&acc);
  fprintf(stdout,"%s", zBuf);







<
|


















|
|

|







1076
1077
1078
1079
1080
1081
1082

1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
    p = sqlite3_malloc( sizeof(*p) );
    if( p==0 ) return 0;
    memset(p, 0, sizeof(*p));
  }else{
    p->iLevel++;
  }
  assert( moreToFollow==0 || moreToFollow==1 );

  if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
  return p;
}
/* Finished with one layer of the tree */
void sqlite3TreeViewPop(TreeView *p){
  if( p==0 ) return;
  p->iLevel--;
  if( p->iLevel<0 ) sqlite3_free(p);
}
/* Generate a single line of output for the tree, with a prefix that contains
** all the appropriate tree lines */
void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
  va_list ap;
  int i;
  StrAccum acc;
  char zBuf[500];
  sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
  acc.useMalloc = 0;
  if( p ){
    for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
      sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|   " : "    ", 4);
    }
    sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
  }
  va_start(ap, zFormat);
  sqlite3VXPrintf(&acc, 0, zFormat, ap);
  va_end(ap);
  if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
  sqlite3StrAccumFinish(&acc);
  fprintf(stdout,"%s", zBuf);
Changes to src/select.c.
5428
5429
5430
5431
5432
5433
5434

5435
5436
5437
5438
5439








5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
}

#ifdef SQLITE_DEBUG
/*
** Generate a human-readable description of a the Select object.
*/
void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){

  pView = sqlite3TreeViewPush(pView, moreToFollow);
  sqlite3TreeViewLine(pView, "SELECT%s%s",
    ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
    ((p->selFlags & SF_Aggregate) ? " agg_flag" : "")
  );








  sqlite3TreeViewExprList(pView, p->pEList, 1, "result-set");
  if( p->pSrc && p->pSrc->nSrc ){
    int i;
    pView = sqlite3TreeViewPush(pView, 1);
    sqlite3TreeViewLine(pView, "FROM");
    for(i=0; i<p->pSrc->nSrc; i++){
      struct SrcList_item *pItem = &p->pSrc->a[i];
      StrAccum x;
      char zLine[100];
      sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
      sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);







>





>
>
>
>
>
>
>
>
|


|







5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
}

#ifdef SQLITE_DEBUG
/*
** Generate a human-readable description of a the Select object.
*/
void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
  int n = 0;
  pView = sqlite3TreeViewPush(pView, moreToFollow);
  sqlite3TreeViewLine(pView, "SELECT%s%s",
    ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
    ((p->selFlags & SF_Aggregate) ? " agg_flag" : "")
  );
  if( p->pSrc && p->pSrc->nSrc ) n++;
  if( p->pWhere ) n++;
  if( p->pGroupBy ) n++;
  if( p->pHaving ) n++;
  if( p->pOrderBy ) n++;
  if( p->pLimit ) n++;
  if( p->pOffset ) n++;
  if( p->pPrior ) n++;
  sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
  if( p->pSrc && p->pSrc->nSrc ){
    int i;
    pView = sqlite3TreeViewPush(pView, (n--)>0);
    sqlite3TreeViewLine(pView, "FROM");
    for(i=0; i<p->pSrc->nSrc; i++){
      struct SrcList_item *pItem = &p->pSrc->a[i];
      StrAccum x;
      char zLine[100];
      sqlite3StrAccumInit(&x, zLine, sizeof(zLine), 0);
      sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
        sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
      }
      sqlite3TreeViewPop(pView);
    }
    sqlite3TreeViewPop(pView);
  }
  if( p->pWhere ){
    sqlite3TreeViewItem(pView, "WHERE", 1);
    sqlite3TreeViewExpr(pView, p->pWhere, 0);
    sqlite3TreeViewPop(pView);
  }
  if( p->pGroupBy ){
    sqlite3TreeViewExprList(pView, p->pGroupBy, 1, "GROUPBY");
  }
  if( p->pHaving ){
    sqlite3TreeViewItem(pView, "HAVING", 1);
    sqlite3TreeViewExpr(pView, p->pHaving, 0);
    sqlite3TreeViewPop(pView);
  }
  if( p->pOrderBy ){
    sqlite3TreeViewExprList(pView, p->pOrderBy, 1, "ORDERBY");
  }
  if( p->pLimit ){
    sqlite3TreeViewItem(pView, "LIMIT", 1);
    sqlite3TreeViewExpr(pView, p->pLimit, 0);
    sqlite3TreeViewPop(pView);
  }
  if( p->pOffset ){
    sqlite3TreeViewItem(pView, "OFFSET", 1);
    sqlite3TreeViewExpr(pView, p->pOffset, 0);
    sqlite3TreeViewPop(pView);
  }
  if( p->pPrior ){
    const char *zOp = "UNION";
    switch( p->op ){
      case TK_ALL:         zOp = "UNION ALL";  break;
      case TK_INTERSECT:   zOp = "INTERSECT";  break;
      case TK_EXCEPT:      zOp = "EXCEPT";     break;
    }
    sqlite3TreeViewItem(pView, zOp, 1);
    sqlite3TreeViewSelect(pView, p->pPrior, 1);
    sqlite3TreeViewPop(pView);
  }
  sqlite3TreeViewItem(pView, "END-SELECT", 0);
  sqlite3TreeViewPop(pView);
  sqlite3TreeViewPop(pView);
}
#endif /* SQLITE_DEBUG */







|




|


|




|


|




|










|
|


<
<



5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519


5520
5521
5522
        sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
      }
      sqlite3TreeViewPop(pView);
    }
    sqlite3TreeViewPop(pView);
  }
  if( p->pWhere ){
    sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
    sqlite3TreeViewExpr(pView, p->pWhere, 0);
    sqlite3TreeViewPop(pView);
  }
  if( p->pGroupBy ){
    sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
  }
  if( p->pHaving ){
    sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
    sqlite3TreeViewExpr(pView, p->pHaving, 0);
    sqlite3TreeViewPop(pView);
  }
  if( p->pOrderBy ){
    sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
  }
  if( p->pLimit ){
    sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
    sqlite3TreeViewExpr(pView, p->pLimit, 0);
    sqlite3TreeViewPop(pView);
  }
  if( p->pOffset ){
    sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
    sqlite3TreeViewExpr(pView, p->pOffset, 0);
    sqlite3TreeViewPop(pView);
  }
  if( p->pPrior ){
    const char *zOp = "UNION";
    switch( p->op ){
      case TK_ALL:         zOp = "UNION ALL";  break;
      case TK_INTERSECT:   zOp = "INTERSECT";  break;
      case TK_EXCEPT:      zOp = "EXCEPT";     break;
    }
    sqlite3TreeViewItem(pView, zOp, (n--)>0);
    sqlite3TreeViewSelect(pView, p->pPrior, 0);
    sqlite3TreeViewPop(pView);
  }


  sqlite3TreeViewPop(pView);
}
#endif /* SQLITE_DEBUG */
Changes to src/sqliteInt.h.
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
#ifdef SQLITE_DEBUG
/*
** An instance of the TreeView object is used for printing the content of
** data structures on sqlite3DebugPrintf() using a tree-like view.
*/
struct TreeView {
  int iLevel;             /* Which level of the tree we are on */
  u64 mLine;              /* Mask of continuation lines to be drawn */
};
#endif /* SQLITE_DEBUG */

/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/







|







2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
#ifdef SQLITE_DEBUG
/*
** An instance of the TreeView object is used for printing the content of
** data structures on sqlite3DebugPrintf() using a tree-like view.
*/
struct TreeView {
  int iLevel;             /* Which level of the tree we are on */
  u8  bLine[100];         /* Draw vertical in column i if bLine[i] is true */
};
#endif /* SQLITE_DEBUG */

/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/