aboutsummaryrefslogtreecommitdiff
path: root/src/resolve.c
diff options
context:
space:
mode:
authordrh <>2021-02-04 23:20:13 +0000
committerdrh <>2021-02-04 23:20:13 +0000
commit70bd2124ed8dba89ee3ad2ccb25c5686b1d0ead5 (patch)
tree3f27cf04afa15c2b4e1e001bc8c99b6b3d2c5e02 /src/resolve.c
parent8ab79d6135b33523a5d7f5c988b080a63fb15db3 (diff)
parent7dec804d4210cf928820693735135f4307fef050 (diff)
downloadsqlite-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.c40
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