-C When\san\sON\sclause\son\san\sINNER\sJOIN\sreferences\sa\stable\sto\sthe\sright\sof\nof\sthe\sjoin,\sjust\sconvert\sthe\sON\sclause\sto\san\sordinary\sWHERE\sclause\sterm,\nin\sorder\sto\sbe\scompatible\swith\solder\sversions\sof\sSQLite.\s\sSee\n[forum:/forumpost/687b0bf563a1d4f1|forum\sthread\s687b0bf563a1d4f1]\sfor\sdetails.
-D 2022-05-24T16:05:41.137
+C An\sattempt\sto\sget\sUPDATE\sFROM\sworking\swhen\sthe\sFROM\sclause\scontains\sa\nRIGHT\sor\sFULL\sJOIN.
+D 2022-05-25T02:32:11.876
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 42120492784fc9bcd9082b5c9b5e329b7318c357f9f3574a1bbfcf7418910356
F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3
-F src/parse.y ad9a59d0078267e5aea4cf62f244c0ce6fcec9a91edd365e929c75d3a1716563
+F src/parse.y b58ad9fadf31e26e45214a4d8be4351ec2910bbd914caa2e172d616057f67ddc
F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
F src/resolve.c a4eb3c617027fd049b07432f3b942ea7151fa793a332a11a7d0f58c9539e104f
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
-F src/select.c 4f13d01141caae4f982125fecf50703c746ab621c57ca0aa747fab2b28e88c1e
+F src/select.c a0dca0b4a328826d4713195a2fe305852cd8b1ed876311667b00c64b93a7fe23
F src/shell.c.in 55d71bf8c7a8f2a66bc5f99cd76f226790b291599b83415533dad84a553ed806
F src/sqlite.h.in d15c307939039086adca159dd340a94b79b69827e74c6d661f343eeeaefba896
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F test/upfrom1.test 8cb06689e99cd707d884faa16da0e8eb26ff658bb01c47ddf72fadade666e6e1
F test/upfrom2.test 66f3ebf721b3cebd922faee5c386bf244f816d416b57c000753ff51af62328a1
F test/upfrom3.test 6130f24ebf97f5ea865e5d2a14a2d543fe5428a62e87cc60f62d875e45c1f5f0
+F test/upfrom4.test 71d25e18c7d04e2930dcbd78e6aafb6931c80cb08f77039309b6095a12f1e62e
F test/upfromfault.test 3a10075a0043f0c4fad6614b2c371f88a8ba5a4acab68b907438413865d6a8d6
F test/upsert1.test b0ae2f58680c5205b4bc1cdeed3c3d444057c506f6c44494fa3eac60731d68a2
F test/upsert2.test 720e94d09f7362a282bc69b3c6b83d51daeaaf0440eb4920a08b86518b8c7496
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 2f9a42fb141d386f6edd03a37da3b0cef63dcc9fbfd076076b5330a8aa7d45a8
-R b23285aa9cad2fbb603a6d0b592197f4
+P 2b6ebba26d936ae7b9acf7d4bd15e82cbfabda22e1044b3dd838c7b07095100e
+R 014358eba344e3263997b7e1fc402f9a
+T *branch * update-from-right-join
+T *sym-update-from-right-join *
+T -sym-trunk *
U drh
-Z a3136607e1e2d962d7405d0d9fcd3d10
+Z f458636c8150cdb5371ae8ca6d7f2721
# Remove this line to create a well-formed Fossil manifest.
-2b6ebba26d936ae7b9acf7d4bd15e82cbfabda22e1044b3dd838c7b07095100e
\ No newline at end of file
+a124e4f96f883d8682ba7a253d33a9565ed0fc3580525225b95733bd3782a806
\ No newline at end of file
where_opt_ret(W). {
sqlite3SrcListIndexedBy(pParse, X, &I);
sqlite3ExprListCheckLength(pParse,Y,"set list");
- X = sqlite3SrcListAppendList(pParse, X, F);
+ if( F ){
+ SrcList *pFromClause = F;
+ if( pFromClause->nSrc>1 ){
+ Select *pSubquery;
+ Token as;
+ pSubquery = sqlite3SelectNew(pParse,0,pFromClause,0,0,0,0,SF_NestedFrom,0);
+ as.n = 0;
+ as.z = 0;
+ pFromClause = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&as,pSubquery,0);
+ }
+ X = sqlite3SrcListAppendList(pParse, X, pFromClause);
+ }
sqlite3Update(pParse,X,Y,W,R,0,0,0);
}
%endif
}
#endif /* SQLITE_COUNTOFVIEW_OPTIMIZATION */
+/*
+** If any term of pSrc, or any SF_NestedFrom sub-query, is not the same
+** as pSrcItem but has the same alias as p0, then return true.
+** Otherwise return false.
+*/
+static int sameSrcAlias(SrcItem *p0, SrcList *pSrc){
+ int i;
+ for(i=0; i<pSrc->nSrc; i++){
+ SrcItem *p1 = &pSrc->a[i];
+ if( p1==p0 ) continue;
+ if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){
+ return 1;
+ }
+ if( p1->pSelect
+ && (p1->pSelect->selFlags & SF_NestedFrom)!=0
+ && sameSrcAlias(p0, p1->pSelect->pSrc)
+ ){
+ return 1;
+ }
+ }
+ return 0;
+}
+
/*
** Generate code for the SELECT statement given in the p argument.
**
** disallow it altogether. */
if( p->selFlags & SF_UFSrcCheck ){
SrcItem *p0 = &p->pSrc->a[0];
- for(i=1; i<p->pSrc->nSrc; i++){
- SrcItem *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( sameSrcAlias(p0, p->pSrc) ){
+ sqlite3ErrorMsg(pParse,
+ "target object/alias may not appear in FROM clause: %s",
+ p0->zAlias ? p0->zAlias : p0->pTab->zName
+ );
+ goto select_end;
}
/* Clear the SF_UFSrcCheck flag. The check has already been performed,
--- /dev/null
+# 2022-05-24
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set testprefix upfrom4
+
+do_execsql_test 100 {
+ DROP TABLE IF EXISTS t5;
+ DROP TABLE IF EXISTS m1;
+ DROP TABLE IF EXISTS m2;
+ CREATE TABLE t5(a INTEGER PRIMARY KEY, b TEXT, c TEXT);
+ CREATE TABLE m1(x INTEGER PRIMARY KEY, y TEXT);
+ CREATE TABLE m2(u INTEGER PRIMARY KEY, v TEXT);
+
+ INSERT INTO t5 VALUES(1, 'one', 'ONE');
+ INSERT INTO t5 VALUES(2, 'two', 'TWO');
+ INSERT INTO t5 VALUES(3, 'three', 'THREE');
+ INSERT INTO t5 VALUES(4, 'four', 'FOUR');
+
+ INSERT INTO m1 VALUES(1, 'i');
+ INSERT INTO m1 VALUES(2, 'ii');
+ INSERT INTO m1 VALUES(3, 'iii');
+
+ INSERT INTO m2 VALUES(1, 'I');
+ INSERT INTO m2 VALUES(3, 'II');
+ INSERT INTO m2 VALUES(4, 'III');
+ SELECT * FROM t5;
+} {1 one ONE 2 two TWO 3 three THREE 4 four FOUR}
+
+do_execsql_test 110 {
+ BEGIN;
+ UPDATE t5 SET b=y, c=v FROM m1 LEFT JOIN m2 ON (x=u) WHERE x=a;
+ SELECT * FROM t5 ORDER BY a;
+ ROLLBACK;
+} {1 i I 2 ii {} 3 iii II 4 four FOUR}
+
+do_execsql_test 120 {
+ BEGIN;
+ UPDATE t5 SET b=y, c=v FROM m2 RIGHT JOIN m1 ON (x=u) WHERE x=a;
+ SELECT * FROM t5 ORDER BY a;
+ ROLLBACK;
+} {1 i I 2 ii {} 3 iii II 4 four FOUR}
+
+
+finish_test