Index: src/alter.c ================================================================== --- src/alter.c +++ src/alter.c @@ -189,11 +189,11 @@ /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in ** the schema to use the new table name. */ sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " - "sql = sqlite_rename_table(%Q, sql, %Q, %Q, %d) " + "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) " "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)" "AND name NOT LIKE 'sqlite_%%'" , zDb, MASTER_NAME, zDb, zTabName, zName, (iDb==1), zTabName ); @@ -229,11 +229,11 @@ ** edit view and trigger definitions within the temp database ** as required. */ if( iDb!=1 ){ sqlite3NestedParse(pParse, "UPDATE sqlite_temp_master SET " - "sql = sqlite_rename_table(%Q, sql, %Q, %Q, 1), " + "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " "tbl_name = " "CASE WHEN tbl_name=%Q COLLATE nocase THEN %Q ELSE tbl_name END " "WHERE type IN ('view', 'trigger')" , zDb, zTabName, zName, zTabName, zTabName, zName); } @@ -1273,14 +1273,16 @@ ** generated by the ALTER TABLE ... RENAME command to modify the definition ** of any foreign key constraints that use the table being renamed as the ** parent table. It is passed three arguments: ** ** 0: The database containing the table being renamed. -** 1: The complete text of the schema statement being modified, -** 2: The old name of the table being renamed, and -** 3: The new name of the table being renamed. -** 4: True if the schema statement comes from the temp db. +** 1. type: Type of object ("table", "view" etc.) +** 2. object: Name of object +** 3: The complete text of the schema statement being modified, +** 4: The old name of the table being renamed, and +** 5: The new name of the table being renamed. +** 6: True if the schema statement comes from the temp db. ** ** It returns the new schema statement. For example: ** ** sqlite_rename_table('main', 'CREATE TABLE t1(a REFERENCES t2)','t2','t3',0) ** -> 'CREATE TABLE t1(a REFERENCES t3)' @@ -1290,14 +1292,14 @@ int NotUsed, sqlite3_value **argv ){ sqlite3 *db = sqlite3_context_db_handle(context); const char *zDb = (const char*)sqlite3_value_text(argv[0]); - const char *zInput = (const char*)sqlite3_value_text(argv[1]); - const char *zOld = (const char*)sqlite3_value_text(argv[2]); - const char *zNew = (const char*)sqlite3_value_text(argv[3]); - int bTemp = sqlite3_value_int(argv[4]); + const char *zInput = (const char*)sqlite3_value_text(argv[3]); + const char *zOld = (const char*)sqlite3_value_text(argv[4]); + const char *zNew = (const char*)sqlite3_value_text(argv[5]); + int bTemp = sqlite3_value_int(argv[6]); UNUSED_PARAMETER(NotUsed); if( zInput && zOld && zNew ){ Parse sParse; int rc; @@ -1386,11 +1388,15 @@ if( rc==SQLITE_OK ){ rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote); } if( rc!=SQLITE_OK ){ - sqlite3_result_error_code(context, rc); + if( sParse.zErrMsg ){ + renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + }else{ + sqlite3_result_error_code(context, rc); + } } renameParseCleanup(&sParse); renameTokenFree(db, sCtx.pList); sqlite3BtreeLeaveAll(db); @@ -1451,11 +1457,11 @@ ** Register built-in functions used to help implement ALTER TABLE */ void sqlite3AlterFunctions(void){ static FuncDef aAlterTableFuncs[] = { FUNCTION(sqlite_rename_column, 9, 0, 0, renameColumnFunc), - FUNCTION(sqlite_rename_table, 5, 0, 0, renameTableFunc), + FUNCTION(sqlite_rename_table, 7, 0, 0, renameTableFunc), FUNCTION(sqlite_rename_test, 5, 0, 0, renameTableTest), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } #endif /* SQLITE_ALTER_TABLE */ Index: test/alter.test ================================================================== --- test/alter.test +++ test/alter.test @@ -686,15 +686,17 @@ # do_test alter-9.1 { execsql {SELECT SQLITE_RENAME_COLUMN(0,0,0,0,0,0,0,0,0)} } {{}} foreach {tn sql} { - 1 { SELECT SQLITE_RENAME_TABLE(0,0,0,0,0) } - 2 { SELECT SQLITE_RENAME_TABLE(10,20,30,40,50) } - 3 { SELECT SQLITE_RENAME_TABLE('foo', 'foo', 'foo', 'foo', 'foo') } + 1 { SELECT SQLITE_RENAME_TABLE(0,0,0,0,0,0,0) } + 2 { SELECT SQLITE_RENAME_TABLE(10,20,30,40,50,60,70) } + 3 { SELECT SQLITE_RENAME_TABLE('foo','foo','foo','foo','foo','foo','foo') } } { - do_catchsql_test alter-9.2.$tn $sql {1 {SQL logic error}} + do_test alter-9.2.$tn { + catch { execsql $sql } + } 1 } #------------------------------------------------------------------------ # alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters # in the names. Index: test/altertab.test ================================================================== --- test/altertab.test +++ test/altertab.test @@ -237,11 +237,11 @@ ); } {} do_execsql_test 7.2 { SELECT - sqlite_rename_table(db, sql, zOld, zNew, bTemp) + sqlite_rename_table(db, 0, 0, sql, zOld, zNew, bTemp) FROM ddd; } {{} {} {}} #------------------------------------------------------------------------- # @@ -264,9 +264,48 @@ do_execsql_test 8.2 { INSERT INTO aux.c1 VALUES(NULL, 1); SELECT sql FROM aux.sqlite_master WHERE name = 'c1'; } {{CREATE TABLE c1(x INTEGER PRIMARY KEY, y REFERENCES "ppp"(a))}} + +reset_db +do_execsql_test 9.0 { + CREATE TABLE t1(a, b, c); + CREATE VIEW v1 AS SELECT * FROM t2; +} +do_catchsql_test 9.1 { + ALTER TABLE t1 RENAME TO t3; +} {1 {error in view v1: no such table: main.t2}} +do_execsql_test 9.2 { + DROP VIEW v1; + CREATE TRIGGER tr AFTER INSERT ON t1 BEGIN + INSERT INTO t2 VALUES(new.a); + END; +} +do_catchsql_test 9.3 { + ALTER TABLE t1 RENAME TO t3; +} {1 {error in trigger tr: no such table: main.t2}} + +forcedelete test.db2 +do_execsql_test 9.4 { + DROP TRIGGER tr; + + ATTACH 'test.db2' AS aux; + CREATE TRIGGER tr AFTER INSERT ON t1 BEGIN SELECT 1, 2, 3; END; + + CREATE TABLE aux.t1(x); + CREATE TEMP TRIGGER tr AFTER INSERT ON aux.t1 BEGIN SELECT 1, 2, 3; END; +} +do_execsql_test 9.5 { + ALTER TABLE main.t1 RENAME TO t3; +} +do_execsql_test 9.6 { + SELECT sql FROM sqlite_temp_master; + SELECT sql FROM sqlite_master WHERE type='trigger'; +} { + {CREATE TRIGGER tr AFTER INSERT ON aux.t1 BEGIN SELECT 1, 2, 3; END} + {CREATE TRIGGER tr AFTER INSERT ON "t3" BEGIN SELECT 1, 2, 3; END} +} finish_test