mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Working prototype.
FossilOrigin-Name: b7ef4dc21f187ff4ff679e823782535188c3814aa6ce720b3a01c6d3ba4ef9f5
This commit is contained in:
26
manifest
26
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Incorporate\sthe\ssqlite3TriggerList()\soptimization\sfrom\strunk.\s\sAnd\smove\nthe\spReturning\sfield\sto\sthe\suninitialized\sarea\sin\sthe\sParse\sobject,\sto\nsave\smemset()\stime.
|
C Working\sprototype.
|
||||||
D 2021-01-29T14:22:56.875
|
D 2021-01-29T19:32:17.139
|
||||||
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 47d9fe97d5c0d74506154e3597f8a23b81a00080751dc4d11fec91ee22796f4c
|
F src/btree.c 47d9fe97d5c0d74506154e3597f8a23b81a00080751dc4d11fec91ee22796f4c
|
||||||
F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e
|
F src/btree.h 285f8377aa1353185a32bf455faafa9ff9a0d40d074d60509534d14990c7829e
|
||||||
F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331
|
F src/btreeInt.h 7614cae30f95b6aed0c7cac7718276a55cfe2c77058cbfd8bef5b75329757331
|
||||||
F src/build.c ba8af18891c07501a185ecd02a2bc13a593de9bfd59dbffa5d126780c0c9fb8e
|
F src/build.c 2aded84176695b0f885eec582f3afbe667737998a14fb39b3eb6623626a8f2b5
|
||||||
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
|
||||||
@@ -495,7 +495,7 @@ F src/dbstat.c 3aa79fc3aed7ce906e4ea6c10e85d657299e304f6049861fe300053ac57de36c
|
|||||||
F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe
|
F src/delete.c 927cf8f900583e79aca8f1a321979e0a8f053babd9a690b44b38f79de2cc09fe
|
||||||
F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74
|
F src/expr.c 47c85263e6d179424e6b09e2c79db5704ab5b8cbc2fae2ee3285faa2566f2e74
|
||||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||||
F src/fkey.c 83372403298e6a7dd989a47aaacdbaa5b4307b5199dbd56e07d4896066b3de72
|
F src/fkey.c df06098e66c95bb5169e2e79eb59583efe00794e6345e196e776dd6f4b1ea33b
|
||||||
F src/func.c 796a7a4a0ff5eee82a04ee3c8265c5ebf9c6a9f5625621c5f97ed94f6224d7d9
|
F src/func.c 796a7a4a0ff5eee82a04ee3c8265c5ebf9c6a9f5625621c5f97ed94f6224d7d9
|
||||||
F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81
|
F src/global.c ed55af196a9b66e198aaeda3f5454c3aa7d7d050c6c938181fd044b70d180a81
|
||||||
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
|
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
|
||||||
@@ -530,7 +530,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
|
|||||||
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
|
||||||
F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d
|
F src/pager.c c49952ac5e9cc536778eff528091d79d38b3e45cbeeed4695dc05e207dc6547d
|
||||||
F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
|
F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
|
||||||
F src/parse.y 6b462c25bae7e0c53f2935f9157f82abeba07754905ef8835c978742c5473ff3
|
F src/parse.y 67ba503780de64b967ae195b7e14c33531329228e1bc0b83d63324beb733680b
|
||||||
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
|
F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177
|
||||||
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
|
||||||
F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a
|
F src/pcache1.c 6596e10baf3d8f84cc1585d226cf1ab26564a5f5caf85a15757a281ff977d51a
|
||||||
@@ -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 1948a92ca9eab776632816b97e57c61d933474a78aad4f4ef835c916a83dbb1c
|
F src/resolve.c b714e6f9f3cdfb6ba287bb5ef76888ec8cd9e15c98a608c82bc3300b99a245d7
|
||||||
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 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7
|
F src/sqlite.h.in 0af968a1fa3c717261e1df0ed105fa7bddb4d82de7e0adb3eab49e6aa81b4de7
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e
|
F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e
|
||||||
F src/sqliteInt.h aebfa715feaf134b5d0cf6a2dccb4a4d0172d7915658c69abd5b3a0cb3b794d3
|
F src/sqliteInt.h e3ad4cc28df195a9676d9f108d2cd1d41da6b505950797dc069094d90fd9f197
|
||||||
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,17 +607,17 @@ 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 731ea5ed6b308574b7dc2a5d2a9187ef5510a3692cc1ea06a34608a084b8f376
|
F src/trigger.c 39ac8d708d6c929817c230fba0cf1ef5bd7ac52ce883df8ab49bcdc28817a787
|
||||||
F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580
|
F src/update.c 9f126204a6acb96bbe47391ae48e0fc579105d8e76a6d9c4fab3271367476580
|
||||||
F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235
|
F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235
|
||||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||||
F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048
|
F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048
|
||||||
F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286
|
F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286
|
||||||
F src/vdbe.c 102d21260bddbb43c845603c3a2d6b4f3762e72f836ccda12991f291485d2539
|
F src/vdbe.c 102d21260bddbb43c845603c3a2d6b4f3762e72f836ccda12991f291485d2539
|
||||||
F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1
|
F src/vdbe.h a71bf43572d3de57923d1928ac01ae8d355cd67e94462ba4f7462265cedbef9a
|
||||||
F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e
|
F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e
|
||||||
F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9
|
F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9
|
||||||
F src/vdbeaux.c e91d74e24babcf61969279b193e228cf4f8bc724a9cc59ed287db064326876f8
|
F src/vdbeaux.c 7ae7b2d7d97250d7100065eca7f04324f331b16b8165775f1724af10c7240d11
|
||||||
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
|
F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1
|
||||||
F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f
|
F src/vdbemem.c 947f2a65910edb4014dc981d33e414a68c51f169f9df8c4c493a0ba840b6eb1f
|
||||||
F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a
|
F src/vdbesort.c f5b5e473a7cee44e47a94817b042fd7172cf3aa2c0a7928a8339d612bcfdec5a
|
||||||
@@ -1898,7 +1898,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 5fbcb208d24d45169fc53ad8738dd3545d9bbd26b7434e31afc7f6419cd4e958 0defaf730bdc82212a5d3feeb2e16f16423b1691b0aaa7da1787eb82ea39ae9e
|
P 29fbaf0e3eabda08500f350bc32e9f339e5732a65bfa62822eefb692a2ff0243
|
||||||
R c5cf37660ce1737a23c63b9fdc43eb3e
|
R 0f4eeb3bbbe288c435a7916147e604d5
|
||||||
U drh
|
U drh
|
||||||
Z c6d2a25c829d2b926a3cb0974507f1ba
|
Z cf32b347d108b527d7c22e05c5929805
|
||||||
|
@@ -1 +1 @@
|
|||||||
29fbaf0e3eabda08500f350bc32e9f339e5732a65bfa62822eefb692a2ff0243
|
b7ef4dc21f187ff4ff679e823782535188c3814aa6ce720b3a01c6d3ba4ef9f5
|
46
src/build.c
46
src/build.c
@@ -1243,13 +1243,55 @@ void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Name of the magic TEMP trigger used to implement RETURNING
|
||||||
|
*/
|
||||||
|
#define RETURNING_TRIGGER "sqlite_returning"
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Delete the data structures associated with the RETURNING clause.
|
||||||
|
*/
|
||||||
|
static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){
|
||||||
|
Hash *pHash;
|
||||||
|
pHash = &(db->aDb[1].pSchema->trigHash);
|
||||||
|
assert( sqlite3HashFind(pHash, RETURNING_TRIGGER)==&pRet->retTrig );
|
||||||
|
sqlite3HashInsert(pHash, RETURNING_TRIGGER, 0);
|
||||||
|
sqlite3ExprListDelete(db, pRet->pReturnEL);
|
||||||
|
sqlite3DbFree(db, pRet);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Add the RETURNING clause to the parser currently underway.
|
** Add the RETURNING clause to the parser currently underway.
|
||||||
*/
|
*/
|
||||||
void sqlite3AddReturning(Parse *pParse, ExprList *pList){
|
void sqlite3AddReturning(Parse *pParse, ExprList *pList){
|
||||||
|
Returning *pRet;
|
||||||
|
Hash *pHash;
|
||||||
|
sqlite3 *db = pParse->db;
|
||||||
|
pRet = sqlite3DbMallocZero(db, sizeof(*pRet));
|
||||||
|
if( pRet==0 ){
|
||||||
|
sqlite3ExprListDelete(db, pList);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pRet->pParse = pParse;
|
||||||
|
pRet->pReturnEL = pList;
|
||||||
sqlite3ParserAddCleanup(pParse,
|
sqlite3ParserAddCleanup(pParse,
|
||||||
(void(*)(sqlite3*,void*))sqlite3ExprListDelete, pList);
|
(void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet);
|
||||||
pParse->pReturning = pList;
|
pRet->retTrig.zName = "sqlite_returning";
|
||||||
|
pRet->retTrig.op = TK_RETURNING;
|
||||||
|
pRet->retTrig.tr_tm = TRIGGER_AFTER;
|
||||||
|
pRet->retTrig.bReturning = 1;
|
||||||
|
pRet->retTrig.pSchema = db->aDb[1].pSchema;
|
||||||
|
pRet->retTrig.step_list = &pRet->retTStep;
|
||||||
|
pRet->retTStep.op = TK_SELECT;
|
||||||
|
pRet->retTStep.eTrigDest = SRT_Output;
|
||||||
|
pRet->retTStep.pTrig = &pRet->retTrig;
|
||||||
|
pRet->retTStep.pSelect = &pRet->retSel;
|
||||||
|
pRet->retSel.op = TK_ALL;
|
||||||
|
pRet->retSel.pEList = pList;
|
||||||
|
pRet->retSel.pSrc = (SrcList*)&pRet->retSrcList;
|
||||||
|
pHash = &(db->aDb[1].pSchema->trigHash);
|
||||||
|
assert( sqlite3HashFind(pHash, RETURNING_TRIGGER)==0 );
|
||||||
|
sqlite3HashInsert(pHash, "sqlite_returning", &pRet->retTrig);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1352,7 +1352,8 @@ static Trigger *fkActionTrigger(
|
|||||||
|
|
||||||
switch( action ){
|
switch( action ){
|
||||||
case OE_Restrict:
|
case OE_Restrict:
|
||||||
pStep->op = TK_SELECT;
|
pStep->op = TK_SELECT;
|
||||||
|
pStep->eTrigDest = SRT_Discard;
|
||||||
break;
|
break;
|
||||||
case OE_Cascade:
|
case OE_Cascade:
|
||||||
if( !pChanges ){
|
if( !pChanges ){
|
||||||
|
@@ -905,7 +905,7 @@ where_opt_ret(A) ::= WHERE expr(X) RETURNING selcollist(Y).
|
|||||||
//
|
//
|
||||||
%if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER
|
%if SQLITE_ENABLE_UPDATE_DELETE_LIMIT || SQLITE_UDL_CAPABLE_PARSER
|
||||||
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
|
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
|
||||||
where_opt(W) orderby_opt(O) limit_opt(L). {
|
where_opt_ret(W) orderby_opt(O) limit_opt(L). {
|
||||||
sqlite3SrcListIndexedBy(pParse, X, &I);
|
sqlite3SrcListIndexedBy(pParse, X, &I);
|
||||||
X = sqlite3SrcListAppendList(pParse, X, F);
|
X = sqlite3SrcListAppendList(pParse, X, F);
|
||||||
sqlite3ExprListCheckLength(pParse,Y,"set list");
|
sqlite3ExprListCheckLength(pParse,Y,"set list");
|
||||||
@@ -920,7 +920,7 @@ cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
|
|||||||
}
|
}
|
||||||
%else
|
%else
|
||||||
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
|
cmd ::= with UPDATE orconf(R) xfullname(X) indexed_opt(I) SET setlist(Y) from(F)
|
||||||
where_opt(W). {
|
where_opt_ret(W). {
|
||||||
sqlite3SrcListIndexedBy(pParse, X, &I);
|
sqlite3SrcListIndexedBy(pParse, X, &I);
|
||||||
sqlite3ExprListCheckLength(pParse,Y,"set list");
|
sqlite3ExprListCheckLength(pParse,Y,"set list");
|
||||||
X = sqlite3SrcListAppendList(pParse, X, F);
|
X = sqlite3SrcListAppendList(pParse, X, F);
|
||||||
|
@@ -371,23 +371,26 @@ 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 && zTab!=0 && cntTab==0 ){
|
if( zDb==0 && cntTab==0 ){
|
||||||
pTab = 0;
|
pTab = 0;
|
||||||
#ifndef SQLITE_OMIT_TRIGGER
|
#ifndef SQLITE_OMIT_TRIGGER
|
||||||
if( pParse->pTriggerTab!=0 ){
|
if( pParse->pTriggerTab!=0 ){
|
||||||
int op = pParse->eTriggerOp;
|
int op = pParse->eTriggerOp;
|
||||||
assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
|
assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT );
|
||||||
if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){
|
if( op!=TK_DELETE && zTab && sqlite3StrICmp("new",zTab) == 0 ){
|
||||||
pExpr->iTable = 1;
|
pExpr->iTable = 1;
|
||||||
pTab = pParse->pTriggerTab;
|
pTab = pParse->pTriggerTab;
|
||||||
}else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){
|
}else if( op!=TK_INSERT && zTab && sqlite3StrICmp("old",zTab)==0 ){
|
||||||
pExpr->iTable = 0;
|
pExpr->iTable = 0;
|
||||||
pTab = pParse->pTriggerTab;
|
pTab = pParse->pTriggerTab;
|
||||||
|
}else if( pParse->bReturning ){
|
||||||
|
pExpr->iTable = op!=TK_DELETE;
|
||||||
|
pTab = pParse->pTriggerTab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* SQLITE_OMIT_TRIGGER */
|
#endif /* SQLITE_OMIT_TRIGGER */
|
||||||
#ifndef SQLITE_OMIT_UPSERT
|
#ifndef SQLITE_OMIT_UPSERT
|
||||||
if( (pNC->ncFlags & NC_UUpsert)!=0 ){
|
if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab ){
|
||||||
Upsert *pUpsert = pNC->uNC.pUpsert;
|
Upsert *pUpsert = pNC->uNC.pUpsert;
|
||||||
if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){
|
if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){
|
||||||
pTab = pUpsert->pUpsertSrc->a[0].pTab;
|
pTab = pUpsert->pUpsertSrc->a[0].pTab;
|
||||||
|
@@ -1159,6 +1159,7 @@ typedef struct ParseCleanup ParseCleanup;
|
|||||||
typedef struct PreUpdate PreUpdate;
|
typedef struct PreUpdate PreUpdate;
|
||||||
typedef struct PrintfArguments PrintfArguments;
|
typedef struct PrintfArguments PrintfArguments;
|
||||||
typedef struct RenameToken RenameToken;
|
typedef struct RenameToken RenameToken;
|
||||||
|
typedef struct Returning Returning;
|
||||||
typedef struct RowSet RowSet;
|
typedef struct RowSet RowSet;
|
||||||
typedef struct Savepoint Savepoint;
|
typedef struct Savepoint Savepoint;
|
||||||
typedef struct Select Select;
|
typedef struct Select Select;
|
||||||
@@ -3429,6 +3430,7 @@ struct Parse {
|
|||||||
u32 oldmask; /* Mask of old.* columns referenced */
|
u32 oldmask; /* Mask of old.* columns referenced */
|
||||||
u32 newmask; /* Mask of new.* columns referenced */
|
u32 newmask; /* Mask of new.* columns referenced */
|
||||||
u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
|
u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
|
||||||
|
u8 bReturning; /* Coding a RETURNING trigger */
|
||||||
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
|
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
|
||||||
u8 disableTriggers; /* True to disable triggers */
|
u8 disableTriggers; /* True to disable triggers */
|
||||||
|
|
||||||
@@ -3441,7 +3443,6 @@ struct Parse {
|
|||||||
|
|
||||||
int aTempReg[8]; /* Holding area for temporary registers */
|
int aTempReg[8]; /* Holding area for temporary registers */
|
||||||
Token sNameToken; /* Token with unqualified schema object name */
|
Token sNameToken; /* Token with unqualified schema object name */
|
||||||
ExprList *pReturning; /* The RETURNING clause, if any */
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
** Above is constant between recursions. Below is reset before and after
|
** Above is constant between recursions. Below is reset before and after
|
||||||
@@ -3579,6 +3580,7 @@ struct Trigger {
|
|||||||
char *table; /* The table or view to which the trigger applies */
|
char *table; /* The table or view to which the trigger applies */
|
||||||
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */
|
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */
|
||||||
u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
|
u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */
|
||||||
|
u8 bReturning; /* This trigger implements a RETURNING clause */
|
||||||
Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */
|
Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */
|
||||||
IdList *pColumns; /* If this is an UPDATE OF <column-list> trigger,
|
IdList *pColumns; /* If this is an UPDATE OF <column-list> trigger,
|
||||||
the <column-list> is stored here */
|
the <column-list> is stored here */
|
||||||
@@ -3639,6 +3641,7 @@ struct Trigger {
|
|||||||
struct TriggerStep {
|
struct TriggerStep {
|
||||||
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
|
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
|
||||||
u8 orconf; /* OE_Rollback etc. */
|
u8 orconf; /* OE_Rollback etc. */
|
||||||
|
u8 eTrigDest; /* SRT_ destination value for SELECT */
|
||||||
Trigger *pTrig; /* The trigger that this step is a part of */
|
Trigger *pTrig; /* The trigger that this step is a part of */
|
||||||
Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */
|
Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */
|
||||||
char *zTarget; /* Target table for DELETE, UPDATE, INSERT */
|
char *zTarget; /* Target table for DELETE, UPDATE, INSERT */
|
||||||
@@ -3652,6 +3655,18 @@ struct TriggerStep {
|
|||||||
TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
|
TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Information about a RETURNING clause
|
||||||
|
*/
|
||||||
|
struct Returning {
|
||||||
|
Parse *pParse; /* The parse that includes the RETURNING clause */
|
||||||
|
ExprList *pReturnEL; /* List of expressions to return */
|
||||||
|
Trigger retTrig; /* The transient trigger that implements RETURNING */
|
||||||
|
TriggerStep retTStep; /* The trigger step */
|
||||||
|
Select retSel; /* The SELECT statement that implements RETURNING */
|
||||||
|
u64 retSrcList; /* The empty FROM clause of the SELECT */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** An objected used to accumulate the text of a string where we
|
** An objected used to accumulate the text of a string where we
|
||||||
** do not necessarily know how big the string will be in the end.
|
** do not necessarily know how big the string will be in the end.
|
||||||
|
@@ -65,11 +65,16 @@ Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){
|
|||||||
while( p ){
|
while( p ){
|
||||||
Trigger *pTrig = (Trigger *)sqliteHashData(p);
|
Trigger *pTrig = (Trigger *)sqliteHashData(p);
|
||||||
if( pTrig->pTabSchema==pTab->pSchema
|
if( pTrig->pTabSchema==pTab->pSchema
|
||||||
&& 0==sqlite3StrICmp(pTrig->table, pTab->zName)
|
&& 0==sqlite3StrICmp(pTrig->table, pTab->zName)
|
||||||
){
|
){
|
||||||
pTrig->pNext = pList;
|
pTrig->pNext = pList;
|
||||||
pList = pTrig;
|
pList = pTrig;
|
||||||
}
|
}else if( pTrig->op==TK_RETURNING ){
|
||||||
|
pTrig->table = pTab->zName;
|
||||||
|
pTrig->pTabSchema = pTab->pSchema;
|
||||||
|
pTrig->pNext = pList;
|
||||||
|
pList = pTrig;
|
||||||
|
}
|
||||||
p = sqliteHashNext(p);
|
p = sqliteHashNext(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -405,6 +410,7 @@ TriggerStep *sqlite3TriggerSelectStep(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
pTriggerStep->op = TK_SELECT;
|
pTriggerStep->op = TK_SELECT;
|
||||||
|
pTriggerStep->eTrigDest = SRT_Discard;
|
||||||
pTriggerStep->pSelect = pSelect;
|
pTriggerStep->pSelect = pSelect;
|
||||||
pTriggerStep->orconf = OE_Default;
|
pTriggerStep->orconf = OE_Default;
|
||||||
pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
|
pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd);
|
||||||
@@ -563,6 +569,7 @@ TriggerStep *sqlite3TriggerDeleteStep(
|
|||||||
*/
|
*/
|
||||||
void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
|
void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){
|
||||||
if( pTrigger==0 ) return;
|
if( pTrigger==0 ) return;
|
||||||
|
assert( !pTrigger->bReturning );
|
||||||
sqlite3DeleteTriggerStep(db, pTrigger->step_list);
|
sqlite3DeleteTriggerStep(db, pTrigger->step_list);
|
||||||
sqlite3DbFree(db, pTrigger->zName);
|
sqlite3DbFree(db, pTrigger->zName);
|
||||||
sqlite3DbFree(db, pTrigger->table);
|
sqlite3DbFree(db, pTrigger->table);
|
||||||
@@ -734,6 +741,9 @@ Trigger *sqlite3TriggersExist(
|
|||||||
for(p=pList; p; p=p->pNext){
|
for(p=pList; p; p=p->pNext){
|
||||||
if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
|
if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){
|
||||||
mask |= p->tr_tm;
|
mask |= p->tr_tm;
|
||||||
|
}else if( p->op==TK_RETURNING ){
|
||||||
|
p->op = op;
|
||||||
|
mask |= TRIGGER_AFTER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pMask ){
|
if( pMask ){
|
||||||
@@ -849,7 +859,7 @@ static int codeTriggerProgram(
|
|||||||
default: assert( pStep->op==TK_SELECT ); {
|
default: assert( pStep->op==TK_SELECT ); {
|
||||||
SelectDest sDest;
|
SelectDest sDest;
|
||||||
Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
|
Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0);
|
||||||
sqlite3SelectDestInit(&sDest, SRT_Discard, 0);
|
sqlite3SelectDestInit(&sDest, pStep->eTrigDest, 0);
|
||||||
sqlite3Select(pParse, pSelect, &sDest);
|
sqlite3Select(pParse, pSelect, &sDest);
|
||||||
sqlite3SelectDelete(db, pSelect);
|
sqlite3SelectDelete(db, pSelect);
|
||||||
break;
|
break;
|
||||||
@@ -947,6 +957,7 @@ static TriggerPrg *codeRowTrigger(
|
|||||||
pSubParse->pToplevel = pTop;
|
pSubParse->pToplevel = pTop;
|
||||||
pSubParse->zAuthContext = pTrigger->zName;
|
pSubParse->zAuthContext = pTrigger->zName;
|
||||||
pSubParse->eTriggerOp = pTrigger->op;
|
pSubParse->eTriggerOp = pTrigger->op;
|
||||||
|
pSubParse->bReturning = pTrigger->bReturning;
|
||||||
pSubParse->nQueryLoop = pParse->nQueryLoop;
|
pSubParse->nQueryLoop = pParse->nQueryLoop;
|
||||||
pSubParse->disableVtab = pParse->disableVtab;
|
pSubParse->disableVtab = pParse->disableVtab;
|
||||||
|
|
||||||
@@ -996,6 +1007,9 @@ static TriggerPrg *codeRowTrigger(
|
|||||||
if( db->mallocFailed==0 && pParse->nErr==0 ){
|
if( db->mallocFailed==0 && pParse->nErr==0 ){
|
||||||
pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
|
pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg);
|
||||||
}
|
}
|
||||||
|
if( pTrigger->bReturning ){
|
||||||
|
sqlite3VdbeColumnInfoXfer(pParse->pVdbe, v);
|
||||||
|
}
|
||||||
pProgram->nMem = pSubParse->nMem;
|
pProgram->nMem = pSubParse->nMem;
|
||||||
pProgram->nCsr = pSubParse->nTab;
|
pProgram->nCsr = pSubParse->nTab;
|
||||||
pProgram->token = (void *)pTrigger;
|
pProgram->token = (void *)pTrigger;
|
||||||
|
@@ -259,6 +259,7 @@ void sqlite3VdbeResetStepResult(Vdbe*);
|
|||||||
void sqlite3VdbeRewind(Vdbe*);
|
void sqlite3VdbeRewind(Vdbe*);
|
||||||
int sqlite3VdbeReset(Vdbe*);
|
int sqlite3VdbeReset(Vdbe*);
|
||||||
void sqlite3VdbeSetNumCols(Vdbe*,int);
|
void sqlite3VdbeSetNumCols(Vdbe*,int);
|
||||||
|
void sqlite3VdbeColumnInfoXfer(Vdbe*,Vdbe*);
|
||||||
int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
|
int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*));
|
||||||
void sqlite3VdbeCountChanges(Vdbe*);
|
void sqlite3VdbeCountChanges(Vdbe*);
|
||||||
sqlite3 *sqlite3VdbeDb(Vdbe*);
|
sqlite3 *sqlite3VdbeDb(Vdbe*);
|
||||||
|
@@ -2595,6 +2595,20 @@ void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){
|
|||||||
initMemArray(p->aColName, n, db, MEM_Null);
|
initMemArray(p->aColName, n, db, MEM_Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Transfer the column count and name information from one Vdbe to
|
||||||
|
** another.
|
||||||
|
*/
|
||||||
|
void sqlite3VdbeColumnInfoXfer(Vdbe *pTo, Vdbe *pFrom){
|
||||||
|
sqlite3 *db = pTo->db;
|
||||||
|
assert( db==pFrom->db );
|
||||||
|
sqlite3DbFree(db, pTo->aColName);
|
||||||
|
pTo->aColName = pFrom->aColName;
|
||||||
|
pFrom->aColName = 0;
|
||||||
|
pTo->nResColumn = pFrom->nResColumn;
|
||||||
|
pFrom->nResColumn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Set the name of the idx'th column to be returned by the SQL statement.
|
** Set the name of the idx'th column to be returned by the SQL statement.
|
||||||
** zName must be a pointer to a nul terminated string.
|
** zName must be a pointer to a nul terminated string.
|
||||||
|
Reference in New Issue
Block a user