diff options
author | drh <> | 2021-02-04 23:20:13 +0000 |
---|---|---|
committer | drh <> | 2021-02-04 23:20:13 +0000 |
commit | 70bd2124ed8dba89ee3ad2ccb25c5686b1d0ead5 (patch) | |
tree | 3f27cf04afa15c2b4e1e001bc8c99b6b3d2c5e02 /src/resolve.c | |
parent | 8ab79d6135b33523a5d7f5c988b080a63fb15db3 (diff) | |
parent | 7dec804d4210cf928820693735135f4307fef050 (diff) | |
download | sqlite-70bd2124ed8dba89ee3ad2ccb25c5686b1d0ead5.tar.gz sqlite-70bd2124ed8dba89ee3ad2ccb25c5686b1d0ead5.zip |
Change the RETURNING algorithm so that outputs accumulate in an ephemeral
table until all modifications have been completed, and only then do results
start being returned. This should help prevent problems with interleaved
sqlite3_step() calls on two separate DML statements. It also seems to be
closer to how PostgreSQL works, which might prevent compatibility problems.
FossilOrigin-Name: c4615eb28c3dd2d473daf104f32e60d02799f3158d9d275a899c39129cc71401
Diffstat (limited to 'src/resolve.c')
-rw-r--r-- | src/resolve.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/src/resolve.c b/src/resolve.c index 5074a2881..84ba82a11 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -371,7 +371,7 @@ static int lookupName( ** it is a new.* or old.* trigger argument reference. Or ** maybe it is an excluded.* from an upsert. */ - if( zDb==0 && cntTab==0 ){ + if( cntTab==0 && zDb==0 ){ pTab = 0; #ifndef SQLITE_OMIT_TRIGGER if( pParse->pTriggerTab!=0 ){ @@ -434,22 +434,27 @@ static int lookupName( }else #endif /* SQLITE_OMIT_UPSERT */ { -#ifndef SQLITE_OMIT_TRIGGER - if( iCol<0 ){ - pExpr->affExpr = SQLITE_AFF_INTEGER; - }else if( pExpr->iTable==0 ){ - testcase( iCol==31 ); - testcase( iCol==32 ); - pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); - }else{ - testcase( iCol==31 ); - testcase( iCol==32 ); - pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); - } pExpr->y.pTab = pTab; - pExpr->iColumn = (i16)iCol; - eNewExprOp = TK_TRIGGER; + if( iCol<0 ) pExpr->affExpr = SQLITE_AFF_INTEGER; + if( pParse->bReturning ){ + eNewExprOp = TK_REGISTER; + pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + + iCol + 1; + }else{ + pExpr->iColumn = (i16)iCol; + eNewExprOp = TK_TRIGGER; +#ifndef SQLITE_OMIT_TRIGGER + if( pExpr->iTable==0 ){ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); + }else{ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<<iCol)); + } #endif /* SQLITE_OMIT_TRIGGER */ + } } } } @@ -630,7 +635,10 @@ static int lookupName( lookupname_end: if( cnt==1 ){ assert( pNC!=0 ); - if( !ExprHasProperty(pExpr, EP_Alias) ){ + if( pParse->db->xAuth + && !ExprHasProperty(pExpr, EP_Alias) + && pExpr->op!=TK_REGISTER + ){ sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); } /* Increment the nRef value on all name contexts from TopNC up to |