From: drh Date: Tue, 3 Jan 2017 15:57:18 +0000 (+0000) Subject: Fix the row-values in UPDATE statements within TRIGGER problem identified X-Git-Tag: version-3.16.1~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=755980ace006e551cf505d1d8352b4bff2b59a3f;p=thirdparty%2Fsqlite.git Fix the row-values in UPDATE statements within TRIGGER problem identified by ticket [8c9458e7]. FossilOrigin-Name: bf984e980c14c9adc54ad010d3a7d199dd53edd6 --- diff --git a/manifest b/manifest index d4ebf16201..5c68d53caa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Version\s3.16.0 -D 2017-01-02T11:57:58.484 +C Fix\sthe\srow-values\sin\sUPDATE\sstatements\swithin\sTRIGGER\sproblem\sidentified\nby\sticket\s[8c9458e7]. +D 2017-01-03T15:57:18.816 F Makefile.in 41bd4cad981487345c4a84081074bcdb876e4b2e F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da @@ -341,7 +341,7 @@ F src/ctime.c 9f2296a4e5d26ebf0e0d95a0af4628f1ea694e7a F src/date.c dc3f1391d9297f8c748132813aaffcb117090d6e F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c c8bc10d145c9666a34ae906250326fdaa8d58fa5 -F src/expr.c 3b662f58b50ba12c004b2d9bd8d3ff5fddbbae7f +F src/expr.c e115097aa866a462051ac8430757638dc1d73f1c F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c d8582ee91975975645f206db332c38f534b783ad @@ -1035,7 +1035,7 @@ F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test 5b7509f384f4f6fae1af3c8c104c8ca299fea18d -F test/rowvalue.test 1701fb786188e9fb7934a7c155bd9cc587d9b677 +F test/rowvalue.test f4a60835c949ec4b8ddc15d78d8a9b412b805875 F test/rowvalue2.test 060d238b7e5639a7c5630cb5e63e311b44efef2b F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 4b556d7de161a0dd8cff095c336e913986398bea @@ -1541,10 +1541,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 2c4d167ccd4be591487f404de9ee629fd484c8bf -R b92eb609c667e98735c96cb1ee09a168 -T +bgcolor * #d0c0ff -T +sym-release * -T +sym-version-3.16.0 * +P 04ac0b75b1716541b2b97704f4809cb7ef19cccf +Q +f12ed3ce0bfb2d94c9baad23fdcbd816c72439a1 +R cf923ffcf348cd32ea5d06c3e1c77d24 +T *branch * branch-3.16 +T *sym-branch-3.16 * +T -sym-trunk * U drh -Z d8ea167822373183dd9b5b971ee1941f +Z 8f14fba7a63b9f6a29946074d4bfc5c2 diff --git a/manifest.uuid b/manifest.uuid index 8830544683..72ec3c2170 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -04ac0b75b1716541b2b97704f4809cb7ef19cccf \ No newline at end of file +bf984e980c14c9adc54ad010d3a7d199dd53edd6 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index b23f17983b..6d4b48fae3 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1088,7 +1088,7 @@ static int dupedExprStructSize(Expr *p, int flags){ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( EXPR_FULLSIZE<=0xfff ); assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); - if( 0==flags ){ + if( 0==flags || p->op==TK_SELECT_COLUMN ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); @@ -1231,6 +1231,8 @@ 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 ); }else{ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); } @@ -1293,6 +1295,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ ExprList *pNew; struct ExprList_item *pItem, *pOldItem; int i; + Expr *pPriorSelectCol = 0; assert( db!=0 ); if( p==0 ) return 0; pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); @@ -1307,7 +1310,24 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ pOldItem = p->a; for(i=0; inExpr; i++, pItem++, pOldItem++){ Expr *pOldExpr = pOldItem->pExpr; + Expr *pNewExpr; pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); + if( pOldExpr + && pOldExpr->op==TK_SELECT_COLUMN + && (pNewExpr = pItem->pExpr)!=0 + ){ + assert( pNewExpr->iColumn==0 || i>0 ); + if( pNewExpr->iColumn==0 ){ + assert( pOldExpr->pLeft==pOldExpr->pRight ); + pPriorSelectCol = 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; + } + } pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); pItem->sortOrder = pOldItem->sortOrder; diff --git a/test/rowvalue.test b/test/rowvalue.test index affc455406..eacfd37ba2 100644 --- a/test/rowvalue.test +++ b/test/rowvalue.test @@ -334,4 +334,25 @@ do_catchsql_test 15.5 { INSERT INTO x1(a,b) VALUES(1,(SELECT * FROM (SELECT 1,2))<3); } {1 {row value misused}} +#------------------------------------------------------------------------- +# Row-values used in UPDATE statements within TRIGGERs +# +# Ticket https://www.sqlite.org/src/info/8c9458e703666e1a +# +do_execsql_test 16.1 { + CREATE TABLE t16a(a,b,c); + INSERT INTO t16a VALUES(1,2,3); + CREATE TABLE t16b(x); + INSERT INTO t16b(x) VALUES(1); + CREATE TRIGGER t16r AFTER UPDATE ON t16b BEGIN + UPDATE t16a SET (a,b,c)=(SELECT new.x,new.x+1,new.x+2); + END; + UPDATE t16b SET x=7; + SELECT * FROM t16a; +} {7 8 9} +do_execsql_test 16.2 { + UPDATE t16b SET x=97; + SELECT * FROM t16a; +} {97 98 99} + finish_test