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

Snapshot. New design appears to work on a simple test case.

FossilOrigin-Name: 8a65fbeecf3597e30853c5f0ccd9b8b46c508854fa521e58e0db279deebca7d4
This commit is contained in:
drh
2021-02-04 20:52:20 +00:00
parent 381bdacc8f
commit 552562c48f
6 changed files with 72 additions and 51 deletions

View File

@@ -1,5 +1,5 @@
C Preliminary\schanges\sfor\sa\snew\simplementation\sof\sRETURNING\sthat\scaptures\sall\nresults\sin\sa\sbuffer\sand\splays\sthem\sall\sback\safter\sthe\sDML\sstatement\ncompletes.\s\sThis\savoids\sproblems\swith\sinterleaved\sDML\sstatements.\nThis\sparticular\scheck-in\sis\sa\snon-functional\swork\sin\sprogress. C Snapshot.\s\sNew\sdesign\sappears\sto\swork\son\sa\ssimple\stest\scase.
D 2021-02-04T17:29:04.659 D 2021-02-04T20:52:20.449
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -485,7 +485,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e F src/btree.c 694020ad8a3af3d79b09f74c8f1421272a419cdea42a13401e3b0f7dea6e9c3e
F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e
F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331 F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331
F src/build.c 5285b8d1e4cf21dd9e12619fe0a6067bcb036ee7f7ad5cd31a39a05c5823e2a2 F src/build.c 1b8d3d59dcd52c5d74847a56174e6819713012cd370809352375422d0907c8bf
F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410 F src/ctime.c 2a322b9a3d75771fb4d99e0702851f4f68dda982507a0f798eefb0712969a410
@@ -539,14 +539,14 @@ F src/pragma.h 8dc78ab7e9ec6ce3ded8332810a2066f1ef6267e2e03cd7356ee00276125c6cf
F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f F src/prepare.c f288cbc35f79eb32e162de7e80a63ebe00d80e639dcfac071bee11570cbdb16f
F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed F src/printf.c 30e92b638fac71dcd85cdea1d12ecfae354c9adee2c71e8e1ae4727cde7c91ed
F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
F src/resolve.c f6761473ea4b51190fc52f8f2121498b78717266e106e7bff12849ea2d52165f F src/resolve.c 397c3e889fea46fc7aa0bbe98ffd91046b7b44ade2cdab6b2357a4b7ddd10b13
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc F src/select.c 738cb746189f721f59972993c13085fa2975c4cbfd04ba26445f3b42c81237dc
F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879 F src/shell.c.in 9ebc74e4f05cfbd0f4a36060fdaeff1da4e9af4458358722bc08c5a1ab9a0879
F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57 F src/sqlite.h.in 8855a19f37ade8dad189a9e48233a2ebe1b46faf469c7eb0906a654e252dcc57
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e
F src/sqliteInt.h 596729ed0c2509a32cb17cecc7baf2a3499299064c03dbe79f8daca08d4daf7c F src/sqliteInt.h c51a21569e193f377f6d70a2fed0031fd88f141e112a5902cb9e31c1f79f5194
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -607,7 +607,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9 F src/tokenize.c c64c49d7c2ec4490c2fef1f24350167ba16b03b0c6cee58ad1a1d70a4325d4e9
F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda F src/treeview.c 4b92992176fb2caefbe06ba5bd06e0e0ebcde3d5564758da672631f17aa51cda
F src/trigger.c 803db1f98d84a86b31a13e8a42715936bc760d0192bc4264d57a96f362c2a591 F src/trigger.c 5da6ba6d4067b5dcdd11a6da37ce3cb56586df75a7be685efb534c46d5c773c8
F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723 F src/update.c 0f5a61f0787199983530a33f6fffe4f52742f35fcdf6ccfad1078b1a8bc17723
F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
@@ -1899,10 +1899,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 5c8e6296aa9f69a092364524b716ba894f113f7f1e6024b9a2eaa01c239e65c1 P 04b77d63216ce11b4e797946953bcde504fc005807c7a5ac757fbf47d78698dc
R 9ba8b89a255b185f318ef97355eff6b3 R 3969643abefe6509994dc8b8c75efd08
T *branch * returning-manifested
T *sym-returning-manifested *
T -sym-trunk *
U drh U drh
Z 04ce06a70e76b82a776d153a576955fb Z b4647d4c6645877bc3632b5ebc38eb6e

View File

@@ -1 +1 @@
04b77d63216ce11b4e797946953bcde504fc005807c7a5ac757fbf47d78698dc 8a65fbeecf3597e30853c5f0ccd9b8b46c508854fa521e58e0db279deebca7d4

View File

@@ -164,8 +164,7 @@ void sqlite3FinishCoding(Parse *pParse){
sqlite3VdbeAddOp0(v, OP_Noop); VdbeComment((v, "TODO: Commit changes")); sqlite3VdbeAddOp0(v, OP_Noop); VdbeComment((v, "TODO: Commit changes"));
addrRewind = addrRewind =
sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur);
reg = pParse->nMem+1; reg = pReturning->iRetReg;
pParse->nMem += pReturning->nRetCol;
for(i=0; i<pReturning->nRetCol; i++){ for(i=0; i<pReturning->nRetCol; i++){
sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i); sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i);
} }

View File

@@ -371,7 +371,7 @@ static int lookupName(
** it is a new.* or old.* trigger argument reference. Or ** it is a new.* or old.* trigger argument reference. Or
** maybe it is an excluded.* from an upsert. ** maybe it is an excluded.* from an upsert.
*/ */
if( zDb==0 && cntTab==0 ){ if( cntTab==0 && zDb==0 ){
pTab = 0; pTab = 0;
#ifndef SQLITE_OMIT_TRIGGER #ifndef SQLITE_OMIT_TRIGGER
if( pParse->pTriggerTab!=0 ){ if( pParse->pTriggerTab!=0 ){
@@ -434,22 +434,27 @@ static int lookupName(
}else }else
#endif /* SQLITE_OMIT_UPSERT */ #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->y.pTab = pTab;
pExpr->iColumn = (i16)iCol; if( iCol<0 ) pExpr->affExpr = SQLITE_AFF_INTEGER;
eNewExprOp = TK_TRIGGER; 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 */ #endif /* SQLITE_OMIT_TRIGGER */
}
} }
} }
} }
@@ -630,7 +635,10 @@ static int lookupName(
lookupname_end: lookupname_end:
if( cnt==1 ){ if( cnt==1 ){
assert( pNC!=0 ); 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); sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList);
} }
/* Increment the nRef value on all name contexts from TopNC up to /* Increment the nRef value on all name contexts from TopNC up to

View File

@@ -3037,6 +3037,7 @@ struct NameContext {
ExprList *pEList; /* Optional list of result-set columns */ ExprList *pEList; /* Optional list of result-set columns */
AggInfo *pAggInfo; /* Information about aggregates at this level */ AggInfo *pAggInfo; /* Information about aggregates at this level */
Upsert *pUpsert; /* ON CONFLICT clause information from an upsert */ Upsert *pUpsert; /* ON CONFLICT clause information from an upsert */
int iBaseReg; /* For TK_REGISTER when parsing RETURNING */
} uNC; } uNC;
NameContext *pNext; /* Next outer name context. NULL for outermost */ NameContext *pNext; /* Next outer name context. NULL for outermost */
int nRef; /* Number of names resolved by this context */ int nRef; /* Number of names resolved by this context */
@@ -3065,6 +3066,7 @@ struct NameContext {
#define NC_UEList 0x00080 /* True if uNC.pEList is used */ #define NC_UEList 0x00080 /* True if uNC.pEList is used */
#define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */ #define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */
#define NC_UUpsert 0x00200 /* True if uNC.pUpsert is used */ #define NC_UUpsert 0x00200 /* True if uNC.pUpsert is used */
#define NC_UBaseReg 0x00400 /* True if uNC.iBaseReg is used */
#define NC_MinMaxAgg 0x01000 /* min/max aggregates seen. See note above */ #define NC_MinMaxAgg 0x01000 /* min/max aggregates seen. See note above */
#define NC_Complex 0x02000 /* True if a function or subquery seen */ #define NC_Complex 0x02000 /* True if a function or subquery seen */
#define NC_AllowWin 0x04000 /* Window functions are allowed here */ #define NC_AllowWin 0x04000 /* Window functions are allowed here */
@@ -3668,6 +3670,7 @@ struct Returning {
TriggerStep retTStep; /* The trigger step */ TriggerStep retTStep; /* The trigger step */
int iRetCur; /* Transient table holding RETURNING results */ int iRetCur; /* Transient table holding RETURNING results */
int nRetCol; /* Number of in pReturnEL after expansion */ int nRetCol; /* Number of in pReturnEL after expansion */
int iRetReg; /* Register array for holding a row of RETURNING */
}; };
/* /*

View File

@@ -832,6 +832,7 @@ static ExprList *sqlite3ExpandReturning(
ExprList *pNew = 0; ExprList *pNew = 0;
sqlite3 *db = pParse->db; sqlite3 *db = pParse->db;
int i; int i;
for(i=0; i<pList->nExpr; i++){ for(i=0; i<pList->nExpr; i++){
Expr *pOldExpr = pList->a[i].pExpr; Expr *pOldExpr = pList->a[i].pExpr;
if( ALWAYS(pOldExpr!=0) && pOldExpr->op==TK_ASTERISK ){ if( ALWAYS(pOldExpr!=0) && pOldExpr->op==TK_ASTERISK ){
@@ -856,6 +857,15 @@ static ExprList *sqlite3ExpandReturning(
} }
} }
} }
if( !db->mallocFailed ){
Vdbe *v = pParse->pVdbe;
assert( v!=0 );
sqlite3VdbeSetNumCols(v, pNew->nExpr);
for(i=0; i<pNew->nExpr; i++){
sqlite3VdbeSetColName(v, i, COLNAME_NAME, pNew->a[i].zEName,
SQLITE_TRANSIENT);
}
}
return pNew; return pNew;
} }
@@ -868,7 +878,7 @@ static void codeReturningTrigger(
Parse *pParse, /* Parse context */ Parse *pParse, /* Parse context */
Trigger *pTrigger, /* The trigger step that defines the RETURNING */ Trigger *pTrigger, /* The trigger step that defines the RETURNING */
Table *pTab, /* The table to code triggers from */ Table *pTab, /* The table to code triggers from */
int reg /* The first in an array of registers */ int regIn /* The first in an array of registers */
){ ){
Vdbe *v = pParse->pVdbe; Vdbe *v = pParse->pVdbe;
ExprList *pNew; ExprList *pNew;
@@ -882,28 +892,32 @@ static void codeReturningTrigger(
VdbeComment((v, "RETURNING trigger goes here")); VdbeComment((v, "RETURNING trigger goes here"));
pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab);
if( pNew ){ if( pNew ){
NameContext sNC;
memset(&sNC, 0, sizeof(sNC));
pReturning->nRetCol = pNew->nExpr; pReturning->nRetCol = pNew->nExpr;
pReturning->iRetCur = pParse->nTab++; pReturning->iRetCur = pParse->nTab++;
sqlite3ExprListDelete(pParse->db, pNew); sNC.pParse = pParse;
} sNC.uNC.iBaseReg = regIn;
sNC.ncFlags = NC_UBaseReg;
#if 0 pParse->eTriggerOp = pTrigger->op;
pSelect->pEList = pParse->pTriggerTab = pTab;
sqlite3ExpandReturning(pParse, pList, pParse->pTriggerTab); if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK ){
sqlite3SelectDestInit(&sDest, SRT_Output, 0); int i;
pNew = sqlite3SelectDup(db, pSelect, 0); int nCol = pNew->nExpr;
if( pNew ){ int reg = pParse->nMem+1;
sqlite3Select(pParse, pNew, &sDest); pParse->nMem += nCol+2;
if( pNew->selFlags & (SF_Aggregate|SF_HasAgg|SF_WinRewrite) ){ pReturning->iRetReg = reg;
sqlite3ErrorMsg(pParse, "aggregates not allowed in RETURNING"); for(i=0; i<nCol; i++){
} sqlite3ExprCodeFactorable(pParse, pNew->a[i].pExpr, reg+i);
sqlite3SelectDelete(db, pNew);
}
sqlite3ExprListDelete(db, pSelect->pEList);
pStep->pSelect->pEList = pList;
break;
} }
#endif sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i);
sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1);
sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1);
}
sqlite3ExprListDelete(pParse->db, pNew);
pParse->eTriggerOp = 0;
pParse->pTriggerTab = 0;
}
} }