1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-11 01:42:22 +03:00

Make it an error to repeat the target object/alias of an UPDATE statement in its FROM clause.

FossilOrigin-Name: d90a37e930c66afe95165955ae47efde08f52c8ce16c4fb239da0233335db050
This commit is contained in:
dan
2020-07-17 16:31:37 +00:00
parent 7e1d9512af
commit 07ca7d610b
9 changed files with 72 additions and 15 deletions

View File

@@ -1,6 +1,6 @@
B 7a876209a678a34c198b54ceef9e3c041f128a14dc73357f6a57cadadaa6cf7b B 7a876209a678a34c198b54ceef9e3c041f128a14dc73357f6a57cadadaa6cf7b
C Add\sa\scouple\sof\s"#ifdef\sSQLITE_ENABLE_UPDATE_DELETE_LIMIT"\sblocks\smissing\sfrom\snew\scode\son\sthis\sbranch. C Make\sit\san\serror\sto\srepeat\sthe\starget\sobject/alias\sof\san\sUPDATE\sstatement\sin\sits\sFROM\sclause.
D 2020-07-17T15:34:54.434 D 2020-07-17T16:31:37.428
F Makefile.in 19374a5db06c3199ec1bab71ab74a103d8abf21053c05e9389255dc58083f806 F Makefile.in 19374a5db06c3199ec1bab71ab74a103d8abf21053c05e9389255dc58083f806
F Makefile.msc 48f5a3fc32672c09ad73795749f6253e406a31526935fbbffd8f021108d54574 F Makefile.msc 48f5a3fc32672c09ad73795749f6253e406a31526935fbbffd8f021108d54574
F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8 F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8
@@ -27,13 +27,13 @@ F src/parse.y ecb9abdd79ec86c8dca7cb126bbdcf322c0e282f87a6d0d734ea5f2c57ced516
F src/pragma.c ae499b5ab8f4e833f67e28bf2322500e9aa612aadf12581d1324333f848d8b51 F src/pragma.c ae499b5ab8f4e833f67e28bf2322500e9aa612aadf12581d1324333f848d8b51
F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf
F src/resolve.c 2dd6821aac2cd27de9fcf6aa6d1f8c41b4b5841c9bc58bf1c9109008009a3a2e F src/resolve.c 2dd6821aac2cd27de9fcf6aa6d1f8c41b4b5841c9bc58bf1c9109008009a3a2e
F src/select.c a48570f614f777d02dd7f419789944225432a9231b2dbca863411ac19e5fb683 F src/select.c d338c9b9e11241b66ef860b6078969d7544ad1351842db693955ae025291c38c
F src/shell.c.in 81fa23ac1a3d6ac9ed13e9ae711a3d8806396ca7cc12c5d6a2e2536f70b0c7ad F src/shell.c.in 81fa23ac1a3d6ac9ed13e9ae711a3d8806396ca7cc12c5d6a2e2536f70b0c7ad
F src/sqliteInt.h e2684c4ba7ee9c0a0529ae2eb847cc5bf923e4104a9d0944bf3d9d151856b6ab F src/sqliteInt.h 9682c3ce6b970b3a997d65c140bdb5b286a04188e4e1c8489b64a525161ecb30
F src/test1.c fe56c4bcaa2685ca9aa25d817a0ee9345e189aff4a5a71a3d8ba946c7776feb8 F src/test1.c fe56c4bcaa2685ca9aa25d817a0ee9345e189aff4a5a71a3d8ba946c7776feb8
F src/test_malloc.c 21121ea85b49ec0bdb69995847cef9036ef9beca3ce63bbb776e4ea2ecc44b97 F src/test_malloc.c 21121ea85b49ec0bdb69995847cef9036ef9beca3ce63bbb776e4ea2ecc44b97
F src/trigger.c ef67bde309a831515dc3c2173d792574309f2f42d45f8c078743fae9f7f98c75 F src/trigger.c ef67bde309a831515dc3c2173d792574309f2f42d45f8c078743fae9f7f98c75
F src/update.c 21cb7bd83ee895cce68811c99dae0fcf62575d8b9d48ba69b52c2c9495dfbd31 F src/update.c a3b2d50dc23e57c01054741cd09c1564cf5dd7df68b07d2d2b14e0c86cd12ad7
F src/util.c c0bacc165f46169d2b720c37c8719165e383211698fad1de39dd16a8c161815a F src/util.c c0bacc165f46169d2b720c37c8719165e383211698fad1de39dd16a8c161815a
F src/vdbe.c 981666c49d33039df6dc9fccd40191575586ac4866255b2f57819cc5eb99f572 F src/vdbe.c 981666c49d33039df6dc9fccd40191575586ac4866255b2f57819cc5eb99f572
F src/vdbeapi.c c1a9004ac554d8d48794d2ce5f80397f8e419fd28643a543cc1e004c7713c3ef F src/vdbeapi.c c1a9004ac554d8d48794d2ce5f80397f8e419fd28643a543cc1e004c7713c3ef
@@ -55,10 +55,10 @@ F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b76
F test/speedtest1.c a8b5afe72d78ff365012aba48d3f0c579e957facb7630f765f58a6ae4656d20d F test/speedtest1.c a8b5afe72d78ff365012aba48d3f0c579e957facb7630f765f58a6ae4656d20d
F test/tester.tcl 174f668fcb4569a775bf24534ac8e59ce47d3a56d37c3465d1857f027e7ec136 F test/tester.tcl 174f668fcb4569a775bf24534ac8e59ce47d3a56d37c3465d1857f027e7ec136
F test/triggerupfrom.test d25961fa70a99b6736193da7b49a36d8c1d28d56188f0be6406d4366315cd6e4 F test/triggerupfrom.test d25961fa70a99b6736193da7b49a36d8c1d28d56188f0be6406d4366315cd6e4
F test/upfrom1.tcl df984cb88010af1555812af55e9db44c4df50677395b45d1f30b69b1b6c07b73 F test/upfrom1.tcl 8859d9d437f03b44174c4524a7a734a391fd4526fcff65be08285dafc9dc9041
F test/upfrom1.test 2ba1ed45b4a2161fc79f234b9ce4300b0d3deba545e3f23b938fb3ebdbf8758d F test/upfrom1.test c0a99a3f44b42beaca37c62e05332d64768c326c75b4edf976533a2d1ef76895
F test/upfrom2.test 79f2d3e4df214010011afdd588ce35410ea1416e0f87aadb48618864347f90a5 F test/upfrom2.test 6ebd3be8c3fac984e89a177d823686f04605b512fc167392bce6d8ba2ba63325
F test/upfrom3.test f47fe3249927af1f912610840597948817f89d8d9d903f4b0a0857b062492758 F test/upfrom3.test 7dab379d128e8dd7beb2055b295fb113c7ba93e8c2038f5ddb7a4a10f0ebb348
F test/upfromfault.test 70ecf8eb85559727a487283f69374e3ae39879e994d8a2437c49d7c05ecb70c9 F test/upfromfault.test 70ecf8eb85559727a487283f69374e3ae39879e994d8a2437c49d7c05ecb70c9
F test/window1.test e52b81fff0c3cb122a1240f336688eb81bea2967a99c4ddb78969adec7aadc2a F test/window1.test e52b81fff0c3cb122a1240f336688eb81bea2967a99c4ddb78969adec7aadc2a
F tool/lemon.c 600a58b9d1b8ec5419373982428e927ca208826edacb91ca42ab94514d006039 F tool/lemon.c 600a58b9d1b8ec5419373982428e927ca208826edacb91ca42ab94514d006039
@@ -68,7 +68,7 @@ F tool/mksqlite3c.tcl f4ef476510eca4124c874a72029f1e01bc54a896b1724e8f9eef0d8bfa
F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78fc4edf F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78fc4edf
F tool/showlocks.c 9cc5e66d4ebbf2d194f39db2527ece92077e86ae627ddd233ee48e16e8142564 F tool/showlocks.c 9cc5e66d4ebbf2d194f39db2527ece92077e86ae627ddd233ee48e16e8142564
F tool/speed-check.sh 615cbdf50f1409ef3bbf9f682e396df80f49d97ed93ed3e61c8e91fae6afde58 F tool/speed-check.sh 615cbdf50f1409ef3bbf9f682e396df80f49d97ed93ed3e61c8e91fae6afde58
P e3c423cb1407c06a3806ae6304e4713c37cd446f4cc399731884e3d009938e57 P cc471df04aecf344d0aa47138014c07d3f93462ae1f8ff86ec5589cfb62c658d
R d2ce899840893b7cd528048345c54e26 R 274a85f0083714cabb990ec4c59ecfbf
U dan U dan
Z 07c0b529dfa24232d5016aa5a9d718ca Z e7675c1aa508a9471dfb9044614d1d8c

View File

@@ -1 +1 @@
cc471df04aecf344d0aa47138014c07d3f93462ae1f8ff86ec5589cfb62c658d d90a37e930c66afe95165955ae47efde08f52c8ce16c4fb239da0233335db050

View File

@@ -5823,6 +5823,24 @@ int sqlite3Select(
} }
#endif #endif
/* If the SF_UpdateFrom flag is set, then this function is being called
** as part of populating the temp table for an UPDATE...FROM statement.
** In this case, it is an error if the target object (pSrc->a[0]) name
** or alias is duplicated within FROM clause (pSrc->a[1..n]). */
if( p->selFlags & SF_UpdateFrom ){
struct SrcList_item *p0 = &p->pSrc->a[0];
for(i=1; i<p->pSrc->nSrc; i++){
struct SrcList_item *p1 = &p->pSrc->a[i];
if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
sqlite3ErrorMsg(pParse,
"target object/alias may not appear in FROM clause: %s",
p0->zAlias ? p0->zAlias : p0->pTab->zName
);
goto select_end;
}
}
}
if( pDest->eDest==SRT_Output ){ if( pDest->eDest==SRT_Output ){
generateColumnNames(pParse, p); generateColumnNames(pParse, p);
} }

View File

@@ -3126,6 +3126,7 @@ struct Select {
#define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */ #define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */
#define SF_View 0x0200000 /* SELECT statement is a view */ #define SF_View 0x0200000 /* SELECT statement is a view */
#define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ #define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */
#define SF_UpdateFrom 0x0800000 /* Statement is an UPDATE...FROM */
/* /*
** The results of a SELECT can be distributed in several ways, as defined ** The results of a SELECT can be distributed in several ways, as defined

View File

@@ -255,7 +255,7 @@ static void updateFromSelect(
} }
} }
pSelect = sqlite3SelectNew(pParse, pList, pSelect = sqlite3SelectNew(pParse, pList,
pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_IncludeHidden, pLimit2 pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_UpdateFrom|SF_IncludeHidden, pLimit2
); );
sqlite3SelectDestInit(&dest, eDest, iEph); sqlite3SelectDestInit(&dest, eDest, iEph);
dest.iSDParm2 = (pPk ? pPk->nKeyCol : -1); dest.iSDParm2 = (pPk ? pPk->nKeyCol : -1);

View File

@@ -103,6 +103,13 @@ execsql_test 2.2 {
SELECT * FROM t5 ORDER BY a; SELECT * FROM t5 ORDER BY a;
} }
errorsql_test 2.3.1 {
UPDATE t5 SET b=1 FROM t5;
}
errorsql_test 2.3.2 {
UPDATE t5 AS apples SET b=1 FROM t5 AS apples;
}
finish_test finish_test

View File

@@ -154,4 +154,14 @@ do_execsql_test 2.2 {
SELECT * FROM t5 ORDER BY a; SELECT * FROM t5 ORDER BY a;
} {1 i I 2 ii {} 3 iii II 4 four FOUR} } {1 i I 2 ii {} 3 iii II 4 four FOUR}
# PG says ERROR: table name "t5" specified more than once
do_test 2.3.1 { catch { execsql {
UPDATE t5 SET b=1 FROM t5;
} } } 1
# PG says ERROR: table name "apples" specified more than once
do_test 2.3.2 { catch { execsql {
UPDATE t5 AS apples SET b=1 FROM t5 AS apples;
} } } 1
finish_test finish_test

View File

@@ -23,6 +23,9 @@ set testprefix upfrom2
# #
# 2.*: Test adding ORDER BY and LIMIT clauses with UPDATE FROM statements. # 2.*: Test adding ORDER BY and LIMIT clauses with UPDATE FROM statements.
# #
# 5.*: Test that specifying the target table name or alias in the FROM
# clause of an UPDATE statement is an error.
#
foreach {tn wo} { foreach {tn wo} {
1 "" 1 ""
@@ -346,5 +349,23 @@ foreach {tn sql} {
} {2 2 2 5 5 5 10 1 1 30 3 3 40 4 4} } {2 2 2 5 5 5 10 1 1 30 3 3 40 4 4}
} }
reset_db
do_execsql_test 5.0 {
CREATE TABLE x1(a, b, c);
CREATE TABLE x2(a, b, c);
}
foreach {tn update nm} {
1 "UPDATE x1 SET a=5 FROM x1" x1
2 "UPDATE x1 AS grapes SET a=5 FROM x1 AS grapes" grapes
3 "UPDATE x1 SET a=5 FROM x2, x1" x1
4 "UPDATE x1 AS grapes SET a=5 FROM x2, x1 AS grapes" grapes
} {
do_catchsql_test 5.$tn $update \
"1 {target object/alias may not appear in FROM clause: $nm}"
}
finish_test finish_test

View File

@@ -203,7 +203,7 @@ foreach {tn wo} {
} {10 1 101 20 2 101 30 3 101} } {10 1 101 20 2 101 30 3 101}
do_execsql_test 3.$tn.4 { do_execsql_test 3.$tn.4 {
UPDATE g1 SET c=101 FROM g1; UPDATE g1 SET c=101 FROM g1 AS g2;
} }
do_execsql_test 3.$tn.5 { do_execsql_test 3.$tn.5 {
SELECT * FROM g1; SELECT * FROM g1;