/ Check-in [1186e3ce]
Login

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

Overview
Comment:Various size optimizations. (CVS 1867)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:1186e3ce0b660f1cf8d03a275b0331da64d21f1b
User & Date: drh 2004-07-26 00:31:09
Context
2004-07-26
12:24
Fix problems for 64-bit machines and when SQLITE_OMIT_AUTHORIZATION is defined. (CVS 1868) check-in: e3cad1ab user: drh tags: trunk
00:31
Various size optimizations. (CVS 1867) check-in: 1186e3ce user: drh tags: trunk
2004-07-24
17:38
Prepared statements now work with CREATE and DROP. All tests pass. No memory leaks. (CVS 1866) check-in: ebdb661e user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/build.c.

    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **     PRAGMA
    25     25   **
    26         -** $Id: build.c,v 1.243 2004/07/24 17:38:29 drh Exp $
           26  +** $Id: build.c,v 1.244 2004/07/26 00:31:09 drh Exp $
    27     27   */
    28     28   #include "sqliteInt.h"
    29     29   #include <ctype.h>
    30     30   
    31     31   /*
    32     32   ** This routine is called when a new SQL statement is beginning to
    33     33   ** be parsed.  Check to see if the schema for the database needs
................................................................................
  1405   1405     }
  1406   1406   
  1407   1407     /* Add the table to the in-memory representation of the database.
  1408   1408     */
  1409   1409     if( db->init.busy && pParse->nErr==0 ){
  1410   1410       Table *pOld;
  1411   1411       FKey *pFKey;
  1412         -    pOld = sqlite3HashInsert(&db->aDb[p->iDb].tblHash, 
  1413         -                            p->zName, strlen(p->zName)+1, p);
         1412  +    Db *pDb = &db->aDb[p->iDb];
         1413  +    pOld = sqlite3HashInsert(&pDb->tblHash, p->zName, strlen(p->zName)+1, p);
  1414   1414       if( pOld ){
  1415   1415         assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
  1416   1416         return;
  1417   1417       }
  1418   1418       for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
  1419   1419         int nTo = strlen(pFKey->zTo) + 1;
  1420         -      pFKey->pNextTo = sqlite3HashFind(&db->aDb[p->iDb].aFKey, pFKey->zTo, nTo);
  1421         -      sqlite3HashInsert(&db->aDb[p->iDb].aFKey, pFKey->zTo, nTo, pFKey);
         1420  +      pFKey->pNextTo = sqlite3HashFind(&pDb->aFKey, pFKey->zTo, nTo);
         1421  +      sqlite3HashInsert(&pDb->aFKey, pFKey->zTo, nTo, pFKey);
  1422   1422       }
  1423   1423       pParse->pNewTable = 0;
  1424   1424       db->nTable++;
  1425   1425       db->flags |= SQLITE_InternChanges;
  1426   1426     }
  1427   1427   }
  1428   1428   
................................................................................
  2399   2399   }
  2400   2400   
  2401   2401   /*
  2402   2402   ** Delete an entire SrcList including all its substructure.
  2403   2403   */
  2404   2404   void sqlite3SrcListDelete(SrcList *pList){
  2405   2405     int i;
         2406  +  struct SrcList_item *pItem;
  2406   2407     if( pList==0 ) return;
  2407         -  for(i=0; i<pList->nSrc; i++){
  2408         -    sqliteFree(pList->a[i].zDatabase);
  2409         -    sqliteFree(pList->a[i].zName);
  2410         -    sqliteFree(pList->a[i].zAlias);
  2411         -    if( pList->a[i].pTab && pList->a[i].pTab->isTransient ){
  2412         -      sqlite3DeleteTable(0, pList->a[i].pTab);
         2408  +  for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){
         2409  +    sqliteFree(pItem->zDatabase);
         2410  +    sqliteFree(pItem->zName);
         2411  +    sqliteFree(pItem->zAlias);
         2412  +    if( pItem->pTab && pItem->pTab->isTransient ){
         2413  +      sqlite3DeleteTable(0, pItem->pTab);
  2413   2414       }
  2414         -    sqlite3SelectDelete(pList->a[i].pSelect);
  2415         -    sqlite3ExprDelete(pList->a[i].pOn);
  2416         -    sqlite3IdListDelete(pList->a[i].pUsing);
         2415  +    sqlite3SelectDelete(pItem->pSelect);
         2416  +    sqlite3ExprDelete(pItem->pOn);
         2417  +    sqlite3IdListDelete(pItem->pUsing);
  2417   2418     }
  2418   2419     sqliteFree(pList);
  2419   2420   }
  2420   2421   
  2421   2422   /*
  2422   2423   ** Begin a transaction
  2423   2424   */

Changes to src/expr.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains routines used for analyzing expressions and
    13     13   ** for generating VDBE code that evaluates expressions in SQLite.
    14     14   **
    15         -** $Id: expr.c,v 1.152 2004/07/21 02:53:30 drh Exp $
           15  +** $Id: expr.c,v 1.153 2004/07/26 00:31:09 drh Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include <ctype.h>
    19     19   
    20     20   char const *sqlite3AffinityString(char affinity){
    21     21     switch( affinity ){
    22     22       case SQLITE_AFF_INTEGER: return "i";
................................................................................
   166    166   static CollSeq* binaryCompareCollSeq(Parse *pParse, Expr *pLeft, Expr *pRight){
   167    167     CollSeq *pColl = sqlite3ExprCollSeq(pParse, pLeft);
   168    168     if( !pColl ){
   169    169       pColl = sqlite3ExprCollSeq(pParse, pRight);
   170    170     }
   171    171     return pColl;
   172    172   }
          173  +
          174  +/*
          175  +** Generate code for a comparison operator.
          176  +*/
          177  +static int codeCompare(
          178  +  Parse *pParse,    /* The parsing (and code generating) context */
          179  +  Expr *pLeft,      /* The left operand */
          180  +  Expr *pRight,     /* The right operand */
          181  +  int opcode,       /* The comparison opcode */
          182  +  int dest,         /* Jump here if true.  */
          183  +  int jumpIfNull    /* If true, jump if either operand is NULL */
          184  +){
          185  +  int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull);
          186  +  CollSeq *p3 = binaryCompareCollSeq(pParse, pLeft, pRight);
          187  +  return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void *)p3, P3_COLLSEQ);
          188  +}
   173    189   
   174    190   /*
   175    191   ** Construct a new expression node and return a pointer to it.  Memory
   176    192   ** for this node is obtained from sqliteMalloc().  The calling function
   177    193   ** is responsible for making sure the node eventually gets freed.
   178    194   */
   179    195   Expr *sqlite3Expr(int op, Expr *pLeft, Expr *pRight, Token *pToken){
................................................................................
   429    445   }
   430    446   
   431    447   /*
   432    448   ** Delete an entire expression list.
   433    449   */
   434    450   void sqlite3ExprListDelete(ExprList *pList){
   435    451     int i;
          452  +  struct ExprList_item *pItem;
   436    453     if( pList==0 ) return;
   437    454     assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) );
   438    455     assert( pList->nExpr<=pList->nAlloc );
   439         -  for(i=0; i<pList->nExpr; i++){
   440         -    sqlite3ExprDelete(pList->a[i].pExpr);
   441         -    sqliteFree(pList->a[i].zName);
          456  +  for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){
          457  +    sqlite3ExprDelete(pItem->pExpr);
          458  +    sqliteFree(pItem->zName);
   442    459     }
   443    460     sqliteFree(pList->a);
   444    461     sqliteFree(pList);
   445    462   }
   446    463   
   447    464   /*
   448    465   ** Walk an expression tree.  Return 1 if the expression is constant
................................................................................
   856    873         if( pExpr->pSelect ){
   857    874           /* Case 1:     expr IN (SELECT ...)
   858    875           **
   859    876           ** Generate code to write the results of the select into the temporary
   860    877           ** table allocated and opened above.
   861    878           */
   862    879           int iParm = pExpr->iTable +  (((int)affinity)<<16);
          880  +        ExprList *pEList;
   863    881           assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
   864    882           sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0);
   865         -        if( pExpr->pSelect->pEList && pExpr->pSelect->pEList->nExpr>0 ){ 
          883  +        pEList = pExpr->pSelect->pEList;
          884  +        if( pEList && pEList->nExpr>0 ){ 
   866    885             keyInfo.aColl[0] = binaryCompareCollSeq(pParse, pExpr->pLeft,
   867         -              pExpr->pSelect->pEList->a[0].pExpr);
          886  +              pEList->a[0].pExpr);
   868    887           }
   869    888         }else if( pExpr->pList ){
   870    889           /* Case 2:     expr IN (exprlist)
   871    890           **
   872    891   	** For each expression, build an index key from the evaluation and
   873    892           ** store it in the temporary table. If <expr> is a column, then use
   874    893           ** that columns affinity when building index keys. If <expr> is not
................................................................................
  1148   1167       }
  1149   1168       case TK_LT:
  1150   1169       case TK_LE:
  1151   1170       case TK_GT:
  1152   1171       case TK_GE:
  1153   1172       case TK_NE:
  1154   1173       case TK_EQ: {
  1155         -      int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, 0);
  1156         -      CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
  1157   1174         sqlite3ExprCode(pParse, pExpr->pLeft);
  1158   1175         sqlite3ExprCode(pParse, pExpr->pRight);
  1159         -      sqlite3VdbeOp3(v, op, p1, 0, (void *)p3, P3_COLLSEQ);
         1176  +      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0);
  1160   1177         break;
  1161   1178       }
  1162   1179       case TK_AND:
  1163   1180       case TK_OR:
  1164   1181       case TK_PLUS:
  1165   1182       case TK_STAR:
  1166   1183       case TK_MINUS:
................................................................................
  1277   1294         sqlite3VdbeOp3(v, OP_MakeRecord, 1, 0, affStr, P3_STATIC); /* addr + 4 */
  1278   1295         sqlite3VdbeAddOp(v, OP_Found, pExpr->iTable, addr+7);
  1279   1296         sqlite3VdbeAddOp(v, OP_AddImm, -1, 0);                  /* addr + 6 */
  1280   1297   
  1281   1298         break;
  1282   1299       }
  1283   1300       case TK_BETWEEN: {
  1284         -      int p1;
  1285         -      CollSeq *p3;
  1286         -      sqlite3ExprCode(pParse, pExpr->pLeft);
         1301  +      Expr *pLeft = pExpr->pLeft;
         1302  +      struct ExprList_item *pLItem = pExpr->pList->a;
         1303  +      Expr *pRight = pLItem->pExpr;
         1304  +      sqlite3ExprCode(pParse, pLeft);
  1287   1305         sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
  1288         -      sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr);
  1289         -      p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, 0);
  1290         -      p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[0].pExpr);
  1291         -      sqlite3VdbeOp3(v, OP_Ge, p1, 0, (void *)p3, P3_COLLSEQ);
         1306  +      sqlite3ExprCode(pParse, pRight);
         1307  +      codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0);
  1292   1308         sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
  1293         -      sqlite3ExprCode(pParse, pExpr->pList->a[1].pExpr);
  1294         -      p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[1].pExpr, 0);
  1295         -      p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[1].pExpr);
  1296         -      sqlite3VdbeOp3(v, OP_Le, p1, 0, (void *)p3, P3_COLLSEQ);
         1309  +      pLItem++;
         1310  +      pRight = pLItem->pExpr;
         1311  +      sqlite3ExprCode(pParse, pRight);
         1312  +      codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0);
  1297   1313         sqlite3VdbeAddOp(v, OP_And, 0, 0);
  1298   1314         break;
  1299   1315       }
  1300   1316       case TK_UPLUS:
  1301   1317       case TK_AS: {
  1302   1318         sqlite3ExprCode(pParse, pExpr->pLeft);
  1303   1319         break;
................................................................................
  1304   1320       }
  1305   1321       case TK_CASE: {
  1306   1322         int expr_end_label;
  1307   1323         int jumpInst;
  1308   1324         int addr;
  1309   1325         int nExpr;
  1310   1326         int i;
         1327  +      ExprList *pEList;
         1328  +      struct ExprList_item *aListelem;
  1311   1329   
  1312   1330         assert(pExpr->pList);
  1313   1331         assert((pExpr->pList->nExpr % 2) == 0);
  1314   1332         assert(pExpr->pList->nExpr > 0);
  1315         -      nExpr = pExpr->pList->nExpr;
         1333  +      pEList = pExpr->pList;
         1334  +      aListelem = pEList->a;
         1335  +      nExpr = pEList->nExpr;
  1316   1336         expr_end_label = sqlite3VdbeMakeLabel(v);
  1317   1337         if( pExpr->pLeft ){
  1318   1338           sqlite3ExprCode(pParse, pExpr->pLeft);
  1319   1339         }
  1320   1340         for(i=0; i<nExpr; i=i+2){
  1321         -        sqlite3ExprCode(pParse, pExpr->pList->a[i].pExpr);
         1341  +        sqlite3ExprCode(pParse, aListelem[i].pExpr);
  1322   1342           if( pExpr->pLeft ){
  1323         -          int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[i].pExpr, 1);
  1324         -          CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, 
  1325         -              pExpr->pList->a[i].pExpr);
  1326   1343             sqlite3VdbeAddOp(v, OP_Dup, 1, 1);
  1327         -          jumpInst = sqlite3VdbeOp3(v, OP_Ne, p1, 0, (void *)p3, P3_COLLSEQ);
         1344  +          jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr,
         1345  +                                 OP_Ne, 0, 1);
  1328   1346             sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
  1329   1347           }else{
  1330   1348             jumpInst = sqlite3VdbeAddOp(v, OP_IfNot, 1, 0);
  1331   1349           }
  1332         -        sqlite3ExprCode(pParse, pExpr->pList->a[i+1].pExpr);
         1350  +        sqlite3ExprCode(pParse, aListelem[i+1].pExpr);
  1333   1351           sqlite3VdbeAddOp(v, OP_Goto, 0, expr_end_label);
  1334   1352           addr = sqlite3VdbeCurrentAddr(v);
  1335   1353           sqlite3VdbeChangeP2(v, jumpInst, addr);
  1336   1354         }
  1337   1355         if( pExpr->pLeft ){
  1338   1356           sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
  1339   1357         }
................................................................................
  1432   1450       }
  1433   1451       case TK_LT:
  1434   1452       case TK_LE:
  1435   1453       case TK_GT:
  1436   1454       case TK_GE:
  1437   1455       case TK_NE:
  1438   1456       case TK_EQ: {
  1439         -      int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, jumpIfNull);
  1440         -      CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
  1441   1457         sqlite3ExprCode(pParse, pExpr->pLeft);
  1442   1458         sqlite3ExprCode(pParse, pExpr->pRight);
  1443         -      sqlite3VdbeOp3(v, op, p1, dest, (void *)p3, P3_COLLSEQ);
         1459  +      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
  1444   1460         break;
  1445   1461       }
  1446   1462       case TK_ISNULL:
  1447   1463       case TK_NOTNULL: {
  1448   1464         sqlite3ExprCode(pParse, pExpr->pLeft);
  1449   1465         sqlite3VdbeAddOp(v, op, 1, dest);
  1450   1466         break;
................................................................................
  1453   1469         /* The expression "x BETWEEN y AND z" is implemented as:
  1454   1470         **
  1455   1471         ** 1 IF (x < y) GOTO 3
  1456   1472         ** 2 IF (x <= z) GOTO <dest>
  1457   1473         ** 3 ...
  1458   1474         */
  1459   1475         int addr;
  1460         -      int p1;
  1461         -      CollSeq *p3;
  1462         -      sqlite3ExprCode(pParse, pExpr->pLeft);
         1476  +      Expr *pLeft = pExpr->pLeft;
         1477  +      Expr *pRight = pExpr->pList->a[0].pExpr;
         1478  +      sqlite3ExprCode(pParse, pLeft);
  1463   1479         sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
  1464         -      sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr);
  1465         -      p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, !jumpIfNull);
  1466         -      p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[0].pExpr);
  1467         -      addr = sqlite3VdbeOp3(v, OP_Lt, p1, 0, (void *)p3, P3_COLLSEQ);
         1480  +      sqlite3ExprCode(pParse, pRight);
         1481  +      addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull);
  1468   1482   
  1469         -      sqlite3ExprCode(pParse, pExpr->pList->a[1].pExpr);
  1470         -      p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[1].pExpr, jumpIfNull);
  1471         -      p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[1].pExpr);
  1472         -      sqlite3VdbeOp3(v, OP_Le, p1, dest, (void *)p3, P3_COLLSEQ);
         1483  +      pRight = pExpr->pList->a[1].pExpr;
         1484  +      sqlite3ExprCode(pParse, pRight);
         1485  +      codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull);
  1473   1486   
  1474   1487         sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
  1475   1488         sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v));
  1476   1489         sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
  1477   1490         break;
  1478   1491       }
  1479   1492       default: {
................................................................................
  1526   1539       }
  1527   1540       case TK_LT:
  1528   1541       case TK_LE:
  1529   1542       case TK_GT:
  1530   1543       case TK_GE:
  1531   1544       case TK_NE:
  1532   1545       case TK_EQ: {
  1533         -      int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, jumpIfNull);
  1534         -      CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
  1535   1546         sqlite3ExprCode(pParse, pExpr->pLeft);
  1536   1547         sqlite3ExprCode(pParse, pExpr->pRight);
  1537         -      sqlite3VdbeOp3(v, op, p1, dest, (void *)p3, P3_COLLSEQ);
         1548  +      codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull);
  1538   1549         break;
  1539   1550       }
  1540   1551       case TK_ISNULL:
  1541   1552       case TK_NOTNULL: {
  1542   1553         sqlite3ExprCode(pParse, pExpr->pLeft);
  1543   1554         sqlite3VdbeAddOp(v, op, 1, dest);
  1544   1555         break;
................................................................................
  1547   1558         /* The expression is "x BETWEEN y AND z". It is implemented as:
  1548   1559         **
  1549   1560         ** 1 IF (x >= y) GOTO 3
  1550   1561         ** 2 GOTO <dest>
  1551   1562         ** 3 IF (x > z) GOTO <dest>
  1552   1563         */
  1553   1564         int addr;
  1554         -      int p1;
  1555         -      CollSeq *p3;
  1556         -      sqlite3ExprCode(pParse, pExpr->pLeft);
         1565  +      Expr *pLeft = pExpr->pLeft;
         1566  +      Expr *pRight = pExpr->pList->a[0].pExpr;
         1567  +      sqlite3ExprCode(pParse, pLeft);
  1557   1568         sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
  1558         -      sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr);
         1569  +      sqlite3ExprCode(pParse, pRight);
  1559   1570         addr = sqlite3VdbeCurrentAddr(v);
  1560         -      p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, !jumpIfNull);
  1561         -      p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[0].pExpr);
  1562         -      sqlite3VdbeOp3(v, OP_Ge, p1, addr+3, (void *)p3, P3_COLLSEQ);
         1571  +      codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull);
         1572  +
  1563   1573         sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
  1564   1574         sqlite3VdbeAddOp(v, OP_Goto, 0, dest);
  1565         -      sqlite3ExprCode(pParse, pExpr->pList->a[1].pExpr);
  1566         -      p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[1].pExpr, jumpIfNull);
  1567         -      p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[1].pExpr);
  1568         -      sqlite3VdbeOp3(v, OP_Gt, p1, dest, (void *)p3, P3_COLLSEQ);
         1575  +      pRight = pExpr->pList->a[1].pExpr;
         1576  +      sqlite3ExprCode(pParse, pRight);
         1577  +      codeCompare(pParse, pLeft, pRight, OP_Gt, dest, jumpIfNull);
  1569   1578         break;
  1570   1579       }
  1571   1580       default: {
  1572   1581         sqlite3ExprCode(pParse, pExpr);
  1573   1582         sqlite3VdbeAddOp(v, OP_IfNot, jumpIfNull, dest);
  1574   1583         break;
  1575   1584       }