mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Fix problems with UPDATE...FROM statements that modify rowid or primary-key values.
FossilOrigin-Name: 623ab585d1aa1bdde2df17f1936aa4eec2d997b274acc5c7b291d9566a9ec2c5
This commit is contained in:
14
manifest
14
manifest
@@ -1,5 +1,5 @@
|
||||
C Add\sOOM\stests\sfor\sthe\snew\scode\son\sthis\sbranch.
|
||||
D 2020-04-30T18:28:40.716
|
||||
C Fix\sproblems\swith\sUPDATE...FROM\sstatements\sthat\smodify\srowid\sor\sprimary-key\svalues.
|
||||
D 2020-05-01T18:43:49.018
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@@ -599,7 +599,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
||||
F src/tokenize.c eee7bae3ec0bc4abee951554bf46a8ba567c0f7752ac90c820ed8afff4c612dc
|
||||
F src/treeview.c 82c6391a3ba76215d4185fd4719a56ec4caf186a40c8a7b6e6ba4ae4467c2742
|
||||
F src/trigger.c 4ada1037cc99777f647a882cdacbd1a4deb6567b69daf02946286401b88cdc04
|
||||
F src/update.c 2f63f9e13c34e4f9fc238e769d8879697d905e542d2e6f9a7a68ea1a5289c631
|
||||
F src/update.c 9777ad958b979488ed2e04a7d226048179078916e32437bd633eb4cae191f1a9
|
||||
F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
|
||||
F src/utf.c 95fb6e03a5ca679045c5adccd05380f0addccabef5911abddcb06af069500ab7
|
||||
F src/util.c 3b6cedf7a0c69bd6e1acce832873952d416212d6293b18d03064e07d7a9b5118
|
||||
@@ -1618,7 +1618,7 @@ F test/update.test e906ca7cb1dc6f52af1ea243e08f727edfa79f924c2691f2f9e72481f8473
|
||||
F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3
|
||||
F test/upfrom1.tcl 62efddee869b3a6f3e076b2816793fec9422e38d10ea42b63da733cdd2b1ad8e
|
||||
F test/upfrom1.test 543389b4eef43c7a21079df018cf95e29d7c2a4efd09b2597e54a03bbdbd30b9
|
||||
F test/upfrom2.test 1dded7ed03e8b335b7ac38f9d70b60380df9049ea13076832ab86fd5b78b4926
|
||||
F test/upfrom2.test 79f2d3e4df214010011afdd588ce35410ea1416e0f87aadb48618864347f90a5
|
||||
F test/upfromfault.test 1e68cc570695a0f8cd16ce09c14210fc43928c7b47b3eda38a99abb0b80c9a65
|
||||
F test/upsert1.test 88f9e258c6a0eeeb85937b08831e8daad440ba41f125af48439e9d33f266fb18
|
||||
F test/upsert2.test 9c3cdbb1a890227f6504ce4b0e3de68f4cdfa16bb21d8641208a9239896c5a09
|
||||
@@ -1866,7 +1866,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P ffcdb6689123bb871c9bd8f977197f86f37c42e9094e2d4bb187ff479f74cf65
|
||||
R 9834e1157ceceff37925bd1917b38659
|
||||
P e4a18601e5093896e5b323c21aec986b07259353d2ef9455d0a81c6846f40282
|
||||
R 31d44a5c5eab4f547b6c4029493d0d87
|
||||
U dan
|
||||
Z 98f1c8c70109f9d7189dd668536b4270
|
||||
Z 8413be68bb1b4ef61cb95011e58e4ac0
|
||||
|
@@ -1 +1 @@
|
||||
e4a18601e5093896e5b323c21aec986b07259353d2ef9455d0a81c6846f40282
|
||||
623ab585d1aa1bdde2df17f1936aa4eec2d997b274acc5c7b291d9566a9ec2c5
|
20
src/update.c
20
src/update.c
@@ -285,6 +285,7 @@ void sqlite3Update(
|
||||
u8 chngRowid; /* Rowid changed in a normal table */
|
||||
u8 chngKey; /* Either chngPk or chngRowid */
|
||||
Expr *pRowidExpr = 0; /* Expression defining the new record number */
|
||||
int iRowidExpr = -1;
|
||||
AuthContext sContext; /* The authorization context */
|
||||
NameContext sNC; /* The name-context to resolve expressions in */
|
||||
int iDb; /* Database containing the table being updated */
|
||||
@@ -430,6 +431,7 @@ void sqlite3Update(
|
||||
if( j==pTab->iPKey ){
|
||||
chngRowid = 1;
|
||||
pRowidExpr = pChanges->a[i].pExpr;
|
||||
iRowidExpr = i;
|
||||
}else if( pPk && (pTab->aCol[j].colFlags & COLFLAG_PRIMKEY)!=0 ){
|
||||
chngPk = 1;
|
||||
}
|
||||
@@ -452,6 +454,7 @@ void sqlite3Update(
|
||||
j = -1;
|
||||
chngRowid = 1;
|
||||
pRowidExpr = pChanges->a[i].pExpr;
|
||||
iRowidExpr = i;
|
||||
}else{
|
||||
sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zEName);
|
||||
pParse->checkSchema = 1;
|
||||
@@ -649,6 +652,8 @@ void sqlite3Update(
|
||||
if( nChangeFrom ){
|
||||
sqlite3MultiWrite(pParse);
|
||||
eOnePass = ONEPASS_OFF;
|
||||
nKey = nPk;
|
||||
regKey = iPk;
|
||||
}else{
|
||||
if( pUpsert ){
|
||||
/* If this is an UPSERT, then all cursors have already been opened by
|
||||
@@ -810,7 +815,12 @@ void sqlite3Update(
|
||||
** already populated. */
|
||||
assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid );
|
||||
if( chngRowid ){
|
||||
assert( iRowidExpr>=0 );
|
||||
if( nChangeFrom==0 ){
|
||||
sqlite3ExprCode(pParse, pRowidExpr, regNewRowid);
|
||||
}else{
|
||||
sqlite3VdbeAddOp3(v, OP_Column, iEph, iRowidExpr, regNewRowid);
|
||||
}
|
||||
sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v);
|
||||
}
|
||||
|
||||
@@ -909,15 +919,7 @@ void sqlite3Update(
|
||||
** documentation.
|
||||
*/
|
||||
if( pPk ){
|
||||
int p3, p4;
|
||||
if( nChangeFrom ){
|
||||
p3 = iPk;
|
||||
p4 = nPk;
|
||||
}else{
|
||||
p3 = regKey;
|
||||
p4 = nKey;
|
||||
}
|
||||
sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, p3, p4);
|
||||
sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey);
|
||||
VdbeCoverage(v);
|
||||
}else{
|
||||
sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid);
|
||||
|
@@ -315,5 +315,36 @@ do_execsql_test 3.1 {
|
||||
UPDATE t1 SET z=v FROM input WHERE x=k;
|
||||
}
|
||||
|
||||
foreach {tn sql} {
|
||||
2 {
|
||||
CREATE TABLE x1(a INT PRIMARY KEY, b, c) WITHOUT ROWID;
|
||||
}
|
||||
1 {
|
||||
CREATE TABLE x1(a INTEGER PRIMARY KEY, b, c);
|
||||
}
|
||||
3 {
|
||||
CREATE TABLE x1(a INT PRIMARY KEY, b, c);
|
||||
}
|
||||
} {
|
||||
|
||||
reset_db
|
||||
execsql $sql
|
||||
|
||||
do_execsql_test 4.$tn.0 {
|
||||
INSERT INTO x1 VALUES(1, 1, 1);
|
||||
INSERT INTO x1 VALUES(2, 2, 2);
|
||||
INSERT INTO x1 VALUES(3, 3, 3);
|
||||
INSERT INTO x1 VALUES(4, 4, 4);
|
||||
INSERT INTO x1 VALUES(5, 5, 5);
|
||||
CREATE TABLE map(o, t);
|
||||
INSERT INTO map VALUES(3, 30), (4, 40), (1, 10);
|
||||
}
|
||||
|
||||
do_execsql_test 4.$tn.1 {
|
||||
UPDATE x1 SET a=t FROM map WHERE a=o;
|
||||
SELECT * FROM x1 ORDER BY a;
|
||||
} {2 2 2 5 5 5 10 1 1 30 3 3 40 4 4}
|
||||
}
|
||||
|
||||
finish_test
|
||||
|
||||
|
Reference in New Issue
Block a user