diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 33 | ||||
-rw-r--r-- | src/expr.c | 119 |
2 files changed, 81 insertions, 71 deletions
diff --git a/src/build.c b/src/build.c index 56a59d4df..1f12a5e16 100644 --- a/src/build.c +++ b/src/build.c @@ -23,7 +23,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.243 2004/07/24 17:38:29 drh Exp $ +** $Id: build.c,v 1.244 2004/07/26 00:31:09 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -1408,17 +1408,17 @@ void sqlite3EndTable(Parse *pParse, Token *pEnd, Select *pSelect){ */ if( db->init.busy && pParse->nErr==0 ){ Table *pOld; - FKey *pFKey; - pOld = sqlite3HashInsert(&db->aDb[p->iDb].tblHash, - p->zName, strlen(p->zName)+1, p); + FKey *pFKey; + Db *pDb = &db->aDb[p->iDb]; + pOld = sqlite3HashInsert(&pDb->tblHash, p->zName, strlen(p->zName)+1, p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ return; } for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){ int nTo = strlen(pFKey->zTo) + 1; - pFKey->pNextTo = sqlite3HashFind(&db->aDb[p->iDb].aFKey, pFKey->zTo, nTo); - sqlite3HashInsert(&db->aDb[p->iDb].aFKey, pFKey->zTo, nTo, pFKey); + pFKey->pNextTo = sqlite3HashFind(&pDb->aFKey, pFKey->zTo, nTo); + sqlite3HashInsert(&pDb->aFKey, pFKey->zTo, nTo, pFKey); } pParse->pNewTable = 0; db->nTable++; @@ -2403,17 +2403,18 @@ int sqlite3IdListIndex(IdList *pList, const char *zName){ */ void sqlite3SrcListDelete(SrcList *pList){ int i; + struct SrcList_item *pItem; if( pList==0 ) return; - for(i=0; i<pList->nSrc; i++){ - sqliteFree(pList->a[i].zDatabase); - sqliteFree(pList->a[i].zName); - sqliteFree(pList->a[i].zAlias); - if( pList->a[i].pTab && pList->a[i].pTab->isTransient ){ - sqlite3DeleteTable(0, pList->a[i].pTab); - } - sqlite3SelectDelete(pList->a[i].pSelect); - sqlite3ExprDelete(pList->a[i].pOn); - sqlite3IdListDelete(pList->a[i].pUsing); + for(pItem=pList->a, i=0; i<pList->nSrc; i++, pItem++){ + sqliteFree(pItem->zDatabase); + sqliteFree(pItem->zName); + sqliteFree(pItem->zAlias); + if( pItem->pTab && pItem->pTab->isTransient ){ + sqlite3DeleteTable(0, pItem->pTab); + } + sqlite3SelectDelete(pItem->pSelect); + sqlite3ExprDelete(pItem->pOn); + sqlite3IdListDelete(pItem->pUsing); } sqliteFree(pList); } diff --git a/src/expr.c b/src/expr.c index b7f612af2..f29d2bfd2 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.152 2004/07/21 02:53:30 drh Exp $ +** $Id: expr.c,v 1.153 2004/07/26 00:31:09 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -172,6 +172,22 @@ static CollSeq* binaryCompareCollSeq(Parse *pParse, Expr *pLeft, Expr *pRight){ } /* +** Generate code for a comparison operator. +*/ +static int codeCompare( + Parse *pParse, /* The parsing (and code generating) context */ + Expr *pLeft, /* The left operand */ + Expr *pRight, /* The right operand */ + int opcode, /* The comparison opcode */ + int dest, /* Jump here if true. */ + int jumpIfNull /* If true, jump if either operand is NULL */ +){ + int p1 = binaryCompareP1(pLeft, pRight, jumpIfNull); + CollSeq *p3 = binaryCompareCollSeq(pParse, pLeft, pRight); + return sqlite3VdbeOp3(pParse->pVdbe, opcode, p1, dest, (void *)p3, P3_COLLSEQ); +} + +/* ** Construct a new expression node and return a pointer to it. Memory ** for this node is obtained from sqliteMalloc(). The calling function ** is responsible for making sure the node eventually gets freed. @@ -433,12 +449,13 @@ ExprList *sqlite3ExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){ */ void sqlite3ExprListDelete(ExprList *pList){ int i; + struct ExprList_item *pItem; if( pList==0 ) return; assert( pList->a!=0 || (pList->nExpr==0 && pList->nAlloc==0) ); assert( pList->nExpr<=pList->nAlloc ); - for(i=0; i<pList->nExpr; i++){ - sqlite3ExprDelete(pList->a[i].pExpr); - sqliteFree(pList->a[i].zName); + for(pItem=pList->a, i=0; i<pList->nExpr; i++, pItem++){ + sqlite3ExprDelete(pItem->pExpr); + sqliteFree(pItem->zName); } sqliteFree(pList->a); sqliteFree(pList); @@ -860,11 +877,13 @@ int sqlite3ExprResolveIds( ** table allocated and opened above. */ int iParm = pExpr->iTable + (((int)affinity)<<16); + ExprList *pEList; assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0); - if( pExpr->pSelect->pEList && pExpr->pSelect->pEList->nExpr>0 ){ + pEList = pExpr->pSelect->pEList; + if( pEList && pEList->nExpr>0 ){ keyInfo.aColl[0] = binaryCompareCollSeq(pParse, pExpr->pLeft, - pExpr->pSelect->pEList->a[0].pExpr); + pEList->a[0].pExpr); } }else if( pExpr->pList ){ /* Case 2: expr IN (exprlist) @@ -1152,11 +1171,9 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ case TK_GE: case TK_NE: case TK_EQ: { - int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, 0); - CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); - sqlite3VdbeOp3(v, op, p1, 0, (void *)p3, P3_COLLSEQ); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, 0, 0); break; } case TK_AND: @@ -1281,19 +1298,18 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ break; } case TK_BETWEEN: { - int p1; - CollSeq *p3; - sqlite3ExprCode(pParse, pExpr->pLeft); + Expr *pLeft = pExpr->pLeft; + struct ExprList_item *pLItem = pExpr->pList->a; + Expr *pRight = pLItem->pExpr; + sqlite3ExprCode(pParse, pLeft); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr); - p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, 0); - p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[0].pExpr); - sqlite3VdbeOp3(v, OP_Ge, p1, 0, (void *)p3, P3_COLLSEQ); + sqlite3ExprCode(pParse, pRight); + codeCompare(pParse, pLeft, pRight, OP_Ge, 0, 0); sqlite3VdbeAddOp(v, OP_Pull, 1, 0); - sqlite3ExprCode(pParse, pExpr->pList->a[1].pExpr); - p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[1].pExpr, 0); - p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[1].pExpr); - sqlite3VdbeOp3(v, OP_Le, p1, 0, (void *)p3, P3_COLLSEQ); + pLItem++; + pRight = pLItem->pExpr; + sqlite3ExprCode(pParse, pRight); + codeCompare(pParse, pLeft, pRight, OP_Le, 0, 0); sqlite3VdbeAddOp(v, OP_And, 0, 0); break; } @@ -1308,28 +1324,30 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){ int addr; int nExpr; int i; + ExprList *pEList; + struct ExprList_item *aListelem; assert(pExpr->pList); assert((pExpr->pList->nExpr % 2) == 0); assert(pExpr->pList->nExpr > 0); - nExpr = pExpr->pList->nExpr; + pEList = pExpr->pList; + aListelem = pEList->a; + nExpr = pEList->nExpr; expr_end_label = sqlite3VdbeMakeLabel(v); if( pExpr->pLeft ){ sqlite3ExprCode(pParse, pExpr->pLeft); } for(i=0; i<nExpr; i=i+2){ - sqlite3ExprCode(pParse, pExpr->pList->a[i].pExpr); + sqlite3ExprCode(pParse, aListelem[i].pExpr); if( pExpr->pLeft ){ - int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[i].pExpr, 1); - CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, - pExpr->pList->a[i].pExpr); sqlite3VdbeAddOp(v, OP_Dup, 1, 1); - jumpInst = sqlite3VdbeOp3(v, OP_Ne, p1, 0, (void *)p3, P3_COLLSEQ); + jumpInst = codeCompare(pParse, pExpr->pLeft, aListelem[i].pExpr, + OP_Ne, 0, 1); sqlite3VdbeAddOp(v, OP_Pop, 1, 0); }else{ jumpInst = sqlite3VdbeAddOp(v, OP_IfNot, 1, 0); } - sqlite3ExprCode(pParse, pExpr->pList->a[i+1].pExpr); + sqlite3ExprCode(pParse, aListelem[i+1].pExpr); sqlite3VdbeAddOp(v, OP_Goto, 0, expr_end_label); addr = sqlite3VdbeCurrentAddr(v); sqlite3VdbeChangeP2(v, jumpInst, addr); @@ -1436,11 +1454,9 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { - int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, jumpIfNull); - CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); - sqlite3VdbeOp3(v, op, p1, dest, (void *)p3, P3_COLLSEQ); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull); break; } case TK_ISNULL: @@ -1457,19 +1473,16 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ ** 3 ... */ int addr; - int p1; - CollSeq *p3; - sqlite3ExprCode(pParse, pExpr->pLeft); + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pList->a[0].pExpr; + sqlite3ExprCode(pParse, pLeft); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr); - p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, !jumpIfNull); - p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[0].pExpr); - addr = sqlite3VdbeOp3(v, OP_Lt, p1, 0, (void *)p3, P3_COLLSEQ); + sqlite3ExprCode(pParse, pRight); + addr = codeCompare(pParse, pLeft, pRight, OP_Lt, 0, !jumpIfNull); - sqlite3ExprCode(pParse, pExpr->pList->a[1].pExpr); - p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[1].pExpr, jumpIfNull); - p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[1].pExpr); - sqlite3VdbeOp3(v, OP_Le, p1, dest, (void *)p3, P3_COLLSEQ); + pRight = pExpr->pList->a[1].pExpr; + sqlite3ExprCode(pParse, pRight); + codeCompare(pParse, pLeft, pRight, OP_Le, dest, jumpIfNull); sqlite3VdbeAddOp(v, OP_Integer, 0, 0); sqlite3VdbeChangeP2(v, addr, sqlite3VdbeCurrentAddr(v)); @@ -1530,11 +1543,9 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ case TK_GE: case TK_NE: case TK_EQ: { - int p1 = binaryCompareP1(pExpr->pLeft, pExpr->pRight, jumpIfNull); - CollSeq *p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight); sqlite3ExprCode(pParse, pExpr->pLeft); sqlite3ExprCode(pParse, pExpr->pRight); - sqlite3VdbeOp3(v, op, p1, dest, (void *)p3, P3_COLLSEQ); + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, dest, jumpIfNull); break; } case TK_ISNULL: @@ -1551,21 +1562,19 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ ** 3 IF (x > z) GOTO <dest> */ int addr; - int p1; - CollSeq *p3; - sqlite3ExprCode(pParse, pExpr->pLeft); + Expr *pLeft = pExpr->pLeft; + Expr *pRight = pExpr->pList->a[0].pExpr; + sqlite3ExprCode(pParse, pLeft); sqlite3VdbeAddOp(v, OP_Dup, 0, 0); - sqlite3ExprCode(pParse, pExpr->pList->a[0].pExpr); + sqlite3ExprCode(pParse, pRight); addr = sqlite3VdbeCurrentAddr(v); - p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[0].pExpr, !jumpIfNull); - p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[0].pExpr); - sqlite3VdbeOp3(v, OP_Ge, p1, addr+3, (void *)p3, P3_COLLSEQ); + codeCompare(pParse, pLeft, pRight, OP_Ge, addr+3, !jumpIfNull); + sqlite3VdbeAddOp(v, OP_Pop, 1, 0); sqlite3VdbeAddOp(v, OP_Goto, 0, dest); - sqlite3ExprCode(pParse, pExpr->pList->a[1].pExpr); - p1 = binaryCompareP1(pExpr->pLeft, pExpr->pList->a[1].pExpr, jumpIfNull); - p3 = binaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pList->a[1].pExpr); - sqlite3VdbeOp3(v, OP_Gt, p1, dest, (void *)p3, P3_COLLSEQ); + pRight = pExpr->pList->a[1].pExpr; + sqlite3ExprCode(pParse, pRight); + codeCompare(pParse, pLeft, pRight, OP_Gt, dest, jumpIfNull); break; } default: { |