diff options
Diffstat (limited to 'src/expr.c')
-rw-r--r-- | src/expr.c | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/src/expr.c b/src/expr.c index f5916c53e..eb3ba35ba 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1698,22 +1698,16 @@ IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){ int i; assert( db!=0 ); if( p==0 ) return 0; - pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); + assert( p->eU4!=EU4_EXPR ); + pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) ); if( pNew==0 ) return 0; pNew->nId = p->nId; - pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) ); - if( pNew->a==0 ){ - sqlite3DbFreeNN(db, pNew); - return 0; - } - /* Note that because the size of the allocation for p->a[] is not - ** necessarily a power of two, sqlite3IdListAppend() may not be called - ** on the duplicate created by this function. */ + pNew->eU4 = p->eU4; for(i=0; i<p->nId; i++){ struct IdList_item *pNewItem = &pNew->a[i]; - struct IdList_item *pOldItem = &p->a[i]; + const struct IdList_item *pOldItem = &p->a[i]; pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); - pNewItem->idx = pOldItem->idx; + pNewItem->u4 = pOldItem->u4; } return pNew; } @@ -2179,7 +2173,7 @@ Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ /* If pWalker->eCode is 2 then any term of the expression that comes from - ** the ON or USING clauses of a left join disqualifies the expression + ** the ON or USING clauses of an outer join disqualifies the expression ** from being considered constant. */ if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){ pWalker->eCode = 0; @@ -3181,9 +3175,9 @@ void sqlite3CodeRhsOfIN( assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); - sqlite3VdbeAddOp2(v, OP_Return, pExpr->y.sub.regReturn, - pExpr->y.sub.iAddr); - sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); + sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr, 1); + VdbeCoverage(v); sqlite3ClearTempRegCache(pParse); } } @@ -3312,9 +3306,9 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); - sqlite3VdbeAddOp2(v, OP_Return, pExpr->y.sub.regReturn, - pExpr->y.sub.iAddr); - sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); + sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr, 1); + VdbeCoverage(v); sqlite3ClearTempRegCache(pParse); return rReg; } @@ -4501,16 +4495,18 @@ expr_code_doover: } case TK_SELECT_COLUMN: { int n; - if( pExpr->pLeft->iTable==0 ){ - pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft); + Expr *pLeft = pExpr->pLeft; + if( pLeft->iTable==0 || pParse->withinRJSubrtn > pLeft->op2 ){ + pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft); + pLeft->op2 = pParse->withinRJSubrtn; } - assert( pExpr->pLeft->op==TK_SELECT || pExpr->pLeft->op==TK_ERROR ); - n = sqlite3ExprVectorSize(pExpr->pLeft); + assert( pLeft->op==TK_SELECT || pLeft->op==TK_ERROR ); + n = sqlite3ExprVectorSize(pLeft); if( pExpr->iTable!=n ){ sqlite3ErrorMsg(pParse, "%d columns assigned %d values", pExpr->iTable, n); } - return pExpr->pLeft->iTable + pExpr->iColumn; + return pLeft->iTable + pExpr->iColumn; } case TK_IN: { int destIfFalse = sqlite3VdbeMakeLabel(pParse); @@ -5818,7 +5814,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ ** in an incorrect answer. ** ** Terms of p that are marked with EP_FromJoin (and hence that come from -** the ON or USING clauses of LEFT JOINS) are excluded from the analysis. +** the ON or USING clauses of OUTER JOINS) are excluded from the analysis. ** ** This routine is used to check if a LEFT JOIN can be converted into ** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE |