1
0
mirror of https://github.com/sqlite/sqlite.git synced 2026-01-06 08:01:16 +03:00

Improved rebustness in sqlite3ExprListDup() when it contains a vector assignment

from an UPDATE where the initial term is omitted.  This can happen during a
UNION ALL query flattening while processing a virtual table update in which
the first term of the vector is repeated.
[forum:/forumpost/16ca0e9f32|Forum post 16ca0e9f32].

FossilOrigin-Name: 2547cfe38f8fb35109b3fc5bdfada387fe4b2b8a304156b704ab7f03f1f71198
This commit is contained in:
drh
2021-07-05 02:40:29 +00:00
parent 10f08270e1
commit e46292a920
6 changed files with 39 additions and 24 deletions

View File

@@ -1400,7 +1400,6 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
if( pNew->op==TK_SELECT_COLUMN ){
pNew->pLeft = p->pLeft;
assert( p->iColumn==0 || p->pRight==0 );
assert( p->pRight==0 || p->pRight==p->pLeft
|| ExprHasProperty(p->pLeft, EP_Subquery) );
}else{
@@ -1498,7 +1497,8 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
ExprList *pNew;
struct ExprList_item *pItem, *pOldItem;
int i;
Expr *pPriorSelectCol = 0;
Expr *pPriorSelectColOld = 0;
Expr *pPriorSelectColNew = 0;
assert( db!=0 );
if( p==0 ) return 0;
pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p));
@@ -1515,17 +1515,17 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
&& pOldExpr->op==TK_SELECT_COLUMN
&& (pNewExpr = pItem->pExpr)!=0
){
assert( pNewExpr->iColumn==0 || i>0 );
if( pNewExpr->iColumn==0 ){
assert( pOldExpr->pLeft==pOldExpr->pRight
|| ExprHasProperty(pOldExpr->pLeft, EP_Subquery) );
pPriorSelectCol = pNewExpr->pLeft = pNewExpr->pRight;
if( pNewExpr->pRight ){
pPriorSelectColOld = pOldExpr->pRight;
pPriorSelectColNew = pNewExpr->pRight;
pNewExpr->pLeft = pNewExpr->pRight;
}else{
assert( i>0 );
assert( pItem[-1].pExpr!=0 );
assert( pNewExpr->iColumn==pItem[-1].pExpr->iColumn+1 );
assert( pPriorSelectCol==pItem[-1].pExpr->pLeft );
pNewExpr->pLeft = pPriorSelectCol;
if( pOldExpr->pLeft!=pPriorSelectColOld ){
pPriorSelectColOld = pOldExpr->pLeft;
pPriorSelectColNew = sqlite3ExprDup(db, pPriorSelectColOld, flags);
pNewExpr->pRight = pPriorSelectColNew;
}
pNewExpr->pLeft = pPriorSelectColNew;
}
}
pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName);