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: | 1186e3ce0b660f1cf8d03a275b0331da |
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
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 ................................................................................ 1404 1404 sqlite3EndWriteOperation(pParse); 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 - FKey *pFKey; 1412 - pOld = sqlite3HashInsert(&db->aDb[p->iDb].tblHash, 1413 - p->zName, strlen(p->zName)+1, p); 1411 + FKey *pFKey; 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 }