From: drh Date: Mon, 13 Aug 2018 15:09:48 +0000 (+0000) Subject: Fix legacy comments on Token. Begin commenting the new ALTER TABLE RENAME X-Git-Tag: version-3.25.0~39^2~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4a2c747c4ca8652f4cd52a96f75d7762a2511c5c;p=thirdparty%2Fsqlite.git Fix legacy comments on Token. Begin commenting the new ALTER TABLE RENAME COLUMN code. Fix a memory leak in the sqlite_rename_column() SQL function. FossilOrigin-Name: 32edc8920376aabb84ebe1900eaa9512d23f1b44d6459e4916dc6b07db66e27c --- diff --git a/manifest b/manifest index 900c1d66e3..d6c9346159 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sissues\swith\sALTER\sTABLE\sRENAME\sCOLUMN\sassociated\swith\sOOM\serrors. -D 2018-08-13T13:43:11.223 +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. +D 2018-08-13T15:09:48.567 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6 @@ -432,7 +432,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c cebb1e3377da1d43f4953958ccba9aa3b8bca1d13c9e65641e618b20fe70b75f +F src/alter.c 7a8e8f14b07063973b772b07921bcc54db36e26e8aae14d2584446ed5af9e513 F src/analyze.c 3dc6b98cf007b005af89df165c966baaa48e8124f38c87b4d2b276fe7f0b9eb9 F src/attach.c 4bd5b92633671d3e8ce431153ebb1893b50335818423b5373f3f27969f79769a F src/auth.c 32a5bbe3b755169ab6c66311c5225a3cd4f75a46c041f7fb117e0cbb68055114 @@ -503,7 +503,7 @@ F src/shell.c.in 6e0aad854be738a5d0368940459399be211e9ac43aebe92bb9ed46cfe38d0e1 F src/sqlite.h.in c6451bb876adced3aba5b1682c6317d215c5eceaba21a6ce979e71a0b8d0bf95 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9887b27e69c01e79c2cbe74ef73bf01af5b5703d6a7f0a4371e386d7249cb1c7 -F src/sqliteInt.h 170af5be3b01be9d92fede33aa5327d486d45a3d784cf87594978a0b7a61fdeb +F src/sqliteInt.h 6cce5956d82972f3e03444c15636222e97938eb9f3dad399df038052c51a04a6 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1756,7 +1756,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P ed64a55a2242408ac0b889b330cf91d38a954399b75c6ebe71232613b864c70b -R 255a4a896f37e0089555356e40c7a265 +P 0b28dd5c2e4908d5e49eaedd359492e46de8af3bf84120f4683b3ea906882fbf +R 8e4aad63439996e323e3c103c6b55b1d U drh -Z 930444da45c5fb126a7b0f868b303e81 +Z 82791a60e4da34a95b2d48254121d988 diff --git a/manifest.uuid b/manifest.uuid index a06a5fba92..aa113d45ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0b28dd5c2e4908d5e49eaedd359492e46de8af3bf84120f4683b3ea906882fbf \ No newline at end of file +32edc8920376aabb84ebe1900eaa9512d23f1b44d6459e4916dc6b07db66e27c \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 98400c1adf..c19eb67a67 100644 --- a/src/alter.c +++ b/src/alter.c @@ -790,29 +790,40 @@ exit_begin_add_column: return; } +/* +** Handles the following parser reduction: +** +** cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew +*/ void sqlite3AlterRenameColumn( - Parse *pParse, - SrcList *pSrc, - Token *pOld, - Token *pNew + Parse *pParse, /* Parsing context */ + SrcList *pSrc, /* Table being altered. pSrc->nSrc==1 */ + Token *pOld, /* Name of column being changed */ + Token *pNew /* New column name */ ){ - sqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; /* Database connection */ Table *pTab; /* Table being updated */ int iCol; /* Index of column being renamed */ - char *zOld = 0; - char *zNew = 0; - const char *zDb; - int iSchema; - int bQuote; + char *zOld = 0; /* Old column name */ + char *zNew = 0; /* New column name */ + const char *zDb; /* Name of schema containing the table */ + int iSchema; /* Index of the schema */ + int bQuote; /* True to quote the new name */ + /* Locate the table to be altered */ pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_rename_column; + + /* Cannot alter a system table */ if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column; - + + /* Which schema holds the table to be altered */ iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iSchema>=0 ); zDb = db->aDb[iSchema].zDbSName; + /* Make sure the old name really is a column name in the table to be + ** altered. Set iCol to be the index of the column being renamed */ zOld = sqlite3NameFromToken(db, pOld); if( !zOld ) goto exit_rename_column; for(iCol=0; iColnCol; iCol++){ @@ -823,6 +834,10 @@ void sqlite3AlterRenameColumn( goto exit_rename_column; } + /* Do the rename operation using a recursive UPDATE statement that + ** uses the sqlite_rename_column() SQL function to compute the new + ** CREATE statement text for the sqlite_master table. + */ zNew = sqlite3NameFromToken(db, pNew); if( !zNew ) goto exit_rename_column; assert( pNew->n>0 ); @@ -849,18 +864,43 @@ void sqlite3AlterRenameColumn( return; } +/* +** Each RenameToken object maps an element of the parse tree into +** the token that generated that element. The parse tree element +** might be one of: +** +** * A pointer to an Expr that represents an ID +** * The name of a table column in Column.zName +** +** A list of RenameToken objects can be constructed during parsing. +** Each new object is created by sqlite3RenameToken(). +** As the parse tree is transformed, the sqlite3MoveRenameToken() +** routine is used to keep the mapping current. +** +** After the parse finishes, renameTokenFind() routine can be used +** to look up the actual token value that created some element in +** the parse tree. +*/ struct RenameToken { - void *p; - Token t; - RenameToken *pNext; + void *p; /* Parse tree element created by token t */ + Token t; /* The token that created parse tree element p */ + RenameToken *pNext; /* Next is a list of all RenameToken objects */ }; +/* +** The context of an ALTER TABLE RENAME COLUMN operation that gets passed +** down into the Walker. +*/ struct RenameCtx { RenameToken *pList; /* List of tokens to overwrite */ int nList; /* Number of tokens in pList */ int iCol; /* Index of column being renamed */ }; +/* +** Add a new RenameToken object mapping parse tree element pPtr into +** token *pToken to the Parse object currently under construction. +*/ void sqlite3RenameToken(Parse *pParse, void *pPtr, Token *pToken){ RenameToken *pNew; pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken)); @@ -872,6 +912,11 @@ void sqlite3RenameToken(Parse *pParse, void *pPtr, Token *pToken){ } } +/* +** If there is a RenameToken object associated with parse tree element +** pFrom, then remap that object over to pTo due to a transformation +** in the parse tree. +*/ void sqlite3MoveRenameToken(Parse *pParse, void *pTo, void *pFrom){ RenameToken *p; for(p=pParse->pRename; p; p=p->pNext){ @@ -883,6 +928,9 @@ void sqlite3MoveRenameToken(Parse *pParse, void *pTo, void *pFrom){ assert( p ); } +/* +** Free the list of RenameToken objects given in the second argument +*/ static void renameTokenFree(sqlite3 *db, RenameToken *pToken){ RenameToken *pNext; RenameToken *p; @@ -1101,6 +1149,7 @@ renameColumnFunc_done: sqlite3DeleteTable(db, sParse.pNewTable); if( sParse.pNewIndex ) sqlite3FreeIndex(db, sParse.pNewIndex); renameTokenFree(db, sParse.pRename); + renameTokenFree(db, sCtx.pList); sqlite3ParserReset(&sParse); sqlite3_free(zQuot); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 5a4fe949ab..7b01bb27f0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2281,9 +2281,11 @@ struct IndexSample { ** Each token coming out of the lexer is an instance of ** this structure. Tokens are also used as part of an expression. ** -** Note if Token.z==0 then Token.dyn and Token.n are undefined and -** may contain random values. Do not make any assumptions about Token.dyn -** and Token.n when Token.z==0. +** The memory that "z" points to is owned by other objects. Take care +** that the owner of the "z" string does not deallocate the string before +** the Token goes out of scope! Very often, the "z" points to some place +** in the middle of the Parse.zSql text. But it might also point to a +** static string. */ struct Token { const char *z; /* Text of the token. Not NULL-terminated! */ @@ -3114,7 +3116,7 @@ struct Parse { With *pWith; /* Current WITH clause, or NULL */ With *pWithToFree; /* Free this WITH object at the end of the parse */ #ifndef SQLITE_OMIT_ALTERTABLE - RenameToken *pRename; + RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ #endif };