From: drh <> Date: Wed, 6 Apr 2022 15:41:53 +0000 (+0000) Subject: Attempt to show triggers in the TreeView output from DELETE, INSERT, and X-Git-Tag: version-3.39.0~236 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2a7dcbfbb0e6fcd255fda917d0f28a10588b7dd0;p=thirdparty%2Fsqlite.git Attempt to show triggers in the TreeView output from DELETE, INSERT, and UPDATE statements. FossilOrigin-Name: b0939d6f4d94b45dce53ace6295508a67d574cc72bd6977623bf77065b3c4e64 --- diff --git a/manifest b/manifest index 7e989d04ad..233a3a04fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Corrections\sand\supdates\sto\sthe\sheader\scomment\sdescribing\sthe\nTriggerStep\sobject.\s\sNo\schanges\sto\scode. -D 2022-04-06T12:54:41.675 +C Attempt\sto\sshow\striggers\sin\sthe\sTreeView\soutput\sfrom\sDELETE,\sINSERT,\sand\nUPDATE\sstatements. +D 2022-04-06T15:41:53.521 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -502,7 +502,7 @@ F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c a70be9a4879ac5392673a1050d526a72b8b2f9938df7049f65348566a2637db3 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d -F src/delete.c f9e765869d4eb1bb639df0d77a8eda36bf064e83d21777b1ea772cac66786df5 +F src/delete.c dafdc71a097f84fbbf66164d8842ebcb9bacf74e069658001fd70b62ee0acbdb F src/expr.c 3cdb00b6c15f815c94836e7b4474b675155d1279e64804f6ab5816188a9b05b6 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a @@ -512,7 +512,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 1e76792fef634bc84dfc79080e632fe5bf833fadb0777510785c6a8fc13e5e8c +F src/insert.c d97fc6f1824297bc3da8e54daa902d6a458cb941b17aaff891564ffa34845e4a F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c @@ -557,7 +557,7 @@ F src/shell.c.in 18832612e74c92bbd25d88e1f92685f66589262f68cca1001d2a43bd6dd0ed6 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 2cd3008975523038cf01ce77d3ec61c190466c5879aa3856fa79c2cb00e5240d +F src/sqliteInt.h e7b2a0a394629bb8d005bb1b64f5d34737ab4659f894cb1be0a322a2199873e3 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -617,9 +617,9 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 9f867920ef5a39659d034fc2e62c737240d9751a833b0a2b71058ee0304224bc +F src/treeview.c 4ed907fc341bbab963a31ffccd803e13af99eb89376de5cbd0418b1fba0c9ebf F src/trigger.c 8caa0baf1b18522863cf0fd611ef483962cfa50155ca82ad43e63b20f863a683 -F src/update.c c79e4ba491dbce7e0bd8995aeccbbf453843c763a0670c7a3414094610b0d71f +F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 @@ -1945,8 +1945,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bc33168cf1f48caf848c2dc5c3ae15e4efff8c0378f944eb5398a245139a2b35 -R 2e653a42f648804346ba4eb540aa80b7 +P abb34c0830a49d4f4e277ddd17e710529e87cba7061f3546079dbba2f82b020e +R 3b68aded646af44203f4f0b172b58b76 U drh -Z 6f432e2a1d80c3ecd80c5f978baed379 +Z c0df658f2ef079af39e2552d24158d31 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2d05530aef..bb2179135e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -abb34c0830a49d4f4e277ddd17e710529e87cba7061f3546079dbba2f82b020e \ No newline at end of file +b0939d6f4d94b45dce53ace6295508a67d574cc72bd6977623bf77065b3c4e64 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index ca3705f552..a4c5d53c58 100644 --- a/src/delete.c +++ b/src/delete.c @@ -300,13 +300,6 @@ void sqlite3DeleteFrom( assert( db->mallocFailed==0 ); assert( pTabList->nSrc==1 ); -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x10000 ){ - sqlite3TreeViewDelete(0, pParse->pWith, pTabList, pWhere, - pOrderBy, pLimit); - } -#endif - /* Locate the table which we want to delete. This table has to be ** put in an SrcList structure because some of the subroutines we ** will be calling are designed to work with multiple tables and expect @@ -331,6 +324,14 @@ void sqlite3DeleteFrom( # define isView 0 #endif +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Delete() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewDelete(pParse->pWith, pTabList, pWhere, + pOrderBy, pLimit, pTrigger); + } +#endif + #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT if( !isView ){ pWhere = sqlite3LimitWhere( diff --git a/src/insert.c b/src/insert.c index 9acddd4070..e56d037194 100644 --- a/src/insert.c +++ b/src/insert.c @@ -722,13 +722,6 @@ void sqlite3Insert( assert( db->mallocFailed==0 ); dest.iSDParm = 0; /* Suppress a harmless compiler warning */ -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x10000 ){ - sqlite3TreeViewInsert(0, pParse->pWith, pTabList, pColumn, pSelect, - onError, pUpsert); - } -#endif - /* If the Select object is really just a simple VALUES() list with a ** single row (the common case) then keep that one row of values ** and discard the other (unused) parts of the pSelect object @@ -772,6 +765,14 @@ void sqlite3Insert( #endif assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) ); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Insert() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewInsert(pParse->pWith, pTabList, pColumn, pSelect, + onError, pUpsert, pTrigger); + } +#endif + /* If pTab is really a view, make sure it has been initialized. ** ViewGetColumnNames() is a no-op if pTab is not a view. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 63d7c3286c..ef28573456 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4418,6 +4418,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #endif #if defined(SQLITE_DEBUG) + void sqlite3TreeViewLine(TreeView*, const char *zFormat, ...); void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); @@ -4427,14 +4428,18 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3TreeViewSelect(TreeView*, const Select*, u8); void sqlite3TreeViewWith(TreeView*, const With*, u8); void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); - void sqlite3TreeViewDelete(TreeView*, const With*, const SrcList*, - const Expr*,const ExprList*,const Expr*); - void sqlite3TreeViewInsert(TreeView*, const With*, const SrcList*, + void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*, + const ExprList*,const Expr*, const Trigger*); + void sqlite3TreeViewInsert(const With*, const SrcList*, const IdList*, const Select*, int, - const Upsert*); - void sqlite3TreeViewUpdate(TreeView*, const With*, const SrcList*, - const ExprList*, const Expr*, int, - const ExprList*, const Expr*, const Upsert*); + const Upsert*, const Trigger*); + void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*, + const Expr*, int, const ExprList*, const Expr*, + const Upsert*, const Trigger*); +#ifndef SQLITE_OMIT_TRIGGER + void sqlite3TreeViewTriggerStep(TreeView*, const TriggerStep*, u8, u8); + void sqlite3TreeViewTrigger(TreeView*, const Trigger*, u8, u8); +#endif #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3TreeViewWindow(TreeView*, const Window*, u8); void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); @@ -4446,6 +4451,12 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3ShowSelect(const Select*); void sqlite3ShowWith(const With*); void sqlite3ShowUpsert(const Upsert*); +#ifndef SQLITE_OMIT_TRIGGER + void sqlite3ShowTriggerStep(const TriggerStep*); + void sqlite3ShowTriggerStepList(const TriggerStep*); + void sqlite3ShowTrigger(const Trigger*); + void sqlite3ShowTriggerList(const Trigger*); +#endif #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3ShowWindow(const Window*); void sqlite3ShowWinFunc(const Window*); diff --git a/src/treeview.c b/src/treeview.c index e935c5bfa6..a63f94bfd5 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -24,33 +24,37 @@ ** Add a new subitem to the tree. The moreToFollow flag indicates that this ** is not the last item in the tree. */ -static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ +static void sqlite3TreeViewPush(TreeView **pp, u8 moreToFollow){ + TreeView *p = *pp; if( p==0 ){ - p = sqlite3_malloc64( sizeof(*p) ); - if( p==0 ) return 0; + *pp = p = sqlite3_malloc64( sizeof(*p) ); + if( p==0 ) return; memset(p, 0, sizeof(*p)); }else{ p->iLevel++; } assert( moreToFollow==0 || moreToFollow==1 ); if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow; - return p; } /* ** Finished with one layer of the tree */ -static void sqlite3TreeViewPop(TreeView *p){ +static void sqlite3TreeViewPop(TreeView **pp){ + TreeView *p = *pp; if( p==0 ) return; p->iLevel--; - if( p->iLevel<0 ) sqlite3_free(p); + if( p->iLevel<0 ){ + sqlite3_free(p); + *pp = 0; + } } /* ** Generate a single line of output for the tree, with a prefix that contains ** all the appropriate tree lines */ -static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ +void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ va_list ap; int i; StrAccum acc; @@ -78,7 +82,7 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ ** Shorthand for starting a new tree item that consists of a single label */ static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ - p = sqlite3TreeViewPush(p, moreFollows); + sqlite3TreeViewPush(&p, moreFollows); sqlite3TreeViewLine(p, "%s", zLabel); } @@ -95,7 +99,7 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith); } if( pWith->nCte>0 ){ - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); for(i=0; inCte; i++){ StrAccum x; char zLine[1000]; @@ -118,9 +122,9 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } } @@ -159,7 +163,7 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } } @@ -173,11 +177,11 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ sqlite3TreeViewLine(pView, "nil-SELECT"); return; } - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); if( p->pWith ){ sqlite3TreeViewWith(pView, p->pWith, 1); cnt = 1; - sqlite3TreeViewPush(pView, 1); + sqlite3TreeViewPush(&pView, 1); } do{ if( p->selFlags & SF_WhereBegin ){ @@ -191,7 +195,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ (int)p->nSelectRow ); } - if( cnt++ ) sqlite3TreeViewPop(pView); + if( cnt++ ) sqlite3TreeViewPop(&pView); if( p->pPrior ){ n = 1000; }else{ @@ -214,24 +218,24 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWin ){ Window *pX; - pView = sqlite3TreeViewPush(pView, (n--)>0); + sqlite3TreeViewPush(&pView, (n--)>0); sqlite3TreeViewLine(pView, "window-functions"); for(pX=p->pWin; pX; pX=pX->pNextWin){ sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #endif if( p->pSrc && p->pSrc->nSrc ){ - pView = sqlite3TreeViewPush(pView, (n--)>0); + sqlite3TreeViewPush(&pView, (n--)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, p->pSrc); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( p->pWhere ){ sqlite3TreeViewItem(pView, "WHERE", (n--)>0); sqlite3TreeViewExpr(pView, p->pWhere, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( p->pGroupBy ){ sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY"); @@ -239,7 +243,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ if( p->pHaving ){ sqlite3TreeViewItem(pView, "HAVING", (n--)>0); sqlite3TreeViewExpr(pView, p->pHaving, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWinDefn ){ @@ -248,7 +252,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ for(pX=p->pWinDefn; pX; pX=pX->pNextWin){ sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #endif if( p->pOrderBy ){ @@ -260,9 +264,9 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ if( p->pLimit->pRight ){ sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( p->pPrior ){ const char *zOp = "UNION"; @@ -275,7 +279,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ } p = p->pPrior; }while( p!=0 ); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #ifndef SQLITE_OMIT_WINDOWFUNC @@ -291,24 +295,24 @@ void sqlite3TreeViewBound( switch( eBound ){ case TK_UNBOUNDED: { sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); break; } case TK_CURRENT: { sqlite3TreeViewItem(pView, "CURRENT", moreToFollow); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); break; } case TK_PRECEDING: { sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow); sqlite3TreeViewExpr(pView, pExpr, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); break; } case TK_FOLLOWING: { sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow); sqlite3TreeViewExpr(pView, pExpr, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); break; } } @@ -324,9 +328,9 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ if( pWin->pFilter ){ sqlite3TreeViewItem(pView, "FILTER", 1); sqlite3TreeViewExpr(pView, pWin->pFilter, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } - pView = sqlite3TreeViewPush(pView, more); + sqlite3TreeViewPush(&pView, more); if( pWin->zName ){ sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin); }else{ @@ -337,9 +341,9 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ if( pWin->eFrmType ) nElement++; if( pWin->eExclude ) nElement++; if( pWin->zBase ){ - sqlite3TreeViewPush(pView, (--nElement)>0); + sqlite3TreeViewPush(&pView, (--nElement)>0); sqlite3TreeViewLine(pView, "window: %s", pWin->zBase); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pWin->pPartition ){ sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY"); @@ -357,7 +361,7 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ sqlite3TreeViewItem(pView, zBuf, (--nElement)>0); sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1); sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pWin->eExclude ){ char zBuf[30]; @@ -372,11 +376,11 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ zExclude = zBuf; break; } - sqlite3TreeViewPush(pView, 0); + sqlite3TreeViewPush(&pView, 0); sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #endif /* SQLITE_OMIT_WINDOWFUNC */ @@ -385,11 +389,11 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ ** Generate a human-readable explanation for a Window Function object */ void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ - pView = sqlite3TreeViewPush(pView, more); + sqlite3TreeViewPush(&pView, more); sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", pWin->pWFunc->zName, pWin->pWFunc->nArg); sqlite3TreeViewWindow(pView, pWin, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #endif /* SQLITE_OMIT_WINDOWFUNC */ @@ -400,10 +404,10 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ const char *zBinOp = 0; /* Binary operator */ const char *zUniOp = 0; /* Unary operator */ char zFlgs[200]; - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); if( pExpr==0 ){ sqlite3TreeViewLine(pView, "nil"); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); return; } if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){ @@ -760,7 +764,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } @@ -784,7 +788,7 @@ void sqlite3TreeViewBareExprList( int moreToFollow = inExpr - 1; if( pList->a[i].eEName!=ENAME_NAME ) zName = 0; if( j || zName ){ - sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); moreToFollow = 0; sqlite3TreeViewLine(pView, 0); if( zName ){ @@ -798,7 +802,7 @@ void sqlite3TreeViewBareExprList( } sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); if( j || zName ){ - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } } } @@ -809,9 +813,9 @@ void sqlite3TreeViewExprList( u8 moreToFollow, const char *zLabel ){ - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); sqlite3TreeViewBareExprList(pView, pList, zLabel); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } /* @@ -832,11 +836,11 @@ void sqlite3TreeViewBareIdList( char *zName = pList->a[i].zName; int moreToFollow = inId - 1; if( zName==0 ) zName = "(null)"; - sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); moreToFollow = 0; sqlite3TreeViewLine(pView, 0); fprintf(stdout, "%s (%d)\n", zName, pList->a[i].idx); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } } } @@ -846,9 +850,9 @@ void sqlite3TreeViewIdList( u8 moreToFollow, const char *zLabel ){ - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); sqlite3TreeViewBareIdList(pView, pList, zLabel); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } /* @@ -860,10 +864,10 @@ void sqlite3TreeViewUpsert( u8 moreToFollow ){ if( pUpsert==0 ) return; - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); while( pUpsert ){ int n; - sqlite3TreeViewPush(pView, pUpsert->pNextUpsert!=0 || moreToFollow); + sqlite3TreeViewPush(&pView, pUpsert->pNextUpsert!=0 || moreToFollow); sqlite3TreeViewLine(pView, "ON CONFLICT DO %s", pUpsert->isDoUpdate ? "UPDATE" : "NOTHING"); n = (pUpsert->pUpsertSet!=0) + (pUpsert->pUpsertWhere!=0); @@ -872,12 +876,12 @@ void sqlite3TreeViewUpsert( if( pUpsert->pUpsertWhere ){ sqlite3TreeViewItem(pView, "WHERE", (n--)>0); sqlite3TreeViewExpr(pView, pUpsert->pUpsertWhere, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); pUpsert = pUpsert->pNextUpsert; } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } /* @@ -885,47 +889,53 @@ void sqlite3TreeViewUpsert( ** into generating an DELETE statement. */ void sqlite3TreeViewDelete( - TreeView *pView, const With *pWith, const SrcList *pTabList, const Expr *pWhere, const ExprList *pOrderBy, - const Expr *pLimit + const Expr *pLimit, + const Trigger *pTrigger ){ int n = 0; + TreeView *pView = 0; + sqlite3TreeViewPush(&pView, 0); sqlite3TreeViewLine(pView, "DELETE"); - pView = sqlite3TreeViewPush(pView, 0); if( pWith ) n++; if( pTabList ) n++; if( pWhere ) n++; if( pOrderBy ) n++; if( pLimit ) n++; + if( pTrigger ) n++; if( pWith ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewWith(pView, pWith, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pTabList ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, pTabList); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pWhere ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "WHERE"); sqlite3TreeViewExpr(pView, pWhere, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pOrderBy ){ sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); } if( pLimit ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "LIMIT"); sqlite3TreeViewExpr(pView, pLimit, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); + } + sqlite3TreeViewPop(&pView); } /* @@ -933,14 +943,15 @@ void sqlite3TreeViewDelete( ** into generating an INSERT statement. */ void sqlite3TreeViewInsert( - TreeView *pView, const With *pWith, const SrcList *pTabList, const IdList *pColumnList, const Select *pSelect, int onError, - const Upsert *pUpsert + const Upsert *pUpsert, + const Trigger *pTrigger ){ + TreeView *pView = 0; int n = 0; const char *zLabel = "INSERT"; switch( onError ){ @@ -950,39 +961,44 @@ void sqlite3TreeViewInsert( case OE_Abort: zLabel = "INSERT OR ABORT"; break; case OE_Fail: zLabel = "INSERT OR FAIL"; break; } + sqlite3TreeViewPush(&pView, 0); sqlite3TreeViewLine(pView, zLabel); - pView = sqlite3TreeViewPush(pView, 0); if( pWith ) n++; if( pTabList ) n++; if( pColumnList ) n++; if( pSelect ) n++; if( pUpsert ) n++; + if( pTrigger ) n++; if( pWith ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewWith(pView, pWith, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pTabList ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "INTO"); sqlite3TreeViewSrcList(pView, pTabList); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pColumnList ){ sqlite3TreeViewIdList(pView, pColumnList, (--n)>0, "COLUMNS"); } if( pSelect ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "DATA-SOURCE"); sqlite3TreeViewSelect(pView, pSelect, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pUpsert ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "UPSERT"); sqlite3TreeViewUpsert(pView, pUpsert, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); + } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); } + sqlite3TreeViewPop(&pView); } /* @@ -990,7 +1006,6 @@ void sqlite3TreeViewInsert( ** into generating an UPDATE statement. */ void sqlite3TreeViewUpdate( - TreeView *pView, const With *pWith, const SrcList *pTabList, const ExprList *pChanges, @@ -998,9 +1013,11 @@ void sqlite3TreeViewUpdate( int onError, const ExprList *pOrderBy, const Expr *pLimit, - const Upsert *pUpsert + const Upsert *pUpsert, + const Trigger *pTrigger ){ int n = 0; + TreeView *pView = 0; const char *zLabel = "UPDATE"; switch( onError ){ case OE_Replace: zLabel = "UPDATE OR REPLACE"; break; @@ -1009,8 +1026,8 @@ void sqlite3TreeViewUpdate( case OE_Abort: zLabel = "UPDATE OR ABORT"; break; case OE_Fail: zLabel = "UPDATE OR FAIL"; break; } + sqlite3TreeViewPush(&pView, 0); sqlite3TreeViewLine(pView, zLabel); - pView = sqlite3TreeViewPush(pView, 0); if( pWith ) n++; if( pTabList ) n++; if( pChanges ) n++; @@ -1018,42 +1035,99 @@ void sqlite3TreeViewUpdate( if( pOrderBy ) n++; if( pLimit ) n++; if( pUpsert ) n++; + if( pTrigger ) n++; if( pWith ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewWith(pView, pWith, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pTabList ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, pTabList); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pChanges ){ sqlite3TreeViewExprList(pView, pChanges, (--n)>0, "SET"); } if( pWhere ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "WHERE"); sqlite3TreeViewExpr(pView, pWhere, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pOrderBy ){ sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); } if( pLimit ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "LIMIT"); sqlite3TreeViewExpr(pView, pLimit, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pUpsert ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "UPSERT"); sqlite3TreeViewUpsert(pView, pUpsert, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); + } + sqlite3TreeViewPop(&pView); +} + +#ifndef SQLITE_OMIT_TRIGGER +/* +** Show a human-readable graph of a TriggerStep +*/ +void sqlite3TreeViewTriggerStep( + TreeView *pView, + const TriggerStep *pStep, + u8 moreToFollow, + u8 showFullList +){ + int cnt = 0; + if( pStep==0 ) return; + sqlite3TreeViewPush(&pView, + moreToFollow || (showFullList && pStep->pNext!=0)); + do{ + if( cnt++ && pStep->pNext==0 ){ + sqlite3TreeViewPop(&pView); + sqlite3TreeViewPush(&pView, 0); + } + sqlite3TreeViewLine(pView, "%s", pStep->zSpan ? pStep->zSpan : "RETURNING"); + }while( showFullList && (pStep = pStep->pNext)!=0 ); + sqlite3TreeViewPop(&pView); } + +/* +** Show a human-readable graph of a Trigger +*/ +void sqlite3TreeViewTrigger( + TreeView *pView, + const Trigger *pTrigger, + u8 moreToFollow, + u8 showFullList +){ + int cnt = 0; + if( pTrigger==0 ) return; + sqlite3TreeViewPush(&pView, + moreToFollow || (showFullList && pTrigger->pNext!=0)); + do{ + if( cnt++ && pTrigger->pNext==0 ){ + sqlite3TreeViewPop(&pView); + sqlite3TreeViewPush(&pView, 0); + } + sqlite3TreeViewLine(pView, "TRIGGER %s", pTrigger->zName); + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewTriggerStep(pView, pTrigger->step_list, 0, 1); + sqlite3TreeViewPop(&pView); + }while( showFullList && (pTrigger = pTrigger->pNext)!=0 ); + sqlite3TreeViewPop(&pView); +} +#endif /* SQLITE_OMIT_TRIGGER */ + /* ** These simplified versions of the tree-view routines omit unnecessary @@ -1072,6 +1146,16 @@ void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); } void sqlite3ShowSelect(const Select *p){ sqlite3TreeViewSelect(0,p,0); } void sqlite3ShowWith(const With *p){ sqlite3TreeViewWith(0,p,0); } void sqlite3ShowUpsert(const Upsert *p){ sqlite3TreeViewUpsert(0,p,0); } +#ifndef SQLITE_OMIT_TRIGGER +void sqlite3ShowTriggerStep(const TriggerStep *p){ + sqlite3TreeViewTriggerStep(0,p,0,0); +} +void sqlite3ShowTriggerStepList(const TriggerStep *p){ + sqlite3TreeViewTriggerStep(0,p,0,1); +} +void sqlite3ShowTrigger(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,0); } +void sqlite3ShowTriggerList(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,1);} +#endif #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3ShowWindow(const Window *p){ sqlite3TreeViewWindow(0,p,0); } void sqlite3ShowWinFunc(const Window *p){ sqlite3TreeViewWinFunc(0,p,0); } diff --git a/src/update.c b/src/update.c index 908fc3ad6d..6547041472 100644 --- a/src/update.c +++ b/src/update.c @@ -353,13 +353,6 @@ void sqlite3Update( } assert( db->mallocFailed==0 ); -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x10000 ){ - sqlite3TreeViewUpdate(0, pParse->pWith, pTabList, pChanges, pWhere, - onError, pOrderBy, pLimit, pUpsert); - } -#endif - /* Locate the table which we want to update. */ pTab = sqlite3SrcListLookup(pParse, pTabList); @@ -383,6 +376,14 @@ void sqlite3Update( # define isView 0 #endif +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Update() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewUpdate(pParse->pWith, pTabList, pChanges, pWhere, + onError, pOrderBy, pLimit, pUpsert, pTrigger); + } +#endif + /* If there was a FROM clause, set nChangeFrom to the number of expressions ** in the change-list. Otherwise, set it to 0. There cannot be a FROM ** clause if this function is being called to generate code for part of