1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-16 23:02:26 +03:00

An attempt to get UPDATE FROM working when the FROM clause contains a

RIGHT or FULL JOIN.

FossilOrigin-Name: a124e4f96f883d8682ba7a253d33a9565ed0fc3580525225b95733bd3782a806
This commit is contained in:
drh
2022-05-25 02:32:11 +00:00
parent 6af03b469e
commit fb98dac04f
5 changed files with 108 additions and 18 deletions

View File

@@ -940,7 +940,18 @@ cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
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

View File

@@ -6518,6 +6518,29 @@ static int countOfViewOptimization(Parse *pParse, Select *p){
}
#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.
**
@@ -6622,15 +6645,12 @@ int sqlite3Select(
** 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,