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

Edit the WHEN and UPDATE OF clauses of trigger programs as part of ALTER TABLE

RENAME COLUMN.

FossilOrigin-Name: 5fdb6b0aafba727139e1937ef5950e4434a77f95a10fc46f8010ca2de3922326
This commit is contained in:
dan
2018-08-13 17:14:26 +00:00
parent 4a2c747c4c
commit 5496d6a25a
9 changed files with 127 additions and 61 deletions

View File

@@ -1,5 +1,5 @@
C Fix\slegacy\scomments\son\sToken.\s\sBegin\scommenting\sthe\snew\sALTER\sTABLE\sRENAME\nCOLUMN\scode.\s\sFix\sa\smemory\sleak\sin\sthe\ssqlite_rename_column()\sSQL\sfunction. C Edit\sthe\sWHEN\sand\sUPDATE\sOF\sclauses\sof\strigger\sprograms\sas\spart\sof\sALTER\sTABLE\nRENAME\sCOLUMN.
D 2018-08-13T15:09:48.567 D 2018-08-13T17:14:26.913
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 Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6 F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6
@@ -432,7 +432,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 7a8e8f14b07063973b772b07921bcc54db36e26e8aae14d2584446ed5af9e513 F src/alter.c 9f8231841d00ef09d328ecb39af46e0cd85ce4e39d416319d458f8aff7af10dd
F src/analyze.c 3dc6b98cf007b005af89df165c966baaa48e8124f38c87b4d2b276fe7f0b9eb9 F src/analyze.c 3dc6b98cf007b005af89df165c966baaa48e8124f38c87b4d2b276fe7f0b9eb9
F src/attach.c 4bd5b92633671d3e8ce431153ebb1893b50335818423b5373f3f27969f79769a F src/attach.c 4bd5b92633671d3e8ce431153ebb1893b50335818423b5373f3f27969f79769a
F src/auth.c 32a5bbe3b755169ab6c66311c5225a3cd4f75a46c041f7fb117e0cbb68055114 F src/auth.c 32a5bbe3b755169ab6c66311c5225a3cd4f75a46c041f7fb117e0cbb68055114
@@ -442,7 +442,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
F src/btree.c 3f5e1a03db871e627bf5da21092bf7434ecfc5c5980bbd7d45eba13341340173 F src/btree.c 3f5e1a03db871e627bf5da21092bf7434ecfc5c5980bbd7d45eba13341340173
F src/btree.h febb2e817be499570b7a2e32a9bbb4b607a9234f6b84bb9ae84916d4806e96f2 F src/btree.h febb2e817be499570b7a2e32a9bbb4b607a9234f6b84bb9ae84916d4806e96f2
F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
F src/build.c a8e71a3cf77ddf953a85d9d2d4c7fbc0a0f70ef4e4515915ad6ff1cdff9c9808 F src/build.c 49cad074fcc2218f45e126375b4d8f7c3960d2fe2c3398bad862e1bfd640d7c4
F src/callback.c 36caff1e7eb7deb58572d59c41cee8f064a11d00297616995c5050ea0cfc1288 F src/callback.c 36caff1e7eb7deb58572d59c41cee8f064a11d00297616995c5050ea0cfc1288
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c b157b01081f92442f8b0218ddb93ddce8ebddad36dbddeecfdd771561dd4f387 F src/ctime.c b157b01081f92442f8b0218ddb93ddce8ebddad36dbddeecfdd771561dd4f387
@@ -487,7 +487,7 @@ F src/os_win.c 070cdbb400097c6cda54aa005356095afdc2f3ee691d17192c54724ef146a971
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 76d29b8a960dcb8b67210f095899d91e4a90673a6674ea58cfd1115b705a7fb9 F src/pager.c 76d29b8a960dcb8b67210f095899d91e4a90673a6674ea58cfd1115b705a7fb9
F src/pager.h c571b064df842ec8f2e90855dead9acf4cbe0d1b2c05afe0ef0d0145f7fd0388 F src/pager.h c571b064df842ec8f2e90855dead9acf4cbe0d1b2c05afe0ef0d0145f7fd0388
F src/parse.y 035b397bf1acbd3cb8293812b07c8aefce9f275d4de1442e113dbd0d2f733dce F src/parse.y 1cdfb5179649b0cde2459d0e76b5acb7007bb10f4744ae804b2326ed98c52060
F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd
F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170 F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880 F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
@@ -503,7 +503,7 @@ F src/shell.c.in 6e0aad854be738a5d0368940459399be211e9ac43aebe92bb9ed46cfe38d0e1
F src/sqlite.h.in c6451bb876adced3aba5b1682c6317d215c5eceaba21a6ce979e71a0b8d0bf95 F src/sqlite.h.in c6451bb876adced3aba5b1682c6317d215c5eceaba21a6ce979e71a0b8d0bf95
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7 F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7
F src/sqliteInt.h 6cce5956d82972f3e03444c15636222e97938eb9f3dad399df038052c51a04a6 F src/sqliteInt.h 6a5d65117068808e2f37035d97a4cea6d55d679e02f9673b2b71ae6d5a0b1c8d
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -561,9 +561,9 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9
F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c 3177575b587f3d0491ca5c3e937663ca3e91bf86adf4f2e8e9f7d0ab98bc66d3 F src/tokenize.c fe35cb947ec54fe9a96895359b777a9305356c2f3c2917a1d83a57603108e66c
F src/treeview.c e7a7f90552bb418533cdd0309b5eb71d4effa50165b880fc8c2001e613577e5f F src/treeview.c e7a7f90552bb418533cdd0309b5eb71d4effa50165b880fc8c2001e613577e5f
F src/trigger.c 4ace6d1d5ba9a89822deb287317f33c810440526eafe185c2d8a48c31df1e995 F src/trigger.c f3ba315cd590a3db88fdfd259c8084e567746f6e0614efb3c806b205d7122276
F src/update.c 345ce35eb1332eb4829857aa8b1f65a614b07dae91d0346c0dc2baacafbcc51b F src/update.c 345ce35eb1332eb4829857aa8b1f65a614b07dae91d0346c0dc2baacafbcc51b
F src/upsert.c 47edd408cc73f8d3c00a140550d1ad180b407c146285947969dd09874802bf88 F src/upsert.c 47edd408cc73f8d3c00a140550d1ad180b407c146285947969dd09874802bf88
F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
@@ -599,7 +599,7 @@ F test/alter.test b820ab9dcf85f8e3a65bc8326accb2f0c7be64ef
F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060 F test/alter2.test 7ea05c7d92ac99349a802ef7ada17294dd647060
F test/alter3.test 4d79934d812eaeacc6f22781a080f8cfe012fdc3 F test/alter3.test 4d79934d812eaeacc6f22781a080f8cfe012fdc3
F test/alter4.test b6d7b86860111864f6cddb54af313f5862dda23b F test/alter4.test b6d7b86860111864f6cddb54af313f5862dda23b
F test/altercol.test a64f69f67a8ac2ab7fd671b3166ad3454e0fea6bf8c22fdc3630a4b0cdeb57e8 F test/altercol.test b3263a3d663e57e35fcd888614cb2256df42ac1be07d40282c5c6023a47a431b
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test b3a9c67d00e1df7588a5b7be9a0292899f94fe8cac1f94a017277474ca2e59df F test/analyze.test b3a9c67d00e1df7588a5b7be9a0292899f94fe8cac1f94a017277474ca2e59df
@@ -1756,7 +1756,11 @@ 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 0b28dd5c2e4908d5e49eaedd359492e46de8af3bf84120f4683b3ea906882fbf P 32edc8920376aabb84ebe1900eaa9512d23f1b44d6459e4916dc6b07db66e27c
R 8e4aad63439996e323e3c103c6b55b1d R 4f99214f849ec616e294c625bebc2173
U drh T *branch * edit-trigger-wrapper
Z 82791a60e4da34a95b2d48254121d988 T *sym-edit-trigger-wrapper *
T +closed 43c3d2d707a7c54dcb75660be9347d6bd79c4844f81f6ed73446570876f5f72b
T -sym-alter-table-rename-column *
U dan
Z e89da0f8ef0add6d1c95dbb889527ec9

View File

@@ -1 +1 @@
32edc8920376aabb84ebe1900eaa9512d23f1b44d6459e4916dc6b07db66e27c 5fdb6b0aafba727139e1937ef5950e4434a77f95a10fc46f8010ca2de3922326

View File

@@ -846,7 +846,7 @@ void sqlite3AlterRenameColumn(
"UPDATE \"%w\".%s SET " "UPDATE \"%w\".%s SET "
"sql = sqlite_rename_column(sql, %d, %d, %Q, %Q, %Q) " "sql = sqlite_rename_column(sql, %d, %d, %Q, %Q, %Q) "
"WHERE name NOT LIKE 'sqlite_%%' AND (" "WHERE name NOT LIKE 'sqlite_%%' AND ("
" type = 'table' OR (type='index' AND tbl_name = %Q)" " type = 'table' OR (type IN ('index', 'trigger') AND tbl_name = %Q)"
")", ")",
zDb, MASTER_NAME, iCol, bQuote, zNew, pTab->zName, zOld, pTab->zName zDb, MASTER_NAME, iCol, bQuote, zNew, pTab->zName, zOld, pTab->zName
); );
@@ -891,10 +891,12 @@ struct RenameToken {
** The context of an ALTER TABLE RENAME COLUMN operation that gets passed ** The context of an ALTER TABLE RENAME COLUMN operation that gets passed
** down into the Walker. ** down into the Walker.
*/ */
typedef struct RenameCtx RenameCtx;
struct RenameCtx { struct RenameCtx {
RenameToken *pList; /* List of tokens to overwrite */ RenameToken *pList; /* List of tokens to overwrite */
int nList; /* Number of tokens in pList */ int nList; /* Number of tokens in pList */
int iCol; /* Index of column being renamed */ int iCol; /* Index of column being renamed */
const char *zOld; /* Old column name */
}; };
/* /*
@@ -940,33 +942,40 @@ static void renameTokenFree(sqlite3 *db, RenameToken *pToken){
} }
} }
static RenameToken *renameTokenFind(Parse *pParse, void *pPtr){ static void renameTokenFind(Parse *pParse, RenameCtx *pCtx, void *pPtr){
RenameToken **pp; RenameToken **pp;
for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){
if( (*pp)->p==pPtr ){ if( (*pp)->p==pPtr ){
RenameToken *pToken = *pp; RenameToken *pToken = *pp;
*pp = pToken->pNext; *pp = pToken->pNext;
pToken->pNext = 0; pToken->pNext = pCtx->pList;
return pToken; pCtx->pList = pToken;
pCtx->nList++;
break;
} }
} }
return 0;
} }
static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){ static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){
struct RenameCtx *p = pWalker->u.pRename; RenameCtx *p = pWalker->u.pRename;
if( pExpr->op==TK_COLUMN && pExpr->iColumn==p->iCol ){ if( p->zOld && pExpr->op==TK_DOT ){
RenameToken *pTok = renameTokenFind(pWalker->pParse, (void*)pExpr); Expr *pLeft = pExpr->pLeft;
if( pTok ){ Expr *pRight = pExpr->pRight;
pTok->pNext = p->pList; assert( pLeft->op==TK_ID && pRight->op==TK_ID );
p->pList = pTok; if( 0==sqlite3_stricmp(pLeft->u.zToken, "old")
p->nList++; || 0==sqlite3_stricmp(pLeft->u.zToken, "new")
){
if( 0==sqlite3_stricmp(pRight->u.zToken, p->zOld) ){
renameTokenFind(pWalker->pParse, p, (void*)pRight);
} }
} }
}else if( pExpr->op==TK_COLUMN && pExpr->iColumn==p->iCol ){
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
}
return WRC_Continue; return WRC_Continue;
} }
static RenameToken *renameColumnTokenNext(struct RenameCtx *pCtx){ static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){
RenameToken *pBest = pCtx->pList; RenameToken *pBest = pCtx->pList;
RenameToken *pToken; RenameToken *pToken;
RenameToken **pp; RenameToken **pp;
@@ -989,7 +998,7 @@ static void renameColumnFunc(
sqlite3_value **argv sqlite3_value **argv
){ ){
sqlite3 *db = sqlite3_context_db_handle(context); sqlite3 *db = sqlite3_context_db_handle(context);
struct RenameCtx sCtx; RenameCtx sCtx;
const char *zSql = (const char*)sqlite3_value_text(argv[0]); const char *zSql = (const char*)sqlite3_value_text(argv[0]);
int nSql = sqlite3_value_bytes(argv[0]); int nSql = sqlite3_value_bytes(argv[0]);
int bQuote = sqlite3_value_int(argv[2]); int bQuote = sqlite3_value_int(argv[2]);
@@ -1019,7 +1028,9 @@ static void renameColumnFunc(
rc = sqlite3RunParser(&sParse, zSql, &zErr); rc = sqlite3RunParser(&sParse, zSql, &zErr);
assert( sParse.pNewTable==0 || sParse.pNewIndex==0 ); assert( sParse.pNewTable==0 || sParse.pNewIndex==0 );
if( db->mallocFailed ) rc = SQLITE_NOMEM; if( db->mallocFailed ) rc = SQLITE_NOMEM;
if( rc==SQLITE_OK && sParse.pNewTable==0 && sParse.pNewIndex==0 ){ if( rc==SQLITE_OK
&& sParse.pNewTable==0 && sParse.pNewIndex==0 && sParse.pNewTrigger==0
){
rc = SQLITE_CORRUPT_BKPT; rc = SQLITE_CORRUPT_BKPT;
} }
@@ -1067,10 +1078,9 @@ static void renameColumnFunc(
int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName);
FKey *pFKey; FKey *pFKey;
if( bFKOnly==0 ){ if( bFKOnly==0 ){
sCtx.pList = renameTokenFind( renameTokenFind(
&sParse, (void*)sParse.pNewTable->aCol[sCtx.iCol].zName &sParse, &sCtx, (void*)sParse.pNewTable->aCol[sCtx.iCol].zName
); );
sCtx.nList = 1;
assert( sCtx.iCol>=0 ); assert( sCtx.iCol>=0 );
if( sParse.pNewTable->iPKey==sCtx.iCol ){ if( sParse.pNewTable->iPKey==sCtx.iCol ){
sCtx.iCol = -1; sCtx.iCol = -1;
@@ -1083,28 +1093,30 @@ static void renameColumnFunc(
for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){
for(i=0; i<pFKey->nCol; i++){ for(i=0; i<pFKey->nCol; i++){
RenameToken *pTok = 0;
if( bFKOnly==0 && pFKey->aCol[i].iFrom==sCtx.iCol ){ if( bFKOnly==0 && pFKey->aCol[i].iFrom==sCtx.iCol ){
pTok = renameTokenFind(&sParse, (void*)&pFKey->aCol[i]); renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]);
if( pTok ){
pTok->pNext = sCtx.pList;
sCtx.pList = pTok;
sCtx.nList++;
}
} }
if( 0==sqlite3_stricmp(pFKey->zTo, zTable) if( 0==sqlite3_stricmp(pFKey->zTo, zTable)
&& 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld) && 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld)
){ ){
pTok = renameTokenFind(&sParse, (void*)pFKey->aCol[i].zCol); renameTokenFind(&sParse, &sCtx, (void*)pFKey->aCol[i].zCol);
pTok->pNext = sCtx.pList;
sCtx.pList = pTok;
sCtx.nList++;
} }
} }
} }
}else{ }else if( sParse.pNewIndex ){
sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr);
sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere);
}else{
sCtx.zOld = zOld;
sqlite3WalkExpr(&sWalker, sParse.pNewTrigger->pWhen);
if( sParse.pNewTrigger->pColumns ){
for(i=0; i<sParse.pNewTrigger->pColumns->nId; i++){
char *zName = sParse.pNewTrigger->pColumns->a[i].zName;
if( 0==sqlite3_stricmp(zName, zOld) ){
renameTokenFind(&sParse, &sCtx, (void*)zName);
}
}
}
} }
assert( nQuot>=nNew ); assert( nQuot>=nNew );
@@ -1148,6 +1160,7 @@ renameColumnFunc_done:
} }
sqlite3DeleteTable(db, sParse.pNewTable); sqlite3DeleteTable(db, sParse.pNewTable);
if( sParse.pNewIndex ) sqlite3FreeIndex(db, sParse.pNewIndex); if( sParse.pNewIndex ) sqlite3FreeIndex(db, sParse.pNewIndex);
sqlite3DeleteTrigger(db, sParse.pNewTrigger);
renameTokenFree(db, sParse.pRename); renameTokenFree(db, sParse.pRename);
renameTokenFree(db, sCtx.pList); renameTokenFree(db, sCtx.pList);
sqlite3ParserReset(&sParse); sqlite3ParserReset(&sParse);

View File

@@ -3686,7 +3686,8 @@ void *sqlite3ArrayAllocate(
** **
** A new IdList is returned, or NULL if malloc() fails. ** A new IdList is returned, or NULL if malloc() fails.
*/ */
IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){ IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){
sqlite3 *db = pParse->db;
int i; int i;
if( pList==0 ){ if( pList==0 ){
pList = sqlite3DbMallocZero(db, sizeof(IdList) ); pList = sqlite3DbMallocZero(db, sizeof(IdList) );
@@ -3704,6 +3705,9 @@ IdList *sqlite3IdListAppend(sqlite3 *db, IdList *pList, Token *pToken){
return 0; return 0;
} }
pList->a[i].zName = sqlite3NameFromToken(db, pToken); pList->a[i].zName = sqlite3NameFromToken(db, pToken);
if( IN_RENAME_COLUMN && pList->a[i].zName ){
sqlite3RenameToken(pParse, (void*)pList->a[i].zName, pToken);
}
return pList; return pList;
} }

View File

@@ -908,9 +908,9 @@ insert_cmd(A) ::= REPLACE. {A = OE_Replace;}
idlist_opt(A) ::= . {A = 0;} idlist_opt(A) ::= . {A = 0;}
idlist_opt(A) ::= LP idlist(X) RP. {A = X;} idlist_opt(A) ::= LP idlist(X) RP. {A = X;}
idlist(A) ::= idlist(A) COMMA nm(Y). idlist(A) ::= idlist(A) COMMA nm(Y).
{A = sqlite3IdListAppend(pParse->db,A,&Y);} {A = sqlite3IdListAppend(pParse,A,&Y);}
idlist(A) ::= nm(Y). idlist(A) ::= nm(Y).
{A = sqlite3IdListAppend(pParse->db,0,&Y); /*A-overwrites-Y*/} {A = sqlite3IdListAppend(pParse,0,&Y); /*A-overwrites-Y*/}
/////////////////////////// Expression Processing ///////////////////////////// /////////////////////////// Expression Processing /////////////////////////////
// //

View File

@@ -3881,7 +3881,7 @@ void sqlite3FreeIndex(sqlite3*, Index*);
#endif #endif
void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*); void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*);
void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); IdList *sqlite3IdListAppend(Parse*, IdList*, Token*);
int sqlite3IdListIndex(IdList*,const char*); int sqlite3IdListIndex(IdList*,const char*);
SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int); SrcList *sqlite3SrcListEnlarge(sqlite3*, SrcList*, int, int);
SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*); SrcList *sqlite3SrcListAppend(sqlite3*, SrcList*, Token*, Token*);

View File

@@ -697,9 +697,11 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
*/ */
sqlite3DeleteTable(db, pParse->pNewTable); sqlite3DeleteTable(db, pParse->pNewTable);
} }
if( !IN_RENAME_COLUMN ){
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
}
if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree);
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
sqlite3DbFree(db, pParse->pVList); sqlite3DbFree(db, pParse->pVList);
while( pParse->pAinc ){ while( pParse->pAinc ){
AutoincInfo *p = pParse->pAinc; AutoincInfo *p = pParse->pAinc;

View File

@@ -181,6 +181,7 @@ void sqlite3BeginTrigger(
goto trigger_cleanup; goto trigger_cleanup;
} }
assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
if( !IN_RENAME_COLUMN ){
if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
if( !noErr ){ if( !noErr ){
sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
@@ -190,6 +191,7 @@ void sqlite3BeginTrigger(
} }
goto trigger_cleanup; goto trigger_cleanup;
} }
}
/* Do not create a trigger on a system table */ /* Do not create a trigger on a system table */
if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
@@ -212,7 +214,7 @@ void sqlite3BeginTrigger(
} }
#ifndef SQLITE_OMIT_AUTHORIZATION #ifndef SQLITE_OMIT_AUTHORIZATION
{ if( !IN_RENAME_COLUMN ){
int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
int code = SQLITE_CREATE_TRIGGER; int code = SQLITE_CREATE_TRIGGER;
const char *zDb = db->aDb[iTabDb].zDbSName; const char *zDb = db->aDb[iTabDb].zDbSName;
@@ -246,8 +248,14 @@ void sqlite3BeginTrigger(
pTrigger->pTabSchema = pTab->pSchema; pTrigger->pTabSchema = pTab->pSchema;
pTrigger->op = (u8)op; pTrigger->op = (u8)op;
pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER;
if( IN_RENAME_COLUMN ){
pTrigger->pWhen = pWhen;
pWhen = 0;
}else{
pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE);
pTrigger->pColumns = sqlite3IdListDup(db, pColumns); }
pTrigger->pColumns = pColumns;
pColumns = 0;
assert( pParse->pNewTrigger==0 ); assert( pParse->pNewTrigger==0 );
pParse->pNewTrigger = pTrigger; pParse->pNewTrigger = pTrigger;
@@ -296,6 +304,14 @@ void sqlite3FinishTrigger(
goto triggerfinish_cleanup; goto triggerfinish_cleanup;
} }
#ifndef SQLITE_OMIT_ALTERTABLE
if( IN_RENAME_COLUMN ){
assert( !db->init.busy );
pParse->pNewTrigger = pTrig;
pTrig = 0;
}else
#endif
/* if we are not initializing, /* if we are not initializing,
** build the sqlite_master entry ** build the sqlite_master entry
*/ */
@@ -337,7 +353,7 @@ void sqlite3FinishTrigger(
triggerfinish_cleanup: triggerfinish_cleanup:
sqlite3DeleteTrigger(db, pTrig); sqlite3DeleteTrigger(db, pTrig);
assert( !pParse->pNewTrigger ); assert( IN_RENAME_COLUMN || !pParse->pNewTrigger );
sqlite3DeleteTriggerStep(db, pStepList); sqlite3DeleteTriggerStep(db, pStepList);
} }

View File

@@ -130,7 +130,7 @@ do_execsql_test 3.2 {
SELECT * FROM t4; SELECT * FROM t4;
} {3 2 1} } {3 2 1}
# do_execsql_test 3.3 { INSERT INTO t4 VALUES(6, 5, 4); } {} do_execsql_test 3.3 { INSERT INTO t4 VALUES(6, 5, 4); } {}
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@@ -208,5 +208,32 @@ do_execsql_test 6.3 {
SELECT "where" FROM blob; SELECT "where" FROM blob;
} {} } {}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 7.0 {
CREATE TABLE c(x);
INSERT INTO c VALUES(0);
CREATE TABLE t6("col a", "col b", "col c");
CREATE TRIGGER zzz AFTER UPDATE OF "col a", "col c" ON t6 BEGIN
UPDATE c SET x=x+1;
END;
}
do_execsql_test 7.1 {
INSERT INTO t6 VALUES(0, 0, 0);
UPDATE t6 SET "col c" = 1;
SELECT * FROM c;
} {1}
do_execsql_test 7.2 {
ALTER TABLE t6 RENAME "col c" TO "col 3";
}
do_execsql_test 7.3 {
UPDATE t6 SET "col 3" = 0;
SELECT * FROM c;
} {2}
finish_test finish_test