/ Check-in [b2449d67]
Login

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

Overview
Comment:Merge all recent trunk fixes and enhancements into the apple-osx branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: b2449d67768f4d3d83877d9c45e5b4b17bb6a551
User & Date: drh 2015-02-13 12:13:43
Context
2015-02-13
16:42
Enhancements to SQLITE_ENABLE_API_ARMOR merged from trunk. check-in: 5147b94a user: drh tags: apple-osx
12:13
Merge all recent trunk fixes and enhancements into the apple-osx branch. check-in: b2449d67 user: drh tags: apple-osx
12:05
Make sure the prepared statement auto-resets on extended error codes of SQLITE_BUSY and SQLITE_LOCKED even when compiled using SQLITE_OMIT_AUTORESET. check-in: 3c6ca414 user: drh tags: trunk
2015-02-07
15:30
Merge increment blob I/O fixes from trunk. check-in: 292cf68b user: drh tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/delete.c.

   185    185     pWhereRowid = sqlite3PExpr(pParse, TK_ROW, 0, 0, 0);
   186    186     if( pWhereRowid == 0 ) goto limit_where_cleanup_1;
   187    187     pInClause = sqlite3PExpr(pParse, TK_IN, pWhereRowid, 0, 0);
   188    188     if( pInClause == 0 ) goto limit_where_cleanup_1;
   189    189   
   190    190     pInClause->x.pSelect = pSelect;
   191    191     pInClause->flags |= EP_xIsSelect;
   192         -  sqlite3ExprSetHeight(pParse, pInClause);
          192  +  sqlite3ExprSetHeightAndFlags(pParse, pInClause);
   193    193     return pInClause;
   194    194   
   195    195     /* something went wrong. clean up anything allocated. */
   196    196   limit_where_cleanup_1:
   197    197     sqlite3SelectDelete(pParse->db, pSelect);
   198    198     return 0;
   199    199   

Changes to src/expr.c.

   142    142         if( j>=0 ){
   143    143           const char *zColl = p->pTab->aCol[j].zColl;
   144    144           pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
   145    145         }
   146    146         break;
   147    147       }
   148    148       if( p->flags & EP_Collate ){
   149         -      if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
          149  +      if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
   150    150           p = p->pLeft;
   151    151         }else{
   152         -        p = p->pRight;
          152  +        Expr *pNext  = p->pRight;
          153  +        /* The Expr.x union is never used at the same time as Expr.pRight */
          154  +        assert( p->x.pList==0 || p->pRight==0 );
          155  +        /* p->flags holds EP_Collate and p->pLeft->flags does not.  And
          156  +        ** p->x.pSelect cannot.  So if p->x.pLeft exists, it must hold at
          157  +        ** least one EP_Collate. Thus the following two ALWAYS. */
          158  +        if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){
          159  +          int i;
          160  +          for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
          161  +            if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
          162  +              pNext = p->x.pList->a[i].pExpr;
          163  +              break;
          164  +            }
          165  +          }
          166  +        }
          167  +        p = pNext;
   153    168         }
   154    169       }else{
   155    170         break;
   156    171       }
   157    172     }
   158    173     if( sqlite3CheckCollSeq(pParse, pColl) ){ 
   159    174       pColl = 0;
................................................................................
   351    366   
   352    367   /*
   353    368   ** Set the Expr.nHeight variable in the structure passed as an 
   354    369   ** argument. An expression with no children, Expr.pList or 
   355    370   ** Expr.pSelect member has a height of 1. Any other expression
   356    371   ** has a height equal to the maximum height of any other 
   357    372   ** referenced Expr plus one.
          373  +**
          374  +** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
          375  +** if appropriate.
   358    376   */
   359    377   static void exprSetHeight(Expr *p){
   360    378     int nHeight = 0;
   361    379     heightOfExpr(p->pLeft, &nHeight);
   362    380     heightOfExpr(p->pRight, &nHeight);
   363    381     if( ExprHasProperty(p, EP_xIsSelect) ){
   364    382       heightOfSelect(p->x.pSelect, &nHeight);
   365         -  }else{
          383  +  }else if( p->x.pList ){
   366    384       heightOfExprList(p->x.pList, &nHeight);
          385  +    p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
   367    386     }
   368    387     p->nHeight = nHeight + 1;
   369    388   }
   370    389   
   371    390   /*
   372    391   ** Set the Expr.nHeight variable using the exprSetHeight() function. If
   373    392   ** the height is greater than the maximum allowed expression depth,
   374    393   ** leave an error in pParse.
          394  +**
          395  +** Also propagate all EP_Propagate flags from the Expr.x.pList into
          396  +** Expr.flags. 
   375    397   */
   376         -void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
          398  +void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
   377    399     exprSetHeight(p);
   378    400     sqlite3ExprCheckHeight(pParse, p->nHeight);
   379    401   }
   380    402   
   381    403   /*
   382    404   ** Return the maximum height of any expression tree referenced
   383    405   ** by the select statement passed as an argument.
   384    406   */
   385    407   int sqlite3SelectExprHeight(Select *p){
   386    408     int nHeight = 0;
   387    409     heightOfSelect(p, &nHeight);
   388    410     return nHeight;
   389    411   }
   390         -#else
   391         -  #define exprSetHeight(y)
          412  +#else /* ABOVE:  Height enforcement enabled.  BELOW: Height enforcement off */
          413  +/*
          414  +** Propagate all EP_Propagate flags from the Expr.x.pList into
          415  +** Expr.flags. 
          416  +*/
          417  +void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
          418  +  if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
          419  +    p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
          420  +  }
          421  +}
          422  +#define exprSetHeight(y)
   392    423   #endif /* SQLITE_MAX_EXPR_DEPTH>0 */
   393    424   
   394    425   /*
   395    426   ** This routine is the core allocator for Expr nodes.
   396    427   **
   397    428   ** Construct a new expression node and return a pointer to it.  Memory
   398    429   ** for this node and for the pToken argument is a single allocation
................................................................................
   486    517     if( pRoot==0 ){
   487    518       assert( db->mallocFailed );
   488    519       sqlite3ExprDelete(db, pLeft);
   489    520       sqlite3ExprDelete(db, pRight);
   490    521     }else{
   491    522       if( pRight ){
   492    523         pRoot->pRight = pRight;
   493         -      pRoot->flags |= EP_Collate & pRight->flags;
          524  +      pRoot->flags |= EP_Propagate & pRight->flags;
   494    525       }
   495    526       if( pLeft ){
   496    527         pRoot->pLeft = pLeft;
   497         -      pRoot->flags |= EP_Collate & pLeft->flags;
          528  +      pRoot->flags |= EP_Propagate & pLeft->flags;
   498    529       }
   499    530       exprSetHeight(pRoot);
   500    531     }
   501    532   }
   502    533   
   503    534   /*
   504    535   ** Allocate an Expr node which joins as many as two subtrees.
................................................................................
   590    621     pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
   591    622     if( pNew==0 ){
   592    623       sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */
   593    624       return 0;
   594    625     }
   595    626     pNew->x.pList = pList;
   596    627     assert( !ExprHasProperty(pNew, EP_xIsSelect) );
   597         -  sqlite3ExprSetHeight(pParse, pNew);
          628  +  sqlite3ExprSetHeightAndFlags(pParse, pNew);
   598    629     return pNew;
   599    630   }
   600    631   
   601    632   /*
   602    633   ** Assign a variable number to an expression that encodes a wildcard
   603    634   ** in the original SQL statement.  
   604    635   **
................................................................................
  1204   1235       sqlite3ExprDelete(db, pItem->pExpr);
  1205   1236       sqlite3DbFree(db, pItem->zName);
  1206   1237       sqlite3DbFree(db, pItem->zSpan);
  1207   1238     }
  1208   1239     sqlite3DbFree(db, pList->a);
  1209   1240     sqlite3DbFree(db, pList);
  1210   1241   }
         1242  +
         1243  +/*
         1244  +** Return the bitwise-OR of all Expr.flags fields in the given
         1245  +** ExprList.
         1246  +*/
         1247  +u32 sqlite3ExprListFlags(const ExprList *pList){
         1248  +  int i;
         1249  +  u32 m = 0;
         1250  +  if( pList ){
         1251  +    for(i=0; i<pList->nExpr; i++){
         1252  +       m |= pList->a[i].pExpr->flags;
         1253  +    }
         1254  +  }
         1255  +  return m;
         1256  +}
  1211   1257   
  1212   1258   /*
  1213   1259   ** These routines are Walker callbacks used to check expressions to
  1214   1260   ** see if they are "constant" for some definition of constant.  The
  1215   1261   ** Walker.eCode value determines the type of "constant" we are looking
  1216   1262   ** for.
  1217   1263   **
................................................................................
  1245   1291     }
  1246   1292   
  1247   1293     switch( pExpr->op ){
  1248   1294       /* Consider functions to be constant if all their arguments are constant
  1249   1295       ** and either pWalker->eCode==4 or 5 or the function has the
  1250   1296       ** SQLITE_FUNC_CONST flag. */
  1251   1297       case TK_FUNCTION:
  1252         -      if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_Constant) ){
         1298  +      if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
  1253   1299           return WRC_Continue;
  1254   1300         }else{
  1255   1301           pWalker->eCode = 0;
  1256   1302           return WRC_Abort;
  1257   1303         }
  1258   1304       case TK_ID:
  1259   1305       case TK_COLUMN:

Changes to src/parse.y.

  1074   1074           pRHS->flags |= EP_Generic;
  1075   1075         }
  1076   1076         A.pExpr = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, X.pExpr, pRHS, 0);
  1077   1077       }else{
  1078   1078         A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
  1079   1079         if( A.pExpr ){
  1080   1080           A.pExpr->x.pList = Y;
  1081         -        sqlite3ExprSetHeight(pParse, A.pExpr);
         1081  +        sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
  1082   1082         }else{
  1083   1083           sqlite3ExprListDelete(pParse->db, Y);
  1084   1084         }
  1085   1085         if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
  1086   1086       }
  1087   1087       A.zStart = X.zStart;
  1088   1088       A.zEnd = &E.z[E.n];
  1089   1089     }
  1090   1090     expr(A) ::= LP(B) select(X) RP(E). {
  1091   1091       A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
  1092   1092       if( A.pExpr ){
  1093   1093         A.pExpr->x.pSelect = X;
  1094         -      ExprSetProperty(A.pExpr, EP_xIsSelect);
  1095         -      sqlite3ExprSetHeight(pParse, A.pExpr);
         1094  +      ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
         1095  +      sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
  1096   1096       }else{
  1097   1097         sqlite3SelectDelete(pParse->db, X);
  1098   1098       }
  1099   1099       A.zStart = B.z;
  1100   1100       A.zEnd = &E.z[E.n];
  1101   1101     }
  1102   1102     expr(A) ::= expr(X) in_op(N) LP select(Y) RP(E).  [IN] {
  1103   1103       A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
  1104   1104       if( A.pExpr ){
  1105   1105         A.pExpr->x.pSelect = Y;
  1106         -      ExprSetProperty(A.pExpr, EP_xIsSelect);
  1107         -      sqlite3ExprSetHeight(pParse, A.pExpr);
         1106  +      ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
         1107  +      sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
  1108   1108       }else{
  1109   1109         sqlite3SelectDelete(pParse->db, Y);
  1110   1110       }
  1111   1111       if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
  1112   1112       A.zStart = X.zStart;
  1113   1113       A.zEnd = &E.z[E.n];
  1114   1114     }
  1115   1115     expr(A) ::= expr(X) in_op(N) nm(Y) dbnm(Z). [IN] {
  1116   1116       SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z);
  1117   1117       A.pExpr = sqlite3PExpr(pParse, TK_IN, X.pExpr, 0, 0);
  1118   1118       if( A.pExpr ){
  1119   1119         A.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
  1120         -      ExprSetProperty(A.pExpr, EP_xIsSelect);
  1121         -      sqlite3ExprSetHeight(pParse, A.pExpr);
         1120  +      ExprSetProperty(A.pExpr, EP_xIsSelect|EP_Subquery);
         1121  +      sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
  1122   1122       }else{
  1123   1123         sqlite3SrcListDelete(pParse->db, pSrc);
  1124   1124       }
  1125   1125       if( N ) A.pExpr = sqlite3PExpr(pParse, TK_NOT, A.pExpr, 0, 0);
  1126   1126       A.zStart = X.zStart;
  1127   1127       A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
  1128   1128     }
  1129   1129     expr(A) ::= EXISTS(B) LP select(Y) RP(E). {
  1130   1130       Expr *p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
  1131   1131       if( p ){
  1132   1132         p->x.pSelect = Y;
  1133         -      ExprSetProperty(p, EP_xIsSelect);
  1134         -      sqlite3ExprSetHeight(pParse, p);
         1133  +      ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
         1134  +      sqlite3ExprSetHeightAndFlags(pParse, p);
  1135   1135       }else{
  1136   1136         sqlite3SelectDelete(pParse->db, Y);
  1137   1137       }
  1138   1138       A.zStart = B.z;
  1139   1139       A.zEnd = &E.z[E.n];
  1140   1140     }
  1141   1141   %endif SQLITE_OMIT_SUBQUERY
  1142   1142   
  1143   1143   /* CASE expressions */
  1144   1144   expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
  1145   1145     A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0, 0);
  1146   1146     if( A.pExpr ){
  1147   1147       A.pExpr->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y;
  1148         -    sqlite3ExprSetHeight(pParse, A.pExpr);
         1148  +    sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
  1149   1149     }else{
  1150   1150       sqlite3ExprListDelete(pParse->db, Y);
  1151   1151       sqlite3ExprDelete(pParse->db, Z);
  1152   1152     }
  1153   1153     A.zStart = C.z;
  1154   1154     A.zEnd = &E.z[E.n];
  1155   1155   }

Changes to src/resolve.c.

   243    243     ** schema.  If not found, pSchema will remain NULL and nothing will match
   244    244     ** resulting in an appropriate error message toward the end of this routine
   245    245     */
   246    246     if( zDb ){
   247    247       testcase( pNC->ncFlags & NC_PartIdx );
   248    248       testcase( pNC->ncFlags & NC_IsCheck );
   249    249       if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
   250         -      /* Silently ignore database qualifiers inside CHECK constraints and partial
   251         -      ** indices.  Do not raise errors because that might break legacy and
   252         -      ** because it does not hurt anything to just ignore the database name. */
          250  +      /* Silently ignore database qualifiers inside CHECK constraints and
          251  +      ** partial indices.  Do not raise errors because that might break
          252  +      ** legacy and because it does not hurt anything to just ignore the
          253  +      ** database name. */
   253    254         zDb = 0;
   254    255       }else{
   255    256         for(i=0; i<db->nDb; i++){
   256    257           assert( db->aDb[i].zName );
   257    258           if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
   258    259             pSchema = db->aDb[i].pSchema;
   259    260             break;
................................................................................
   316    317               break;
   317    318             }
   318    319           }
   319    320         }
   320    321         if( pMatch ){
   321    322           pExpr->iTable = pMatch->iCursor;
   322    323           pExpr->pTab = pMatch->pTab;
   323         -        assert( (pMatch->jointype & JT_RIGHT)==0 ); /* RIGHT JOIN not (yet) supported */
          324  +        /* RIGHT JOIN not (yet) supported */
          325  +        assert( (pMatch->jointype & JT_RIGHT)==0 );
   324    326           if( (pMatch->jointype & JT_LEFT)!=0 ){
   325    327             ExprSetProperty(pExpr, EP_CanBeNull);
   326    328           }
   327    329           pSchema = pExpr->pTab->pSchema;
   328    330         }
   329    331       } /* if( pSrcList ) */
   330    332   
................................................................................
   637    639         pExpr->op = TK_COLUMN;
   638    640         pExpr->pTab = pItem->pTab;
   639    641         pExpr->iTable = pItem->iCursor;
   640    642         pExpr->iColumn = -1;
   641    643         pExpr->affinity = SQLITE_AFF_INTEGER;
   642    644         break;
   643    645       }
   644         -#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
          646  +#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
          647  +          && !defined(SQLITE_OMIT_SUBQUERY) */
   645    648   
   646    649       /* A lone identifier is the name of a column.
   647    650       */
   648    651       case TK_ID: {
   649    652         return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr);
   650    653       }
   651    654     
................................................................................
   702    705         }else{
   703    706           is_agg = pDef->xFunc==0;
   704    707           if( pDef->funcFlags & SQLITE_FUNC_UNLIKELY ){
   705    708             ExprSetProperty(pExpr, EP_Unlikely|EP_Skip);
   706    709             if( n==2 ){
   707    710               pExpr->iTable = exprProbability(pList->a[1].pExpr);
   708    711               if( pExpr->iTable<0 ){
   709         -              sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a "
   710         -                                      "constant between 0.0 and 1.0");
          712  +              sqlite3ErrorMsg(pParse,
          713  +                "second argument to likelihood() must be a "
          714  +                "constant between 0.0 and 1.0");
   711    715                 pNC->nErr++;
   712    716               }
   713    717             }else{
   714         -            /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to
   715         -            ** likelihood(X, 0.0625).
   716         -            ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
   717         -            ** likelihood(X,0.0625).
   718         -            ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for
   719         -            ** likelihood(X,0.9375).
   720         -            ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to
   721         -            ** likelihood(X,0.9375). */
          718  +            /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
          719  +            ** equivalent to likelihood(X, 0.0625).
          720  +            ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is
          721  +            ** short-hand for likelihood(X,0.0625).
          722  +            ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand
          723  +            ** for likelihood(X,0.9375).
          724  +            ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent
          725  +            ** to likelihood(X,0.9375). */
   722    726               /* TUNING: unlikely() probability is 0.0625.  likely() is 0.9375 */
   723    727               pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120;
   724    728             }             
   725    729           }
   726    730   #ifndef SQLITE_OMIT_AUTHORIZATION
   727    731           auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
   728    732           if( auth!=SQLITE_OK ){
................................................................................
   731    735                                       pDef->zName);
   732    736               pNC->nErr++;
   733    737             }
   734    738             pExpr->op = TK_NULL;
   735    739             return WRC_Prune;
   736    740           }
   737    741   #endif
   738         -        if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant);
          742  +        if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ){
          743  +          ExprSetProperty(pExpr,EP_ConstFunc);
          744  +        }
   739    745         }
   740    746         if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
   741    747           sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
   742    748           pNC->nErr++;
   743    749           is_agg = 0;
   744    750         }else if( no_such_func && pParse->db->init.busy==0 ){
   745    751           sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId);
................................................................................
  1042   1048     assert( pEList!=0 );  /* sqlite3SelectNew() guarantees this */
  1043   1049     for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
  1044   1050       if( pItem->u.x.iOrderByCol ){
  1045   1051         if( pItem->u.x.iOrderByCol>pEList->nExpr ){
  1046   1052           resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
  1047   1053           return 1;
  1048   1054         }
  1049         -      resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0);
         1055  +      resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,
         1056  +                   zType,0);
  1050   1057       }
  1051   1058     }
  1052   1059     return 0;
  1053   1060   }
  1054   1061   
  1055   1062   /*
  1056   1063   ** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.

Changes to src/select.c.

  3190   3190   ** exist on the table t1, a complete scan of the data might be
  3191   3191   ** avoided.
  3192   3192   **
  3193   3193   ** Flattening is only attempted if all of the following are true:
  3194   3194   **
  3195   3195   **   (1)  The subquery and the outer query do not both use aggregates.
  3196   3196   **
  3197         -**   (2)  The subquery is not an aggregate or the outer query is not a join.
         3197  +**   (2)  The subquery is not an aggregate or (2a) the outer query is not a join
         3198  +**        and (2b) the outer query does not use subqueries other than the one
         3199  +**        FROM-clause subquery that is a candidate for flattening.  (2b is
         3200  +**        due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
  3198   3201   **
  3199   3202   **   (3)  The subquery is not the right operand of a left outer join
  3200   3203   **        (Originally ticket #306.  Strengthened by ticket #3300)
  3201   3204   **
  3202   3205   **   (4)  The subquery is not DISTINCT.
  3203   3206   **
  3204   3207   **  (**)  At one point restrictions (4) and (5) defined a subset of DISTINCT
................................................................................
  3327   3330     if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
  3328   3331     pSrc = p->pSrc;
  3329   3332     assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
  3330   3333     pSubitem = &pSrc->a[iFrom];
  3331   3334     iParent = pSubitem->iCursor;
  3332   3335     pSub = pSubitem->pSelect;
  3333   3336     assert( pSub!=0 );
  3334         -  if( isAgg && subqueryIsAgg ) return 0;                 /* Restriction (1)  */
  3335         -  if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;          /* Restriction (2)  */
         3337  +  if( subqueryIsAgg ){
         3338  +    if( isAgg ) return 0;                                /* Restriction (1)   */
         3339  +    if( pSrc->nSrc>1 ) return 0;                         /* Restriction (2a)  */
         3340  +    if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery))
         3341  +     || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0
         3342  +     || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0
         3343  +    ){
         3344  +      return 0;                                          /* Restriction (2b)  */
         3345  +    }
         3346  +  }
         3347  +    
  3336   3348     pSubSrc = pSub->pSrc;
  3337   3349     assert( pSubSrc );
  3338   3350     /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
  3339   3351     ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET
  3340   3352     ** because they could be computed at compile-time.  But when LIMIT and OFFSET
  3341   3353     ** became arbitrary expressions, we were forced to add restrictions (13)
  3342   3354     ** and (14). */
................................................................................
  4748   4760     pTabList = p->pSrc;
  4749   4761     pEList = p->pEList;
  4750   4762     if( pParse->nErr || db->mallocFailed ){
  4751   4763       goto select_end;
  4752   4764     }
  4753   4765     isAgg = (p->selFlags & SF_Aggregate)!=0;
  4754   4766     assert( pEList!=0 );
         4767  +#if SELECTTRACE_ENABLED
         4768  +  if( sqlite3SelectTrace & 0x100 ){
         4769  +    SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
         4770  +    sqlite3TreeViewSelect(0, p, 0);
         4771  +  }
         4772  +#endif
         4773  +
  4755   4774   
  4756   4775     /* Begin generating code.
  4757   4776     */
  4758   4777     v = sqlite3GetVdbe(pParse);
  4759   4778     if( v==0 ) goto select_end;
  4760   4779   
  4761   4780     /* If writing to memory or generating a set
................................................................................
  5496   5515   void sqlite3PrintSelect(Select *p, int indent);
  5497   5516   /*
  5498   5517   ** Generate a human-readable description of a the Select object.
  5499   5518   */
  5500   5519   void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
  5501   5520     int n = 0;
  5502   5521     pView = sqlite3TreeViewPush(pView, moreToFollow);
  5503         -  sqlite3TreeViewLine(pView, "SELECT%s%s",
         5522  +  sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p)",
  5504   5523       ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
  5505         -    ((p->selFlags & SF_Aggregate) ? " agg_flag" : "")
         5524  +    ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p
  5506   5525     );
  5507   5526     if( p->pSrc && p->pSrc->nSrc ) n++;
  5508   5527     if( p->pWhere ) n++;
  5509   5528     if( p->pGroupBy ) n++;
  5510   5529     if( p->pHaving ) n++;
  5511   5530     if( p->pOrderBy ) n++;
  5512   5531     if( p->pLimit ) n++;

Changes to src/shell.c.

  3017   3017           */
  3018   3018           if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break;
  3019   3019           sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT);
  3020   3020           if( i<nCol-1 && sCtx.cTerm!=sCtx.cColSep ){
  3021   3021             fprintf(stderr, "%s:%d: expected %d columns but found %d - "
  3022   3022                             "filling the rest with NULL\n",
  3023   3023                             sCtx.zFile, startLine, nCol, i+1);
  3024         -          i++;
         3024  +          i += 2;
  3025   3025             while( i<=nCol ){ sqlite3_bind_null(pStmt, i); i++; }
  3026   3026           }
  3027   3027         }
  3028   3028         if( sCtx.cTerm==sCtx.cColSep ){
  3029   3029           do{
  3030   3030             xRead(&sCtx);
  3031   3031             i++;

Changes to src/sqliteInt.h.

  2050   2050   #define EP_Skip      0x001000 /* COLLATE, AS, or UNLIKELY */
  2051   2051   #define EP_Reduced   0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
  2052   2052   #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
  2053   2053   #define EP_Static    0x008000 /* Held in memory not obtained from malloc() */
  2054   2054   #define EP_MemToken  0x010000 /* Need to sqlite3DbFree() Expr.zToken */
  2055   2055   #define EP_NoReduce  0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
  2056   2056   #define EP_Unlikely  0x040000 /* unlikely() or likelihood() function */
  2057         -#define EP_Constant  0x080000 /* Node is a constant */
         2057  +#define EP_ConstFunc 0x080000 /* Node is a SQLITE_FUNC_CONSTANT function */
  2058   2058   #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
         2059  +#define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
         2060  +
         2061  +/*
         2062  +** Combinations of two or more EP_* flags
         2063  +*/
         2064  +#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
  2059   2065   
  2060   2066   /*
  2061   2067   ** These macros can be used to test, set, or clear bits in the 
  2062   2068   ** Expr.flags field.
  2063   2069   */
  2064   2070   #define ExprHasProperty(E,P)     (((E)->flags&(P))!=0)
  2065   2071   #define ExprHasAllProperty(E,P)  (((E)->flags&(P))==(P))
................................................................................
  3159   3165   Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*);
  3160   3166   void sqlite3ExprAssignVarNumber(Parse*, Expr*);
  3161   3167   void sqlite3ExprDelete(sqlite3*, Expr*);
  3162   3168   ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
  3163   3169   void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
  3164   3170   void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
  3165   3171   void sqlite3ExprListDelete(sqlite3*, ExprList*);
         3172  +u32 sqlite3ExprListFlags(const ExprList*);
  3166   3173   int sqlite3Init(sqlite3*, char**);
  3167   3174   int sqlite3InitCallback(void*, int, char**, char**);
  3168   3175   void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
  3169   3176   void sqlite3ResetAllSchemasOfConnection(sqlite3*);
  3170   3177   void sqlite3ResetOneSchema(sqlite3*,int);
  3171   3178   void sqlite3CollapseDatabaseArray(sqlite3*);
  3172   3179   void sqlite3BeginParse(Parse*,int);
................................................................................
  3742   3749     #define sqlite3JournalExists(p) 1
  3743   3750   #endif
  3744   3751   
  3745   3752   void sqlite3MemJournalOpen(sqlite3_file *);
  3746   3753   int sqlite3MemJournalSize(void);
  3747   3754   int sqlite3IsMemJournal(sqlite3_file *);
  3748   3755   
         3756  +void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
  3749   3757   #if SQLITE_MAX_EXPR_DEPTH>0
  3750         -  void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
  3751   3758     int sqlite3SelectExprHeight(Select *);
  3752   3759     int sqlite3ExprCheckHeight(Parse*, int);
  3753   3760   #else
  3754         -  #define sqlite3ExprSetHeight(x,y)
  3755   3761     #define sqlite3SelectExprHeight(x) 0
  3756   3762     #define sqlite3ExprCheckHeight(x,y)
  3757   3763   #endif
  3758   3764   
  3759   3765   u32 sqlite3Get4byte(const u8*);
  3760   3766   void sqlite3Put4byte(u8*, u32);
  3761   3767   

Changes to src/vdbeInt.h.

   340    340     Mem *aVar;              /* Values for the OP_Variable opcode. */
   341    341     char **azVar;           /* Name of variables */
   342    342     ynVar nVar;             /* Number of entries in aVar[] */
   343    343     ynVar nzVar;            /* Number of entries in azVar[] */
   344    344     u32 cacheCtr;           /* VdbeCursor row cache generation counter */
   345    345     int pc;                 /* The program counter */
   346    346     int rc;                 /* Value to return */
          347  +#ifdef SQLITE_DEBUG
          348  +  int rcApp;              /* errcode set by sqlite3_result_error_code() */
          349  +#endif
   347    350     u16 nResColumn;         /* Number of columns in one row of the result set */
   348    351     u8 errorAction;         /* Recovery action to do in case of an error */
   349    352     u8 minWriteFileFormat;  /* Minimum file format for writable database files */
   350    353     bft explain:2;          /* True if EXPLAIN present on SQL command */
   351    354     bft inVtabMethod:2;     /* See comments above */
   352    355     bft changeCntOn:1;      /* True to update the change-counter */
   353    356     bft expired:1;          /* True if the VM needs to be recompiled */

Changes to src/vdbeapi.c.

   377    377   void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
   378    378     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   379    379     sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
   380    380   }
   381    381   void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
   382    382     pCtx->isError = errCode;
   383    383     pCtx->fErrorOrAux = 1;
          384  +#ifdef SQLITE_DEBUG
          385  +  pCtx->pVdbe->rcApp = errCode;
          386  +#endif
   384    387     if( pCtx->pOut->flags & MEM_Null ){
   385    388       sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, 
   386    389                            SQLITE_UTF8, SQLITE_STATIC);
   387    390     }
   388    391   }
   389    392   
   390    393   /* Force an SQLITE_TOOBIG error. */
................................................................................
   457    460       ** returns, and those were broken by the automatic-reset change.  As a
   458    461       ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
   459    462       ** legacy behavior of returning SQLITE_MISUSE for cases where the 
   460    463       ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
   461    464       ** or SQLITE_BUSY error.
   462    465       */
   463    466   #ifdef SQLITE_OMIT_AUTORESET
   464         -    if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){
          467  +    if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
   465    468         sqlite3_reset((sqlite3_stmt*)p);
   466    469       }else{
   467    470         return SQLITE_MISUSE_BKPT;
   468    471       }
   469    472   #else
   470    473       sqlite3_reset((sqlite3_stmt*)p);
   471    474   #endif
................................................................................
   503    506   #endif
   504    507   
   505    508       db->nVdbeActive++;
   506    509       if( p->readOnly==0 ) db->nVdbeWrite++;
   507    510       if( p->bIsReader ) db->nVdbeRead++;
   508    511       p->pc = 0;
   509    512     }
          513  +#ifdef SQLITE_DEBUG
          514  +  p->rcApp = SQLITE_OK;
          515  +#endif
   510    516   #ifndef SQLITE_OMIT_EXPLAIN
   511    517     if( p->explain ){
   512    518       rc = sqlite3VdbeList(p);
   513    519     }else
   514    520   #endif /* SQLITE_OMIT_EXPLAIN */
   515    521     {
   516    522       db->nVdbeExec++;
................................................................................
   547    553     ** be one of the values in the first assert() below. Variable p->rc 
   548    554     ** contains the value that would be returned if sqlite3_finalize() 
   549    555     ** were called on statement p.
   550    556     */
   551    557     assert( rc==SQLITE_ROW  || rc==SQLITE_DONE   || rc==SQLITE_ERROR 
   552    558          || rc==SQLITE_BUSY || rc==SQLITE_MISUSE
   553    559     );
   554         -  assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE );
          560  +  assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp );
   555    561     if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
   556    562       /* If this statement was prepared using sqlite3_prepare_v2(), and an
   557    563       ** error has occurred, then return the error code in p->rc to the
   558    564       ** caller. Set the error code in the database handle to the same value.
   559    565       */ 
   560    566       rc = sqlite3VdbeTransferError(p);
   561    567     }

Changes to test/collate8.test.

     9      9   #    May you share freely, never taking more than you give.
    10     10   #
    11     11   #***********************************************************************
    12     12   # This file implements regression tests for SQLite library.  The
    13     13   # focus of this script is making sure collations pass through the
    14     14   # unary + operator.
    15     15   #
    16         -# $Id: collate8.test,v 1.2 2008/08/25 12:14:09 drh Exp $
           16  +# 2015-02-09:  Added tests to make sure COLLATE passes through function
           17  +# calls.  Ticket [ca0d20b6cdddec5e81b8d66f89c46a5583b5f6f6].
           18  +#
    17     19   
    18     20   set testdir [file dirname $argv0]
    19     21   source $testdir/tester.tcl
    20     22   
    21     23   do_test collate8-1.1 {
    22     24     execsql {
    23     25       CREATE TABLE t1(a TEXT COLLATE nocase);
................................................................................
   117    119     }
   118    120   } {abc ABC}
   119    121   do_test collate8-2.8 {
   120    122     execsql {
   121    123       SELECT a COLLATE nocase AS x FROM t2 WHERE 'abc'=x COLLATE binary;
   122    124     }
   123    125   } {abc}
          126  +
          127  +# Make sure the COLLATE operator perculates up through function calls
          128  +# and other Expr structures that use the Expr.x.pList field.
          129  +#
          130  +do_execsql_test collate8-3.1 {
          131  +  SELECT 'abc'==('ABC'||'') COLLATE nocase;
          132  +  SELECT 'abc'==('ABC'||'' COLLATE nocase);
          133  +  SELECT 'abc'==('ABC'||('' COLLATE nocase));
          134  +  SELECT 'abc'==('ABC'||upper('' COLLATE nocase));
          135  +} {1 1 1 1}
          136  +do_execsql_test collate8-3.2 {
          137  +  SELECT 'abc'==('ABC'||max('' COLLATE nocase,'' COLLATE binary));
          138  +} {1}
          139  +
          140  +# The COLLATE binary is on the left and so takes precedence
          141  +do_execsql_test collate8-3.3 {
          142  +  SELECT 'abc'==('ABC'||max('' COLLATE binary,'' COLLATE nocase));
          143  +} {0}
          144  +
          145  +do_execsql_test collate8-3.4 {
          146  +  SELECT 'abc'==('ABC'||CASE WHEN 1-1=2 THEN '' COLLATE nocase
          147  +                                        ELSE '' COLLATE binary END);
          148  +  SELECT 'abc'==('ABC'||CASE WHEN 1+1=2 THEN '' COLLATE nocase
          149  +                                        ELSE '' COLLATE binary END);
          150  +} {1 1}
          151  +do_execsql_test collate8-3.5 {
          152  +  SELECT 'abc'==('ABC'||CASE WHEN 1=2 THEN '' COLLATE binary
          153  +                                      ELSE '' COLLATE nocase END);
          154  +} {0}
          155  +
   124    156   
   125    157   finish_test

Changes to test/select6.test.

   552    552   do_catchsql_test 10.8 {
   553    553     SELECT * FROM (
   554    554       SELECT * FROM k UNION ALL
   555    555       SELECT * FROM t UNION ALL 
   556    556       SELECT l,m,l FROM j 
   557    557     )
   558    558   } $err
          559  +
          560  +# 2015-02-09 Ticket [2f7170d73bf9abf80339187aa3677dce3dbcd5ca]
          561  +# "misuse of aggregate" error if aggregate column from FROM
          562  +# subquery is used in correlated subquery 
          563  +#
          564  +do_execsql_test 11.1 {
          565  +  DROP TABLE IF EXISTS t1;
          566  +  CREATE TABLE t1(w INT, x INT);
          567  +  INSERT INTO t1(w,x)
          568  +   VALUES(1,10),(2,20),(3,30),
          569  +         (2,21),(3,31),
          570  +         (3,32);
          571  +  CREATE INDEX t1wx ON t1(w,x);
          572  +
          573  +  DROP TABLE IF EXISTS t2;
          574  +  CREATE TABLE t2(w INT, y VARCHAR(8));
          575  +  INSERT INTO t2(w,y) VALUES(1,'one'),(2,'two'),(3,'three'),(4,'four');
          576  +  CREATE INDEX t2wy ON t2(w,y);
          577  +
          578  +  SELECT cnt, xyz, (SELECT y FROM t2 WHERE w=cnt), '|'
          579  +    FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
          580  +   ORDER BY cnt, xyz;
          581  +} {1 1 one | 2 2 two | 3 3 three |}
          582  +do_execsql_test 11.2 {
          583  +  SELECT cnt, xyz, lower((SELECT y FROM t2 WHERE w=cnt)), '|'
          584  +    FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
          585  +   ORDER BY cnt, xyz;
          586  +} {1 1 one | 2 2 two | 3 3 three |}
          587  +do_execsql_test 11.3 {
          588  +  SELECT cnt, xyz, '|'
          589  +    FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
          590  +   WHERE (SELECT y FROM t2 WHERE w=cnt)!='two'
          591  +   ORDER BY cnt, xyz;
          592  +} {1 1 | 3 3 |}
          593  +do_execsql_test 11.4 {
          594  +  SELECT cnt, xyz, '|'
          595  +    FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
          596  +   ORDER BY lower((SELECT y FROM t2 WHERE w=cnt));
          597  +} {1 1 | 3 3 | 2 2 |}
          598  +do_execsql_test 11.5 {
          599  +  SELECT cnt, xyz, 
          600  +         CASE WHEN (SELECT y FROM t2 WHERE w=cnt)=='two'
          601  +              THEN 'aaa' ELSE 'bbb'
          602  +          END, '|'
          603  +    FROM (SELECT count(*) AS cnt, w AS xyz FROM t1 GROUP BY 2)
          604  +   ORDER BY +cnt;
          605  +} {1 1 bbb | 2 2 aaa | 3 3 bbb |}
          606  +
          607  +do_execsql_test 11.100 {
          608  +  DROP TABLE t1;
          609  +  DROP TABLE t2;
          610  +  CREATE TABLE t1(x);
          611  +  CREATE TABLE t2(y, z);
          612  +  SELECT ( SELECT y FROM t2 WHERE z = cnt )
          613  +    FROM ( SELECT count(*) AS cnt FROM t1 );
          614  +} {{}}
   559    615   
   560    616   
   561    617   finish_test

Changes to test/shell5.test.

   401    401   SELECT * FROM t5;
   402    402     }]
   403    403     # Handle platform end-of-line differences
   404    404     regsub -all {[\n\r]?\n} $x <EOL> x
   405    405     set x
   406    406   } "0 \{\"test 1\"\x1F,test 2<EOL>\x1Etest 3\x1Ftest 4<EOL>\x1E\}"
   407    407   
          408  +do_test shell5-4.1 {
          409  +  forcedelete shell5.csv
          410  +  set fd [open shell5.csv w]
          411  +  puts $fd "1,2,3"
          412  +  puts $fd "4,5"
          413  +  puts $fd "6,7,8"
          414  +  close $fd
          415  +  catchcmd test.db [string trim {
          416  +.mode csv
          417  +CREATE TABLE t6(a, b, c);
          418  +.import shell5.csv t6
          419  +  }]
          420  +  db eval { SELECT * FROM t6 ORDER BY a }
          421  +} {1 2 3 4 5 {} 6 7 8}
          422  +
          423  +do_test shell5-4.2 {
          424  +  forcedelete shell5.csv
          425  +  set fd [open shell5.csv w]
          426  +  puts $fd "1,2,3"
          427  +  puts $fd "4,5"
          428  +  puts $fd "6,7,8,9"
          429  +  close $fd
          430  +  catchcmd test.db [string trim {
          431  +.mode csv
          432  +CREATE TABLE t7(a, b, c);
          433  +.import shell5.csv t7
          434  +  }]
          435  +  db eval { SELECT * FROM t7 ORDER BY a }
          436  +} {1 2 3 4 5 {} 6 7 8}
          437  +
   408    438   finish_test

Changes to tool/spaceanal.tcl.

     1      1   # Run this TCL script using "testfixture" in order get a report that shows
     2      2   # how much disk space is used by a particular data to actually store data
     3      3   # versus how much space is unused.
     4      4   #
     5      5   
     6      6   if {[catch {
            7  +
            8  +# Argument $tname is the name of a table within the database opened by
            9  +# database handle [db]. Return true if it is a WITHOUT ROWID table, or
           10  +# false otherwise.
           11  +#
           12  +proc is_without_rowid {tname} {
           13  +  set t [string map {' ''} $tname]
           14  +  db eval "PRAGMA index_list = '$t'" o {
           15  +    if {$o(origin) == "pk"} {
           16  +      set n $o(name)
           17  +      if {0==[db one { SELECT count(*) FROM sqlite_master WHERE name=$n }]} {
           18  +        return 1
           19  +      }
           20  +    }
           21  +  }
           22  +  return 0
           23  +}
           24  +
     7     25   # Get the name of the database to analyze
     8     26   #
     9     27   proc usage {} {
    10     28     set argv0 [file rootname [file tail [info nameofexecutable]]]
    11     29     puts stderr "Usage: $argv0 database-name"
    12     30     exit 1
    13     31   }
................................................................................
   163    181   
   164    182   set isCompressed 0
   165    183   set compressOverhead 0
   166    184   set sql { SELECT name, tbl_name FROM sqlite_master WHERE rootpage>0 }
   167    185   foreach {name tblname} [concat sqlite_master sqlite_master [db eval $sql]] {
   168    186   
   169    187     set is_index [expr {$name!=$tblname}]
          188  +  set idx_btree [expr {$is_index || [is_without_rowid $name]}]
   170    189     db eval {
   171    190       SELECT 
   172    191         sum(ncell) AS nentry,
   173         -      sum(isleaf(pagetype, $is_index) * ncell) AS leaf_entries,
          192  +      sum(isleaf(pagetype, $idx_btree) * ncell) AS leaf_entries,
   174    193         sum(payload) AS payload,
   175         -      sum(isoverflow(pagetype, $is_index) * payload) AS ovfl_payload,
          194  +      sum(isoverflow(pagetype, $idx_btree) * payload) AS ovfl_payload,
   176    195         sum(path LIKE '%+000000') AS ovfl_cnt,
   177    196         max(mx_payload) AS mx_payload,
   178         -      sum(isinternal(pagetype, $is_index)) AS int_pages,
   179         -      sum(isleaf(pagetype, $is_index)) AS leaf_pages,
   180         -      sum(isoverflow(pagetype, $is_index)) AS ovfl_pages,
   181         -      sum(isinternal(pagetype, $is_index) * unused) AS int_unused,
   182         -      sum(isleaf(pagetype, $is_index) * unused) AS leaf_unused,
   183         -      sum(isoverflow(pagetype, $is_index) * unused) AS ovfl_unused,
          197  +      sum(isinternal(pagetype, $idx_btree)) AS int_pages,
          198  +      sum(isleaf(pagetype, $idx_btree)) AS leaf_pages,
          199  +      sum(isoverflow(pagetype, $idx_btree)) AS ovfl_pages,
          200  +      sum(isinternal(pagetype, $idx_btree) * unused) AS int_unused,
          201  +      sum(isleaf(pagetype, $idx_btree) * unused) AS leaf_unused,
          202  +      sum(isoverflow(pagetype, $idx_btree) * unused) AS ovfl_unused,
   184    203         sum(pgsize) AS compressed_size
   185    204       FROM temp.dbstat WHERE name = $name
   186    205     } break
   187    206   
   188    207     set total_pages [expr {$leaf_pages+$int_pages+$ovfl_pages}]
   189    208     set storage [expr {$total_pages*$pageSize}]
   190    209     if {!$isCompressed && $storage>$compressed_size} {