123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864 |
- # 2004 November 10
- #
- # The author disclaims copyright to this source code. In place of
- # a legal notice, here is a blessing:
- #
- # May you do good and not evil.
- # May you find forgiveness for yourself and forgive others.
- # May you share freely, never taking more than you give.
- #
- #*************************************************************************
- # This file implements regression tests for SQLite library. The
- # focus of this script is testing the ALTER TABLE statement.
- #
- # $Id: alter.test,v 1.32 2009/03/24 15:08:10 drh Exp $
- #
- set testdir [file dirname $argv0]
- source $testdir/tester.tcl
- # If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
- ifcapable !altertable {
- finish_test
- return
- }
- #----------------------------------------------------------------------
- # Test organization:
- #
- # alter-1.1.* - alter-1.7.*: Basic tests of ALTER TABLE, including tables
- # with implicit and explicit indices. These tests came from an earlier
- # fork of SQLite that also supported ALTER TABLE.
- # alter-1.8.*: Tests for ALTER TABLE when the table resides in an
- # attached database.
- # alter-1.9.*: Tests for ALTER TABLE when their is whitespace between the
- # table name and left parenthesis token. i.e:
- # "CREATE TABLE abc (a, b, c);"
- # alter-2.*: Test error conditions and messages.
- # alter-3.*: Test ALTER TABLE on tables that have TRIGGERs attached to them.
- # alter-4.*: Test ALTER TABLE on tables that have AUTOINCREMENT fields.
- # ...
- # alter-12.*: Test ALTER TABLE on views.
- #
- # Create some tables to rename. Be sure to include some TEMP tables
- # and some tables with odd names.
- #
- do_test alter-1.1 {
- ifcapable tempdb {
- set ::temp TEMP
- } else {
- set ::temp {}
- }
- execsql [subst -nocommands {
- CREATE TABLE t1(a,b);
- INSERT INTO t1 VALUES(1,2);
- CREATE TABLE [t1'x1](c UNIQUE, b PRIMARY KEY);
- INSERT INTO [t1'x1] VALUES(3,4);
- CREATE INDEX t1i1 ON T1(B);
- CREATE INDEX t1i2 ON t1(a,b);
- CREATE INDEX i3 ON [t1'x1](b,c);
- CREATE $::temp TABLE "temp table"(e,f,g UNIQUE);
- CREATE INDEX i2 ON [temp table](f);
- INSERT INTO [temp table] VALUES(5,6,7);
- }]
- execsql {
- SELECT 't1', * FROM t1;
- SELECT 't1''x1', * FROM "t1'x1";
- SELECT * FROM [temp table];
- }
- } {t1 1 2 t1'x1 3 4 5 6 7}
- do_test alter-1.2 {
- execsql [subst {
- CREATE $::temp TABLE objlist(type, name, tbl_name);
- INSERT INTO objlist SELECT type, name, tbl_name
- FROM sqlite_master WHERE NAME!='objlist';
- }]
- ifcapable tempdb {
- execsql {
- INSERT INTO objlist SELECT type, name, tbl_name
- FROM sqlite_temp_master WHERE NAME!='objlist';
- }
- }
- execsql {
- SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name;
- }
- } [list \
- table t1 t1 \
- index t1i1 t1 \
- index t1i2 t1 \
- table t1'x1 t1'x1 \
- index i3 t1'x1 \
- index {sqlite_autoindex_t1'x1_1} t1'x1 \
- index {sqlite_autoindex_t1'x1_2} t1'x1 \
- table {temp table} {temp table} \
- index i2 {temp table} \
- index {sqlite_autoindex_temp table_1} {temp table} \
- ]
- # Make some changes
- #
- integrity_check alter-1.3.0
- do_test alter-1.3 {
- execsql {
- ALTER TABLE [T1] RENAME to [-t1-];
- ALTER TABLE "t1'x1" RENAME TO T2;
- ALTER TABLE [temp table] RENAME to TempTab;
- }
- } {}
- integrity_check alter-1.3.1
- do_test alter-1.4 {
- execsql {
- SELECT 't1', * FROM [-t1-];
- SELECT 't2', * FROM t2;
- SELECT * FROM temptab;
- }
- } {t1 1 2 t2 3 4 5 6 7}
- do_test alter-1.5 {
- execsql {
- DELETE FROM objlist;
- INSERT INTO objlist SELECT type, name, tbl_name
- FROM sqlite_master WHERE NAME!='objlist';
- }
- catchsql {
- INSERT INTO objlist SELECT type, name, tbl_name
- FROM sqlite_temp_master WHERE NAME!='objlist';
- }
- execsql {
- SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name;
- }
- } [list \
- table -t1- -t1- \
- index t1i1 -t1- \
- index t1i2 -t1- \
- table T2 T2 \
- index i3 T2 \
- index {sqlite_autoindex_T2_1} T2 \
- index {sqlite_autoindex_T2_2} T2 \
- table {TempTab} {TempTab} \
- index i2 {TempTab} \
- index {sqlite_autoindex_TempTab_1} {TempTab} \
- ]
- # Make sure the changes persist after restarting the database.
- # (The TEMP table will not persist, of course.)
- #
- ifcapable tempdb {
- do_test alter-1.6 {
- db close
- sqlite3 db test.db
- set DB [sqlite3_connection_pointer db]
- execsql {
- CREATE TEMP TABLE objlist(type, name, tbl_name);
- INSERT INTO objlist SELECT type, name, tbl_name FROM sqlite_master;
- INSERT INTO objlist
- SELECT type, name, tbl_name FROM sqlite_temp_master
- WHERE NAME!='objlist';
- SELECT type, name, tbl_name FROM objlist
- ORDER BY tbl_name, type desc, name;
- }
- } [list \
- table -t1- -t1- \
- index t1i1 -t1- \
- index t1i2 -t1- \
- table T2 T2 \
- index i3 T2 \
- index {sqlite_autoindex_T2_1} T2 \
- index {sqlite_autoindex_T2_2} T2 \
- ]
- } else {
- execsql {
- DROP TABLE TempTab;
- }
- }
- # Create bogus application-defined functions for functions used
- # internally by ALTER TABLE, to ensure that ALTER TABLE falls back
- # to the built-in functions.
- #
- proc failing_app_func {args} {error "bad function"}
- do_test alter-1.7-prep {
- db func substr failing_app_func
- db func like failing_app_func
- db func sqlite_rename_table failing_app_func
- db func sqlite_rename_trigger failing_app_func
- db func sqlite_rename_parent failing_app_func
- catchsql {SELECT substr(name,1,3) FROM sqlite_master}
- } {1 {bad function}}
- # Make sure the ALTER TABLE statements work with the
- # non-callback API
- #
- do_test alter-1.7 {
- stepsql $DB {
- ALTER TABLE [-t1-] RENAME to [*t1*];
- ALTER TABLE T2 RENAME TO [<t2>];
- }
- execsql {
- DELETE FROM objlist;
- INSERT INTO objlist SELECT type, name, tbl_name
- FROM sqlite_master WHERE NAME!='objlist';
- }
- catchsql {
- INSERT INTO objlist SELECT type, name, tbl_name
- FROM sqlite_temp_master WHERE NAME!='objlist';
- }
- execsql {
- SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name;
- }
- } [list \
- table *t1* *t1* \
- index t1i1 *t1* \
- index t1i2 *t1* \
- table <t2> <t2> \
- index i3 <t2> \
- index {sqlite_autoindex_<t2>_1} <t2> \
- index {sqlite_autoindex_<t2>_2} <t2> \
- ]
- # Check that ALTER TABLE works on attached databases.
- #
- ifcapable attach {
- do_test alter-1.8.1 {
- forcedelete test2.db
- forcedelete test2.db-journal
- execsql {
- ATTACH 'test2.db' AS aux;
- }
- } {}
- do_test alter-1.8.2 {
- execsql {
- CREATE TABLE t4(a PRIMARY KEY, b, c);
- CREATE TABLE aux.t4(a PRIMARY KEY, b, c);
- CREATE INDEX i4 ON t4(b);
- CREATE INDEX aux.i4 ON t4(b);
- }
- } {}
- do_test alter-1.8.3 {
- execsql {
- INSERT INTO t4 VALUES('main', 'main', 'main');
- INSERT INTO aux.t4 VALUES('aux', 'aux', 'aux');
- SELECT * FROM t4 WHERE a = 'main';
- }
- } {main main main}
- do_test alter-1.8.4 {
- execsql {
- ALTER TABLE t4 RENAME TO t5;
- SELECT * FROM t4 WHERE a = 'aux';
- }
- } {aux aux aux}
- do_test alter-1.8.5 {
- execsql {
- SELECT * FROM t5;
- }
- } {main main main}
- do_test alter-1.8.6 {
- execsql {
- SELECT * FROM t5 WHERE b = 'main';
- }
- } {main main main}
- do_test alter-1.8.7 {
- execsql {
- ALTER TABLE aux.t4 RENAME TO t5;
- SELECT * FROM aux.t5 WHERE b = 'aux';
- }
- } {aux aux aux}
- }
- do_test alter-1.9.1 {
- execsql {
- CREATE TABLE tbl1 (a, b, c);
- INSERT INTO tbl1 VALUES(1, 2, 3);
- }
- } {}
- do_test alter-1.9.2 {
- execsql {
- SELECT * FROM tbl1;
- }
- } {1 2 3}
- do_test alter-1.9.3 {
- execsql {
- ALTER TABLE tbl1 RENAME TO tbl2;
- SELECT * FROM tbl2;
- }
- } {1 2 3}
- do_test alter-1.9.4 {
- execsql {
- DROP TABLE tbl2;
- }
- } {}
- # Test error messages
- #
- do_test alter-2.1 {
- catchsql {
- ALTER TABLE none RENAME TO hi;
- }
- } {1 {no such table: none}}
- do_test alter-2.2 {
- execsql {
- CREATE TABLE t3(p,q,r);
- }
- catchsql {
- ALTER TABLE [<t2>] RENAME TO t3;
- }
- } {1 {there is already another table or index with this name: t3}}
- do_test alter-2.3 {
- catchsql {
- ALTER TABLE [<t2>] RENAME TO i3;
- }
- } {1 {there is already another table or index with this name: i3}}
- do_test alter-2.4 {
- catchsql {
- ALTER TABLE SqLiTe_master RENAME TO master;
- }
- } {1 {table sqlite_master may not be altered}}
- do_test alter-2.5 {
- catchsql {
- ALTER TABLE t3 RENAME TO sqlite_t3;
- }
- } {1 {object name reserved for internal use: sqlite_t3}}
- do_test alter-2.6 {
- catchsql {
- ALTER TABLE t3 ADD COLUMN (ALTER TABLE t3 ADD COLUMN);
- }
- } {1 {near "(": syntax error}}
- # If this compilation does not include triggers, omit the alter-3.* tests.
- ifcapable trigger {
- #-----------------------------------------------------------------------
- # Tests alter-3.* test ALTER TABLE on tables that have triggers.
- #
- # alter-3.1.*: ALTER TABLE with triggers.
- # alter-3.2.*: Test that the ON keyword cannot be used as a database,
- # table or column name unquoted. This is done because part of the
- # ALTER TABLE code (specifically the implementation of SQL function
- # "sqlite_alter_trigger") will break in this case.
- # alter-3.3.*: ALTER TABLE with TEMP triggers (todo).
- #
- # An SQL user-function for triggers to fire, so that we know they
- # are working.
- proc trigfunc {args} {
- set ::TRIGGER $args
- }
- db func trigfunc trigfunc
- do_test alter-3.1.0 {
- execsql {
- CREATE TABLE t6(a, b, c);
- -- Different case for the table name in the trigger.
- CREATE TRIGGER trig1 AFTER INSERT ON T6 BEGIN
- SELECT trigfunc('trig1', new.a, new.b, new.c);
- END;
- }
- } {}
- do_test alter-3.1.1 {
- execsql {
- INSERT INTO t6 VALUES(1, 2, 3);
- }
- set ::TRIGGER
- } {trig1 1 2 3}
- do_test alter-3.1.2 {
- execsql {
- ALTER TABLE t6 RENAME TO t7;
- INSERT INTO t7 VALUES(4, 5, 6);
- }
- set ::TRIGGER
- } {trig1 4 5 6}
- do_test alter-3.1.3 {
- execsql {
- DROP TRIGGER trig1;
- }
- } {}
- do_test alter-3.1.4 {
- execsql {
- CREATE TRIGGER trig2 AFTER INSERT ON main.t7 BEGIN
- SELECT trigfunc('trig2', new.a, new.b, new.c);
- END;
- INSERT INTO t7 VALUES(1, 2, 3);
- }
- set ::TRIGGER
- } {trig2 1 2 3}
- do_test alter-3.1.5 {
- execsql {
- ALTER TABLE t7 RENAME TO t8;
- INSERT INTO t8 VALUES(4, 5, 6);
- }
- set ::TRIGGER
- } {trig2 4 5 6}
- do_test alter-3.1.6 {
- execsql {
- DROP TRIGGER trig2;
- }
- } {}
- do_test alter-3.1.7 {
- execsql {
- CREATE TRIGGER trig3 AFTER INSERT ON main.'t8'BEGIN
- SELECT trigfunc('trig3', new.a, new.b, new.c);
- END;
- INSERT INTO t8 VALUES(1, 2, 3);
- }
- set ::TRIGGER
- } {trig3 1 2 3}
- do_test alter-3.1.8 {
- execsql {
- ALTER TABLE t8 RENAME TO t9;
- INSERT INTO t9 VALUES(4, 5, 6);
- }
- set ::TRIGGER
- } {trig3 4 5 6}
- # Make sure "ON" cannot be used as a database, table or column name without
- # quoting. Otherwise the sqlite_alter_trigger() function might not work.
- forcedelete test3.db
- forcedelete test3.db-journal
- ifcapable attach {
- do_test alter-3.2.1 {
- catchsql {
- ATTACH 'test3.db' AS ON;
- }
- } {1 {near "ON": syntax error}}
- do_test alter-3.2.2 {
- catchsql {
- ATTACH 'test3.db' AS 'ON';
- }
- } {0 {}}
- do_test alter-3.2.3 {
- catchsql {
- CREATE TABLE ON.t1(a, b, c);
- }
- } {1 {near "ON": syntax error}}
- do_test alter-3.2.4 {
- catchsql {
- CREATE TABLE 'ON'.t1(a, b, c);
- }
- } {0 {}}
- do_test alter-3.2.4 {
- catchsql {
- CREATE TABLE 'ON'.ON(a, b, c);
- }
- } {1 {near "ON": syntax error}}
- do_test alter-3.2.5 {
- catchsql {
- CREATE TABLE 'ON'.'ON'(a, b, c);
- }
- } {0 {}}
- }
- do_test alter-3.2.6 {
- catchsql {
- CREATE TABLE t10(a, ON, c);
- }
- } {1 {near "ON": syntax error}}
- do_test alter-3.2.7 {
- catchsql {
- CREATE TABLE t10(a, 'ON', c);
- }
- } {0 {}}
- do_test alter-3.2.8 {
- catchsql {
- CREATE TRIGGER trig4 AFTER INSERT ON ON BEGIN SELECT 1; END;
- }
- } {1 {near "ON": syntax error}}
- ifcapable attach {
- do_test alter-3.2.9 {
- catchsql {
- CREATE TRIGGER 'on'.trig4 AFTER INSERT ON 'ON' BEGIN SELECT 1; END;
- }
- } {0 {}}
- }
- do_test alter-3.2.10 {
- execsql {
- DROP TABLE t10;
- }
- } {}
- do_test alter-3.3.1 {
- execsql [subst {
- CREATE TABLE tbl1(a, b, c);
- CREATE $::temp TRIGGER trig1 AFTER INSERT ON tbl1 BEGIN
- SELECT trigfunc('trig1', new.a, new.b, new.c);
- END;
- }]
- } {}
- do_test alter-3.3.2 {
- execsql {
- INSERT INTO tbl1 VALUES('a', 'b', 'c');
- }
- set ::TRIGGER
- } {trig1 a b c}
- do_test alter-3.3.3 {
- execsql {
- ALTER TABLE tbl1 RENAME TO tbl2;
- INSERT INTO tbl2 VALUES('d', 'e', 'f');
- }
- set ::TRIGGER
- } {trig1 d e f}
- do_test alter-3.3.4 {
- execsql [subst {
- CREATE $::temp TRIGGER trig2 AFTER UPDATE ON tbl2 BEGIN
- SELECT trigfunc('trig2', new.a, new.b, new.c);
- END;
- }]
- } {}
- do_test alter-3.3.5 {
- execsql {
- ALTER TABLE tbl2 RENAME TO tbl3;
- INSERT INTO tbl3 VALUES('g', 'h', 'i');
- }
- set ::TRIGGER
- } {trig1 g h i}
- do_test alter-3.3.6 {
- execsql {
- UPDATE tbl3 SET a = 'G' where a = 'g';
- }
- set ::TRIGGER
- } {trig2 G h i}
- do_test alter-3.3.7 {
- execsql {
- DROP TABLE tbl3;
- }
- } {}
- ifcapable tempdb {
- do_test alter-3.3.8 {
- execsql {
- SELECT * FROM sqlite_temp_master WHERE type = 'trigger';
- }
- } {}
- }
- } ;# ifcapable trigger
- # If the build does not include AUTOINCREMENT fields, omit alter-4.*.
- ifcapable autoinc {
- do_test alter-4.1 {
- execsql {
- CREATE TABLE tbl1(a INTEGER PRIMARY KEY AUTOINCREMENT);
- INSERT INTO tbl1 VALUES(10);
- }
- } {}
- do_test alter-4.2 {
- execsql {
- INSERT INTO tbl1 VALUES(NULL);
- SELECT a FROM tbl1;
- }
- } {10 11}
- do_test alter-4.3 {
- execsql {
- ALTER TABLE tbl1 RENAME TO tbl2;
- DELETE FROM tbl2;
- INSERT INTO tbl2 VALUES(NULL);
- SELECT a FROM tbl2;
- }
- } {12}
- do_test alter-4.4 {
- execsql {
- DROP TABLE tbl2;
- }
- } {}
- } ;# ifcapable autoinc
- # Test that it is Ok to execute an ALTER TABLE immediately after
- # opening a database.
- do_test alter-5.1 {
- execsql {
- CREATE TABLE tbl1(a, b, c);
- INSERT INTO tbl1 VALUES('x', 'y', 'z');
- }
- } {}
- do_test alter-5.2 {
- sqlite3 db2 test.db
- execsql {
- ALTER TABLE tbl1 RENAME TO tbl2;
- SELECT * FROM tbl2;
- } db2
- } {x y z}
- do_test alter-5.3 {
- db2 close
- } {}
- foreach tblname [execsql {
- SELECT name FROM sqlite_master
- WHERE type='table' AND name NOT GLOB 'sqlite*'
- }] {
- execsql "DROP TABLE \"$tblname\""
- }
- set ::tbl_name "abc\uABCDdef"
- do_test alter-6.1 {
- string length $::tbl_name
- } {7}
- do_test alter-6.2 {
- execsql "
- CREATE TABLE ${tbl_name}(a, b, c);
- "
- set ::oid [execsql {SELECT max(oid) FROM sqlite_master}]
- execsql "
- SELECT sql FROM sqlite_master WHERE oid = $::oid;
- "
- } "{CREATE TABLE ${::tbl_name}(a, b, c)}"
- execsql "
- SELECT * FROM ${::tbl_name}
- "
- set ::tbl_name2 "abcXdef"
- do_test alter-6.3 {
- execsql "
- ALTER TABLE $::tbl_name RENAME TO $::tbl_name2
- "
- execsql "
- SELECT sql FROM sqlite_master WHERE oid = $::oid
- "
- } "{CREATE TABLE \"${::tbl_name2}\"(a, b, c)}"
- do_test alter-6.4 {
- execsql "
- ALTER TABLE $::tbl_name2 RENAME TO $::tbl_name
- "
- execsql "
- SELECT sql FROM sqlite_master WHERE oid = $::oid
- "
- } "{CREATE TABLE \"${::tbl_name}\"(a, b, c)}"
- set ::col_name ghi\1234\jkl
- do_test alter-6.5 {
- execsql "
- ALTER TABLE $::tbl_name ADD COLUMN $::col_name VARCHAR
- "
- execsql "
- SELECT sql FROM sqlite_master WHERE oid = $::oid
- "
- } "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR)}"
- set ::col_name2 B\3421\A
- do_test alter-6.6 {
- db close
- sqlite3 db test.db
- execsql "
- ALTER TABLE $::tbl_name ADD COLUMN $::col_name2
- "
- execsql "
- SELECT sql FROM sqlite_master WHERE oid = $::oid
- "
- } "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR, $::col_name2)}"
- do_test alter-6.7 {
- execsql "
- INSERT INTO ${::tbl_name} VALUES(1, 2, 3, 4, 5);
- SELECT $::col_name, $::col_name2 FROM $::tbl_name;
- "
- } {4 5}
- # Ticket #1665: Make sure ALTER TABLE ADD COLUMN works on a table
- # that includes a COLLATE clause.
- #
- do_realnum_test alter-7.1 {
- execsql {
- CREATE TABLE t1(a TEXT COLLATE BINARY);
- ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE;
- INSERT INTO t1 VALUES(1,'-2');
- INSERT INTO t1 VALUES(5.4e-08,'5.4e-08');
- SELECT typeof(a), a, typeof(b), b FROM t1;
- }
- } {text 1 integer -2 text 5.4e-08 real 5.4e-08}
- # Make sure that when a column is added by ALTER TABLE ADD COLUMN and has
- # a default value that the default value is used by aggregate functions.
- #
- do_test alter-8.1 {
- execsql {
- CREATE TABLE t2(a INTEGER);
- INSERT INTO t2 VALUES(1);
- INSERT INTO t2 VALUES(1);
- INSERT INTO t2 VALUES(2);
- ALTER TABLE t2 ADD COLUMN b INTEGER DEFAULT 9;
- SELECT sum(b) FROM t2;
- }
- } {27}
- do_test alter-8.2 {
- execsql {
- SELECT a, sum(b) FROM t2 GROUP BY a;
- }
- } {1 18 2 9}
- #--------------------------------------------------------------------------
- # alter-9.X - Special test: Make sure the sqlite_rename_trigger() and
- # rename_table() functions do not crash when handed bad input.
- #
- ifcapable trigger {
- do_test alter-9.1 {
- execsql {SELECT SQLITE_RENAME_TRIGGER(0,0)}
- } {{}}
- }
- do_test alter-9.2 {
- execsql {
- SELECT SQLITE_RENAME_TABLE(0,0);
- SELECT SQLITE_RENAME_TABLE(10,20);
- SELECT SQLITE_RENAME_TABLE('foo', 'foo');
- }
- } {{} {} {}}
- #------------------------------------------------------------------------
- # alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters
- # in the names.
- #
- do_test alter-10.1 {
- execsql "CREATE TABLE xyz(x UNIQUE)"
- execsql "ALTER TABLE xyz RENAME TO xyz\u1234abc"
- execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
- } [list xyz\u1234abc]
- do_test alter-10.2 {
- execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
- } [list sqlite_autoindex_xyz\u1234abc_1]
- do_test alter-10.3 {
- execsql "ALTER TABLE xyz\u1234abc RENAME TO xyzabc"
- execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
- } [list xyzabc]
- do_test alter-10.4 {
- execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
- } [list sqlite_autoindex_xyzabc_1]
- do_test alter-11.1 {
- sqlite3_exec db {CREATE TABLE t11(%c6%c6)}
- execsql {
- ALTER TABLE t11 ADD COLUMN abc;
- }
- catchsql {
- ALTER TABLE t11 ADD COLUMN abc;
- }
- } {1 {duplicate column name: abc}}
- set isutf16 [regexp 16 [db one {PRAGMA encoding}]]
- if {!$isutf16} {
- do_test alter-11.2 {
- execsql {INSERT INTO t11 VALUES(1,2)}
- sqlite3_exec db {SELECT %c6%c6 AS xyz, abc FROM t11}
- } {0 {xyz abc 1 2}}
- }
- do_test alter-11.3 {
- sqlite3_exec db {CREATE TABLE t11b("%81%82%83" text)}
- execsql {
- ALTER TABLE t11b ADD COLUMN abc;
- }
- catchsql {
- ALTER TABLE t11b ADD COLUMN abc;
- }
- } {1 {duplicate column name: abc}}
- if {!$isutf16} {
- do_test alter-11.4 {
- execsql {INSERT INTO t11b VALUES(3,4)}
- sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11b}
- } {0 {xyz abc 3 4}}
- do_test alter-11.5 {
- sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11b}
- } {0 {xyz abc 3 4}}
- do_test alter-11.6 {
- sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11b}
- } {0 {xyz abc 3 4}}
- }
- do_test alter-11.7 {
- sqlite3_exec db {CREATE TABLE t11c(%81%82%83 text)}
- execsql {
- ALTER TABLE t11c ADD COLUMN abc;
- }
- catchsql {
- ALTER TABLE t11c ADD COLUMN abc;
- }
- } {1 {duplicate column name: abc}}
- if {!$isutf16} {
- do_test alter-11.8 {
- execsql {INSERT INTO t11c VALUES(5,6)}
- sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11c}
- } {0 {xyz abc 5 6}}
- do_test alter-11.9 {
- sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11c}
- } {0 {xyz abc 5 6}}
- do_test alter-11.10 {
- sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11c}
- } {0 {xyz abc 5 6}}
- }
- do_test alter-12.1 {
- execsql {
- CREATE TABLE t12(a, b, c);
- CREATE VIEW v1 AS SELECT * FROM t12;
- }
- } {}
- do_test alter-12.2 {
- catchsql {
- ALTER TABLE v1 RENAME TO v2;
- }
- } {1 {view v1 may not be altered}}
- do_test alter-12.3 {
- execsql { SELECT * FROM v1; }
- } {}
- do_test alter-12.4 {
- db close
- sqlite3 db test.db
- execsql { SELECT * FROM v1; }
- } {}
- do_test alter-12.5 {
- catchsql {
- ALTER TABLE v1 ADD COLUMN new_column;
- }
- } {1 {Cannot add a column to a view}}
- # Ticket #3102:
- # Verify that comments do not interfere with the table rename
- # algorithm.
- #
- do_test alter-13.1 {
- execsql {
- CREATE TABLE /* hi */ t3102a(x);
- CREATE TABLE t3102b -- comment
- (y);
- CREATE INDEX t3102c ON t3102a(x);
- SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
- }
- } {t3102a t3102b t3102c}
- do_test alter-13.2 {
- execsql {
- ALTER TABLE t3102a RENAME TO t3102a_rename;
- SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
- }
- } {t3102a_rename t3102b t3102c}
- do_test alter-13.3 {
- execsql {
- ALTER TABLE t3102b RENAME TO t3102b_rename;
- SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
- }
- } {t3102a_rename t3102b_rename t3102c}
- # Ticket #3651
- do_test alter-14.1 {
- catchsql {
- CREATE TABLE t3651(a UNIQUE);
- ALTER TABLE t3651 ADD COLUMN b UNIQUE;
- }
- } {1 {Cannot add a UNIQUE column}}
- do_test alter-14.2 {
- catchsql {
- ALTER TABLE t3651 ADD COLUMN b PRIMARY KEY;
- }
- } {1 {Cannot add a PRIMARY KEY column}}
- #-------------------------------------------------------------------------
- # Test that it is not possible to use ALTER TABLE on any system table.
- #
- set system_table_list {1 sqlite_master}
- catchsql ANALYZE
- ifcapable analyze { lappend system_table_list 2 sqlite_stat1 }
- ifcapable stat3 { lappend system_table_list 3 sqlite_stat3 }
- ifcapable stat4 { lappend system_table_list 4 sqlite_stat4 }
- foreach {tn tbl} $system_table_list {
- do_test alter-15.$tn.1 {
- catchsql "ALTER TABLE $tbl RENAME TO xyz"
- } [list 1 "table $tbl may not be altered"]
- do_test alter-15.$tn.2 {
- catchsql "ALTER TABLE $tbl ADD COLUMN xyz"
- } [list 1 "table $tbl may not be altered"]
- }
- finish_test
|