From: dan Date: Thu, 18 Feb 2021 19:25:44 +0000 (+0000) Subject: Fix a problem with schema error detection when processing ALTER TABLE DROP COLUMN... X-Git-Tag: version-3.35.0~81^2~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=16953469a64ed8f8b5c7434f7200ebd49c5ac983;p=thirdparty%2Fsqlite.git Fix a problem with schema error detection when processing ALTER TABLE DROP COLUMN commands. FossilOrigin-Name: 565a6fd0c95b438fea7bf84913b38de1718117e16e0d685534a8650e1dc8421b --- diff --git a/manifest b/manifest index 12294215e9..bc2e3dbf4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sfor\sALTER\sTABLE\sDROP\sCOLUMN. -D 2021-02-18T17:48:36.327 +C Fix\sa\sproblem\swith\sschema\serror\sdetection\swhen\sprocessing\sALTER\sTABLE\sDROP\sCOLUMN\scommands. +D 2021-02-18T19:25:44.637 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c d56ceae00c743ef991e5ab1e9be2095a441dcee085bccf8795eba3da71b4d85f +F src/alter.c 2e5a29206228e57739e644dab71f268a5d95348e29fc498aa2c31ccc33229fcc F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c F src/attach.c e80162a47411f296bea550ed8fafd730481f4aa71e89ece23ba9c957eed15d4a F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 @@ -647,7 +647,7 @@ F test/alter4.test dfd6086faf461b27ca2d2999848dcd207edf23352fc1592d0005c0844f3f0 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test c0a1ddf5b93d93cb0d15ba7acaf0c5c6fb515bbe861ede75b2d3fabad33b6499 F test/altercol.test 1d6a6fe698b81e626baea4881f5717f9bc53d7d07f1cd23ee7ad1b931f117ddf -F test/alterdropcol.test e75893837c5a9b6422c646c36cb9b50b6ff5a526e6c827bd96a9cea7112ca9ad +F test/alterdropcol.test f4fb3a02a7274740769506f2af2eb8cc60aac26a148b71564b79fe3a19acae3b F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test fa7b1c1139ea39b8dec407cf1feb032ca8e0076bd429574969b619175ad0174b @@ -1902,7 +1902,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 ea999c9db59e4193b306a2e1b15fc94f8f04cb05e852bb0d068b7d5243a0849b -R e87cb22a663d50f61a2888642ea17223 +P 204ee5e28210738fb624a9cf85dc6f9b59de0d7eb4fddd46c8babe9beddd4944 +R 845ed6581bddfe7c8da85d38a6d123ff U dan -Z a5aedcb976c3c92cd79e2c941a67f828 +Z f3602657c19c9bc4f7de01775efae4db diff --git a/manifest.uuid b/manifest.uuid index 6ed839059c..70e8900803 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -204ee5e28210738fb624a9cf85dc6f9b59de0d7eb4fddd46c8babe9beddd4944 \ No newline at end of file +565a6fd0c95b438fea7bf84913b38de1718117e16e0d685534a8650e1dc8421b \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index d48b5ec919..36cc9f3213 100644 --- a/src/alter.c +++ b/src/alter.c @@ -49,16 +49,21 @@ static int isAlterableTable(Parse *pParse, Table *pTab){ ** statement to ensure that the operation has not rendered any schema ** objects unusable. */ -static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ +static void renameTestSchema( + Parse *pParse, /* Parse context */ + const char *zDb, /* Name of db to verify schema of */ + int bTemp, /* True if this is the temp db */ + const char *zWhen /* "when" part of error message */ +){ pParse->colNamesSet = 1; sqlite3NestedParse(pParse, "SELECT 1 " "FROM \"%w\"." DFLT_SCHEMA_TABLE " " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" - " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ", + " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q)=NULL ", zDb, - zDb, bTemp + zDb, bTemp, zWhen ); if( bTemp==0 ){ @@ -67,8 +72,8 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ "FROM temp." DFLT_SCHEMA_TABLE " " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" - " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ", - zDb + " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q)=NULL ", + zDb, zWhen ); } } @@ -231,7 +236,7 @@ void sqlite3AlterRenameTable( "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " "tbl_name = " "CASE WHEN tbl_name=%Q COLLATE nocase AND " - " sqlite_rename_test(%Q, sql, type, name, 1) " + " sqlite_rename_test(%Q, sql, type, name, 1, 'after rename') " "THEN %Q ELSE tbl_name END " "WHERE type IN ('view', 'trigger')" , zDb, zTabName, zName, zTabName, zDb, zName); @@ -251,7 +256,7 @@ void sqlite3AlterRenameTable( #endif renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); - renameTestSchema(pParse, zDb, iDb==1); + renameTestSchema(pParse, zDb, iDb==1, "after rename"); exit_rename_table: sqlite3SrcListDelete(db, pSrc); @@ -619,7 +624,7 @@ void sqlite3AlterRenameColumn( /* Drop and reload the database schema. */ renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename); - renameTestSchema(pParse, zDb, iSchema==1); + renameTestSchema(pParse, zDb, iSchema==1, "after rename"); exit_rename_column: sqlite3SrcListDelete(db, pSrc); @@ -968,7 +973,7 @@ static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ */ static void renameColumnParseError( sqlite3_context *pCtx, - int bPost, + const char *zWhen, sqlite3_value *pType, sqlite3_value *pObject, Parse *pParse @@ -977,8 +982,8 @@ static void renameColumnParseError( const char *zN = (const char*)sqlite3_value_text(pObject); char *zErr; - zErr = sqlite3_mprintf("error in %s %s%s: %s", - zT, zN, (bPost ? " after rename" : ""), + zErr = sqlite3_mprintf("error in %s %s%s%s: %s", + zT, zN, (zWhen[0] ? " " : ""), zWhen, pParse->zErrMsg ); sqlite3_result_error(pCtx, zErr, -1); @@ -1484,7 +1489,7 @@ static void renameColumnFunc( renameColumnFunc_done: if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -1673,7 +1678,7 @@ static void renameTableFunc( } if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -1702,6 +1707,7 @@ static void renameTableFunc( ** 2: Object type ("view", "table", "trigger" or "index"). ** 3: Object name. ** 4: True if object is from temp schema. +** 5: "when" part of error message. ** ** Unless it finds an error, this function normally returns NULL. However, it ** returns integer value 1 if: @@ -1719,6 +1725,7 @@ static void renameTableTest( char const *zInput = (const char*)sqlite3_value_text(argv[1]); int bTemp = sqlite3_value_int(argv[4]); int isLegacy = (db->flags & SQLITE_LegacyAlter); + char const *zWhen = (const char*)sqlite3_value_text(argv[5]); #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth = db->xAuth; @@ -1751,8 +1758,8 @@ static void renameTableTest( } } - if( rc!=SQLITE_OK ){ - renameColumnParseError(context, 1, argv[2], argv[3], &sParse); + if( rc!=SQLITE_OK && zWhen ){ + renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse); } renameParseCleanup(&sParse); } @@ -1869,6 +1876,7 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 ); zDb = db->aDb[iDb].zDbSName; + renameTestSchema(pParse, zDb, iDb==1, ""); sqlite3NestedParse(pParse, "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " "sql = sqlite_drop_column(%d, sql, %d, %d) " @@ -1878,7 +1886,7 @@ void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ /* Drop and reload the database schema. */ renameReloadSchema(pParse, iDb, INITFLAG_AlterDrop); - renameTestSchema(pParse, zDb, iDb==1); + renameTestSchema(pParse, zDb, iDb==1, "after drop column"); /* Edit rows of table on disk */ if( pParse->nErr==0 && (pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL)==0 ){ @@ -1939,7 +1947,7 @@ void sqlite3AlterFunctions(void){ static FuncDef aAlterTableFuncs[] = { INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), - INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest), + INTERNAL_FUNCTION(sqlite_rename_test, 6, renameTableTest), INTERNAL_FUNCTION(sqlite_drop_column, 4, dropColumnFunc), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); diff --git a/test/alterdropcol.test b/test/alterdropcol.test index fecd9e121a..7edb05f4b9 100644 --- a/test/alterdropcol.test +++ b/test/alterdropcol.test @@ -223,6 +223,37 @@ do_execsql_test 5.1 { {CREATE TABLE c2(x, y, w REFERENCES p1(b))} } +do_execsql_test 5.2.1 { + CREATE VIEW v1 AS SELECT d, e FROM p1 +} +do_catchsql_test 5.2.2 { + ALTER TABLE c1 DROP COLUMN x +} {1 {error in view v1: no such column: d}} +do_execsql_test 5.3.1 { + DROP VIEW v1; + CREATE VIEW v1 AS SELECT x, y FROM c1; +} +do_catchsql_test 5.3.2 { + ALTER TABLE c1 DROP COLUMN x +} {1 {error in view v1 after drop column: no such column: x}} + +do_execsql_test 5.4.1 { + CREATE TRIGGER tr AFTER INSERT ON c1 BEGIN + INSERT INTO p1 VALUES(new.y, new.xyz); + END; +} +do_catchsql_test 5.4.2 { + ALTER TABLE c1 DROP COLUMN y +} {1 {error in trigger tr: no such column: new.xyz}} +do_execsql_test 5.5.1 { + DROP TRIGGER tr; + CREATE TRIGGER tr AFTER INSERT ON c1 BEGIN + INSERT INTO p1 VALUES(new.y, new.z); + END; +} +do_catchsql_test 5.5.2 { + ALTER TABLE c1 DROP COLUMN y +} {1 {error in trigger tr: no such column: new.z}} finish_test