xref: /sqlite-3.40.0/test/alter.test (revision febf0352)
1b6c29897Sdrh# 2004 November 10
29fd2a9a0Sdanielk1977#
3b6c29897Sdrh# The author disclaims copyright to this source code.  In place of
4b6c29897Sdrh# a legal notice, here is a blessing:
5b6c29897Sdrh#
6b6c29897Sdrh#    May you do good and not evil.
7b6c29897Sdrh#    May you find forgiveness for yourself and forgive others.
8b6c29897Sdrh#    May you share freely, never taking more than you give.
99fd2a9a0Sdanielk1977#
109fd2a9a0Sdanielk1977#*************************************************************************
119fd2a9a0Sdanielk1977# This file implements regression tests for SQLite library.  The
129fd2a9a0Sdanielk1977# focus of this script is testing the ALTER TABLE statement.
139fd2a9a0Sdanielk1977#
14d9da78a2Sdrh# $Id: alter.test,v 1.32 2009/03/24 15:08:10 drh Exp $
159fd2a9a0Sdanielk1977#
169fd2a9a0Sdanielk1977
179fd2a9a0Sdanielk1977set testdir [file dirname $argv0]
189fd2a9a0Sdanielk1977source $testdir/tester.tcl
199fd2a9a0Sdanielk1977
201c8c23ccSdanielk1977# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
211c8c23ccSdanielk1977ifcapable !altertable {
221c8c23ccSdanielk1977  finish_test
231c8c23ccSdanielk1977  return
241c8c23ccSdanielk1977}
259fd2a9a0Sdanielk1977
26343e9261Sdanielk1977#----------------------------------------------------------------------
27343e9261Sdanielk1977# Test organization:
28343e9261Sdanielk1977#
29343e9261Sdanielk1977# alter-1.1.* - alter-1.7.*: Basic tests of ALTER TABLE, including tables
30343e9261Sdanielk1977#     with implicit and explicit indices. These tests came from an earlier
31343e9261Sdanielk1977#     fork of SQLite that also supported ALTER TABLE.
32343e9261Sdanielk1977# alter-1.8.*: Tests for ALTER TABLE when the table resides in an
33343e9261Sdanielk1977#     attached database.
34343e9261Sdanielk1977# alter-1.9.*: Tests for ALTER TABLE when their is whitespace between the
35343e9261Sdanielk1977#     table name and left parenthesis token. i.e:
36343e9261Sdanielk1977#     "CREATE TABLE abc       (a, b, c);"
37343e9261Sdanielk1977# alter-2.*: Test error conditions and messages.
38343e9261Sdanielk1977# alter-3.*: Test ALTER TABLE on tables that have TRIGGERs attached to them.
39aacd732bSdanielk1977# alter-4.*: Test ALTER TABLE on tables that have AUTOINCREMENT fields.
4061116ae1Sdanielk1977# ...
4161116ae1Sdanielk1977# alter-12.*: Test ALTER TABLE on views.
42343e9261Sdanielk1977#
43343e9261Sdanielk1977
449fd2a9a0Sdanielk1977# Create some tables to rename.  Be sure to include some TEMP tables
459fd2a9a0Sdanielk1977# and some tables with odd names.
469fd2a9a0Sdanielk1977#
479fd2a9a0Sdanielk1977do_test alter-1.1 {
4853c0f748Sdanielk1977  ifcapable tempdb {
4953c0f748Sdanielk1977    set ::temp TEMP
5053c0f748Sdanielk1977  } else {
5153c0f748Sdanielk1977    set ::temp {}
5253c0f748Sdanielk1977  }
5353c0f748Sdanielk1977  execsql [subst -nocommands {
549fd2a9a0Sdanielk1977    CREATE TABLE t1(a,b);
559fd2a9a0Sdanielk1977    INSERT INTO t1 VALUES(1,2);
569fd2a9a0Sdanielk1977    CREATE TABLE [t1'x1](c UNIQUE, b PRIMARY KEY);
579fd2a9a0Sdanielk1977    INSERT INTO [t1'x1] VALUES(3,4);
589fd2a9a0Sdanielk1977    CREATE INDEX t1i1 ON T1(B);
599fd2a9a0Sdanielk1977    CREATE INDEX t1i2 ON t1(a,b);
609fd2a9a0Sdanielk1977    CREATE INDEX i3 ON [t1'x1](b,c);
6153c0f748Sdanielk1977    CREATE $::temp TABLE "temp table"(e,f,g UNIQUE);
629fd2a9a0Sdanielk1977    CREATE INDEX i2 ON [temp table](f);
639fd2a9a0Sdanielk1977    INSERT INTO [temp table] VALUES(5,6,7);
6453c0f748Sdanielk1977  }]
659fd2a9a0Sdanielk1977  execsql {
6627c77438Sdanielk1977    SELECT 't1', * FROM t1;
6727c77438Sdanielk1977    SELECT 't1''x1', * FROM "t1'x1";
6827c77438Sdanielk1977    SELECT * FROM [temp table];
699fd2a9a0Sdanielk1977  }
709fd2a9a0Sdanielk1977} {t1 1 2 t1'x1 3 4 5 6 7}
719fd2a9a0Sdanielk1977do_test alter-1.2 {
7253c0f748Sdanielk1977  execsql [subst {
7353c0f748Sdanielk1977    CREATE $::temp TABLE objlist(type, name, tbl_name);
7453c0f748Sdanielk1977    INSERT INTO objlist SELECT type, name, tbl_name
7553c0f748Sdanielk1977        FROM sqlite_master WHERE NAME!='objlist';
7653c0f748Sdanielk1977  }]
7753c0f748Sdanielk1977  ifcapable tempdb {
789fd2a9a0Sdanielk1977    execsql {
7953c0f748Sdanielk1977      INSERT INTO objlist SELECT type, name, tbl_name
80e0a04a36Sdrh          FROM temp.sqlite_master WHERE NAME!='objlist';
8153c0f748Sdanielk1977    }
8253c0f748Sdanielk1977  }
8353c0f748Sdanielk1977
8453c0f748Sdanielk1977  execsql {
8527c77438Sdanielk1977    SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name;
869fd2a9a0Sdanielk1977  }
879fd2a9a0Sdanielk1977} [list \
889fd2a9a0Sdanielk1977     table t1                              t1             \
899fd2a9a0Sdanielk1977     index t1i1                            t1             \
909fd2a9a0Sdanielk1977     index t1i2                            t1             \
919fd2a9a0Sdanielk1977     table t1'x1                           t1'x1          \
929fd2a9a0Sdanielk1977     index i3                              t1'x1          \
939fd2a9a0Sdanielk1977     index {sqlite_autoindex_t1'x1_1}      t1'x1          \
949fd2a9a0Sdanielk1977     index {sqlite_autoindex_t1'x1_2}      t1'x1          \
959fd2a9a0Sdanielk1977     table {temp table}                    {temp table}   \
969fd2a9a0Sdanielk1977     index i2                              {temp table}   \
979fd2a9a0Sdanielk1977     index {sqlite_autoindex_temp table_1} {temp table}   \
989fd2a9a0Sdanielk1977  ]
999fd2a9a0Sdanielk1977
1009fd2a9a0Sdanielk1977# Make some changes
1019fd2a9a0Sdanielk1977#
1024e5dd851Sdrhintegrity_check alter-1.3.0
1039fd2a9a0Sdanielk1977do_test alter-1.3 {
1049fd2a9a0Sdanielk1977  execsql {
1059fd2a9a0Sdanielk1977    ALTER TABLE [T1] RENAME to [-t1-];
1069fd2a9a0Sdanielk1977    ALTER TABLE "t1'x1" RENAME TO T2;
1079fd2a9a0Sdanielk1977    ALTER TABLE [temp table] RENAME to TempTab;
1089fd2a9a0Sdanielk1977  }
1099fd2a9a0Sdanielk1977} {}
1109fd2a9a0Sdanielk1977integrity_check alter-1.3.1
1119fd2a9a0Sdanielk1977do_test alter-1.4 {
1129fd2a9a0Sdanielk1977  execsql {
11327c77438Sdanielk1977    SELECT 't1', * FROM [-t1-];
11427c77438Sdanielk1977    SELECT 't2', * FROM t2;
11527c77438Sdanielk1977    SELECT * FROM temptab;
1169fd2a9a0Sdanielk1977  }
1179fd2a9a0Sdanielk1977} {t1 1 2 t2 3 4 5 6 7}
1189fd2a9a0Sdanielk1977do_test alter-1.5 {
1199fd2a9a0Sdanielk1977  execsql {
12027c77438Sdanielk1977    DELETE FROM objlist;
12153c0f748Sdanielk1977    INSERT INTO objlist SELECT type, name, tbl_name
12253c0f748Sdanielk1977        FROM sqlite_master WHERE NAME!='objlist';
12353c0f748Sdanielk1977  }
12453c0f748Sdanielk1977  catchsql {
12553c0f748Sdanielk1977    INSERT INTO objlist SELECT type, name, tbl_name
12653c0f748Sdanielk1977        FROM sqlite_temp_master WHERE NAME!='objlist';
12753c0f748Sdanielk1977  }
12853c0f748Sdanielk1977  execsql {
12927c77438Sdanielk1977    SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name;
1309fd2a9a0Sdanielk1977  }
1319fd2a9a0Sdanielk1977} [list \
1329fd2a9a0Sdanielk1977     table -t1-                         -t1-        \
1339fd2a9a0Sdanielk1977     index t1i1                         -t1-        \
1349fd2a9a0Sdanielk1977     index t1i2                         -t1-        \
1359fd2a9a0Sdanielk1977     table T2                           T2          \
1369fd2a9a0Sdanielk1977     index i3                           T2          \
1379fd2a9a0Sdanielk1977     index {sqlite_autoindex_T2_1}      T2          \
1389fd2a9a0Sdanielk1977     index {sqlite_autoindex_T2_2}      T2          \
1399fd2a9a0Sdanielk1977     table {TempTab}                    {TempTab}   \
1409fd2a9a0Sdanielk1977     index i2                           {TempTab}   \
1419fd2a9a0Sdanielk1977     index {sqlite_autoindex_TempTab_1} {TempTab}   \
1429fd2a9a0Sdanielk1977  ]
1439fd2a9a0Sdanielk1977
1449fd2a9a0Sdanielk1977# Make sure the changes persist after restarting the database.
1459fd2a9a0Sdanielk1977# (The TEMP table will not persist, of course.)
1469fd2a9a0Sdanielk1977#
14753c0f748Sdanielk1977ifcapable tempdb {
1489fd2a9a0Sdanielk1977  do_test alter-1.6 {
1499fd2a9a0Sdanielk1977    db close
150dddca286Sdrh    sqlite3 db test.db
151dddca286Sdrh    set DB [sqlite3_connection_pointer db]
1529fd2a9a0Sdanielk1977    execsql {
15327c77438Sdanielk1977      CREATE TEMP TABLE objlist(type, name, tbl_name);
15427c77438Sdanielk1977      INSERT INTO objlist SELECT type, name, tbl_name FROM sqlite_master;
15527c77438Sdanielk1977      INSERT INTO objlist
156e0a04a36Sdrh          SELECT type, name, tbl_name FROM temp.sqlite_master
15727c77438Sdanielk1977          WHERE NAME!='objlist';
15827c77438Sdanielk1977      SELECT type, name, tbl_name FROM objlist
15927c77438Sdanielk1977          ORDER BY tbl_name, type desc, name;
1609fd2a9a0Sdanielk1977    }
1619fd2a9a0Sdanielk1977  } [list \
1629fd2a9a0Sdanielk1977       table -t1-                         -t1-           \
1639fd2a9a0Sdanielk1977       index t1i1                         -t1-           \
1649fd2a9a0Sdanielk1977       index t1i2                         -t1-           \
1659fd2a9a0Sdanielk1977       table T2                           T2          \
1669fd2a9a0Sdanielk1977       index i3                           T2          \
1679fd2a9a0Sdanielk1977       index {sqlite_autoindex_T2_1}      T2          \
1689fd2a9a0Sdanielk1977       index {sqlite_autoindex_T2_2}      T2          \
1699fd2a9a0Sdanielk1977    ]
17053c0f748Sdanielk1977} else {
17153c0f748Sdanielk1977  execsql {
17253c0f748Sdanielk1977    DROP TABLE TempTab;
17353c0f748Sdanielk1977  }
17453c0f748Sdanielk1977}
1759fd2a9a0Sdanielk1977
176545f587fSdrh# Create bogus application-defined functions for functions used
177545f587fSdrh# internally by ALTER TABLE, to ensure that ALTER TABLE falls back
178545f587fSdrh# to the built-in functions.
179545f587fSdrh#
180545f587fSdrhproc failing_app_func {args} {error "bad function"}
181545f587fSdrhdo_test alter-1.7-prep {
182545f587fSdrh  db func substr failing_app_func
183545f587fSdrh  db func like failing_app_func
184545f587fSdrh  db func sqlite_rename_table failing_app_func
185545f587fSdrh  db func sqlite_rename_trigger failing_app_func
186545f587fSdrh  db func sqlite_rename_parent failing_app_func
187545f587fSdrh  catchsql {SELECT substr(name,1,3) FROM sqlite_master}
188545f587fSdrh} {1 {bad function}}
189545f587fSdrh
1909fd2a9a0Sdanielk1977# Make sure the ALTER TABLE statements work with the
1919fd2a9a0Sdanielk1977# non-callback API
1929fd2a9a0Sdanielk1977#
1939fd2a9a0Sdanielk1977do_test alter-1.7 {
1949fd2a9a0Sdanielk1977  stepsql $DB {
1959fd2a9a0Sdanielk1977    ALTER TABLE [-t1-] RENAME to [*t1*];
1969fd2a9a0Sdanielk1977    ALTER TABLE T2 RENAME TO [<t2>];
1979fd2a9a0Sdanielk1977  }
1989fd2a9a0Sdanielk1977  execsql {
19927c77438Sdanielk1977    DELETE FROM objlist;
20053c0f748Sdanielk1977    INSERT INTO objlist SELECT type, name, tbl_name
20153c0f748Sdanielk1977        FROM sqlite_master WHERE NAME!='objlist';
20253c0f748Sdanielk1977  }
20353c0f748Sdanielk1977  catchsql {
20453c0f748Sdanielk1977    INSERT INTO objlist SELECT type, name, tbl_name
20553c0f748Sdanielk1977        FROM sqlite_temp_master WHERE NAME!='objlist';
20653c0f748Sdanielk1977  }
20753c0f748Sdanielk1977  execsql {
20853c0f748Sdanielk1977    SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name;
2099fd2a9a0Sdanielk1977  }
2109fd2a9a0Sdanielk1977} [list \
2119fd2a9a0Sdanielk1977     table *t1*                         *t1*           \
2129fd2a9a0Sdanielk1977     index t1i1                         *t1*           \
2139fd2a9a0Sdanielk1977     index t1i2                         *t1*           \
2149fd2a9a0Sdanielk1977     table <t2>                         <t2>          \
2159fd2a9a0Sdanielk1977     index i3                           <t2>          \
2169fd2a9a0Sdanielk1977     index {sqlite_autoindex_<t2>_1}    <t2>          \
2179fd2a9a0Sdanielk1977     index {sqlite_autoindex_<t2>_2}    <t2>          \
2189fd2a9a0Sdanielk1977  ]
2199fd2a9a0Sdanielk1977
2201c8c23ccSdanielk1977# Check that ALTER TABLE works on attached databases.
2211c8c23ccSdanielk1977#
2225a8f9374Sdanielk1977ifcapable attach {
2231c8c23ccSdanielk1977  do_test alter-1.8.1 {
224fda06befSmistachkin    forcedelete test2.db
225fda06befSmistachkin    forcedelete test2.db-journal
2261c8c23ccSdanielk1977    execsql {
2271c8c23ccSdanielk1977      ATTACH 'test2.db' AS aux;
2281c8c23ccSdanielk1977    }
2291c8c23ccSdanielk1977  } {}
2301c8c23ccSdanielk1977  do_test alter-1.8.2 {
2311c8c23ccSdanielk1977    execsql {
2321c8c23ccSdanielk1977      CREATE TABLE t4(a PRIMARY KEY, b, c);
2331c8c23ccSdanielk1977      CREATE TABLE aux.t4(a PRIMARY KEY, b, c);
2341c8c23ccSdanielk1977      CREATE INDEX i4 ON t4(b);
2352b6d46b9Sdanielk1977      CREATE INDEX aux.i4 ON t4(b);
2361c8c23ccSdanielk1977    }
2371c8c23ccSdanielk1977  } {}
2381c8c23ccSdanielk1977  do_test alter-1.8.3 {
2391c8c23ccSdanielk1977    execsql {
2401c8c23ccSdanielk1977      INSERT INTO t4 VALUES('main', 'main', 'main');
2411c8c23ccSdanielk1977      INSERT INTO aux.t4 VALUES('aux', 'aux', 'aux');
2421c8c23ccSdanielk1977      SELECT * FROM t4 WHERE a = 'main';
2431c8c23ccSdanielk1977    }
2441c8c23ccSdanielk1977  } {main main main}
2451c8c23ccSdanielk1977  do_test alter-1.8.4 {
2461c8c23ccSdanielk1977    execsql {
2471c8c23ccSdanielk1977      ALTER TABLE t4 RENAME TO t5;
2481c8c23ccSdanielk1977      SELECT * FROM t4 WHERE a = 'aux';
2491c8c23ccSdanielk1977    }
2501c8c23ccSdanielk1977  } {aux aux aux}
2511c8c23ccSdanielk1977  do_test alter-1.8.5 {
2521c8c23ccSdanielk1977    execsql {
2531c8c23ccSdanielk1977      SELECT * FROM t5;
2541c8c23ccSdanielk1977    }
2551c8c23ccSdanielk1977  } {main main main}
2561c8c23ccSdanielk1977  do_test alter-1.8.6 {
2571c8c23ccSdanielk1977    execsql {
2581c8c23ccSdanielk1977      SELECT * FROM t5 WHERE b = 'main';
2591c8c23ccSdanielk1977    }
2601c8c23ccSdanielk1977  } {main main main}
2611c8c23ccSdanielk1977  do_test alter-1.8.7 {
2621c8c23ccSdanielk1977    execsql {
2631c8c23ccSdanielk1977      ALTER TABLE aux.t4 RENAME TO t5;
2641c8c23ccSdanielk1977      SELECT * FROM aux.t5 WHERE b = 'aux';
2651c8c23ccSdanielk1977    }
2661c8c23ccSdanielk1977  } {aux aux aux}
2675a8f9374Sdanielk1977}
2689fd2a9a0Sdanielk1977
269343e9261Sdanielk1977do_test alter-1.9.1 {
270343e9261Sdanielk1977  execsql {
271343e9261Sdanielk1977    CREATE TABLE tbl1   (a, b, c);
272343e9261Sdanielk1977    INSERT INTO tbl1 VALUES(1, 2, 3);
273343e9261Sdanielk1977  }
274343e9261Sdanielk1977} {}
275343e9261Sdanielk1977do_test alter-1.9.2 {
276343e9261Sdanielk1977  execsql {
277343e9261Sdanielk1977    SELECT * FROM tbl1;
278343e9261Sdanielk1977  }
279343e9261Sdanielk1977} {1 2 3}
280343e9261Sdanielk1977do_test alter-1.9.3 {
281343e9261Sdanielk1977  execsql {
282343e9261Sdanielk1977    ALTER TABLE tbl1 RENAME TO tbl2;
283343e9261Sdanielk1977    SELECT * FROM tbl2;
284343e9261Sdanielk1977  }
285343e9261Sdanielk1977} {1 2 3}
286343e9261Sdanielk1977do_test alter-1.9.4 {
287343e9261Sdanielk1977  execsql {
288343e9261Sdanielk1977    DROP TABLE tbl2;
289343e9261Sdanielk1977  }
290343e9261Sdanielk1977} {}
291343e9261Sdanielk1977
2929fd2a9a0Sdanielk1977# Test error messages
2939fd2a9a0Sdanielk1977#
2949fd2a9a0Sdanielk1977do_test alter-2.1 {
2959fd2a9a0Sdanielk1977  catchsql {
2969fd2a9a0Sdanielk1977    ALTER TABLE none RENAME TO hi;
2979fd2a9a0Sdanielk1977  }
2989fd2a9a0Sdanielk1977} {1 {no such table: none}}
2999fd2a9a0Sdanielk1977do_test alter-2.2 {
3009fd2a9a0Sdanielk1977  execsql {
3019fd2a9a0Sdanielk1977    CREATE TABLE t3(p,q,r);
3029fd2a9a0Sdanielk1977  }
3039fd2a9a0Sdanielk1977  catchsql {
3049fd2a9a0Sdanielk1977    ALTER TABLE [<t2>] RENAME TO t3;
3059fd2a9a0Sdanielk1977  }
3069fd2a9a0Sdanielk1977} {1 {there is already another table or index with this name: t3}}
3079fd2a9a0Sdanielk1977do_test alter-2.3 {
3089fd2a9a0Sdanielk1977  catchsql {
3099fd2a9a0Sdanielk1977    ALTER TABLE [<t2>] RENAME TO i3;
3109fd2a9a0Sdanielk1977  }
3119fd2a9a0Sdanielk1977} {1 {there is already another table or index with this name: i3}}
312023f4176Sdanielk1977do_test alter-2.4 {
313023f4176Sdanielk1977  catchsql {
314023f4176Sdanielk1977    ALTER TABLE SqLiTe_master RENAME TO master;
315023f4176Sdanielk1977  }
316023f4176Sdanielk1977} {1 {table sqlite_master may not be altered}}
317023f4176Sdanielk1977do_test alter-2.5 {
318023f4176Sdanielk1977  catchsql {
319023f4176Sdanielk1977    ALTER TABLE t3 RENAME TO sqlite_t3;
320023f4176Sdanielk1977  }
321023f4176Sdanielk1977} {1 {object name reserved for internal use: sqlite_t3}}
3222a9abf61Sdrhdo_test alter-2.6 {
3232a9abf61Sdrh  catchsql {
3242a9abf61Sdrh    ALTER TABLE t3 ADD COLUMN (ALTER TABLE t3 ADD COLUMN);
3252a9abf61Sdrh  }
3262a9abf61Sdrh} {1 {near "(": syntax error}}
3279fd2a9a0Sdanielk1977
328aacd732bSdanielk1977# If this compilation does not include triggers, omit the alter-3.* tests.
329aacd732bSdanielk1977ifcapable trigger {
330d641d646Sdanielk1977
331343e9261Sdanielk1977#-----------------------------------------------------------------------
332343e9261Sdanielk1977# Tests alter-3.* test ALTER TABLE on tables that have triggers.
333343e9261Sdanielk1977#
334343e9261Sdanielk1977# alter-3.1.*: ALTER TABLE with triggers.
335343e9261Sdanielk1977# alter-3.2.*: Test that the ON keyword cannot be used as a database,
336343e9261Sdanielk1977#     table or column name unquoted. This is done because part of the
337343e9261Sdanielk1977#     ALTER TABLE code (specifically the implementation of SQL function
338343e9261Sdanielk1977#     "sqlite_alter_trigger") will break in this case.
339343e9261Sdanielk1977# alter-3.3.*: ALTER TABLE with TEMP triggers (todo).
340343e9261Sdanielk1977#
341343e9261Sdanielk1977
342d641d646Sdanielk1977# An SQL user-function for triggers to fire, so that we know they
343d641d646Sdanielk1977# are working.
344d641d646Sdanielk1977proc trigfunc {args} {
345d641d646Sdanielk1977  set ::TRIGGER $args
346d641d646Sdanielk1977}
347d641d646Sdanielk1977db func trigfunc trigfunc
348d641d646Sdanielk1977
349d641d646Sdanielk1977do_test alter-3.1.0 {
350d641d646Sdanielk1977  execsql {
351d641d646Sdanielk1977    CREATE TABLE t6(a, b, c);
35201522687Sdrh    -- Different case for the table name in the trigger.
35301522687Sdrh    CREATE TRIGGER trig1 AFTER INSERT ON T6 BEGIN
354d641d646Sdanielk1977      SELECT trigfunc('trig1', new.a, new.b, new.c);
355d641d646Sdanielk1977    END;
356d641d646Sdanielk1977  }
357d641d646Sdanielk1977} {}
358d641d646Sdanielk1977do_test alter-3.1.1 {
359d641d646Sdanielk1977  execsql {
360d641d646Sdanielk1977    INSERT INTO t6 VALUES(1, 2, 3);
361d641d646Sdanielk1977  }
362d641d646Sdanielk1977  set ::TRIGGER
363d641d646Sdanielk1977} {trig1 1 2 3}
364d641d646Sdanielk1977do_test alter-3.1.2 {
365d641d646Sdanielk1977  execsql {
366d641d646Sdanielk1977    ALTER TABLE t6 RENAME TO t7;
367d641d646Sdanielk1977    INSERT INTO t7 VALUES(4, 5, 6);
368d641d646Sdanielk1977  }
369d641d646Sdanielk1977  set ::TRIGGER
370d641d646Sdanielk1977} {trig1 4 5 6}
371d641d646Sdanielk1977do_test alter-3.1.3 {
372d641d646Sdanielk1977  execsql {
373d641d646Sdanielk1977    DROP TRIGGER trig1;
374d641d646Sdanielk1977  }
375d641d646Sdanielk1977} {}
376d641d646Sdanielk1977do_test alter-3.1.4 {
377d641d646Sdanielk1977  execsql {
378d641d646Sdanielk1977    CREATE TRIGGER trig2 AFTER INSERT ON main.t7 BEGIN
379d641d646Sdanielk1977      SELECT trigfunc('trig2', new.a, new.b, new.c);
380d641d646Sdanielk1977    END;
381d641d646Sdanielk1977    INSERT INTO t7 VALUES(1, 2, 3);
382d641d646Sdanielk1977  }
383d641d646Sdanielk1977  set ::TRIGGER
384d641d646Sdanielk1977} {trig2 1 2 3}
385d641d646Sdanielk1977do_test alter-3.1.5 {
386d641d646Sdanielk1977  execsql {
387d641d646Sdanielk1977    ALTER TABLE t7 RENAME TO t8;
388d641d646Sdanielk1977    INSERT INTO t8 VALUES(4, 5, 6);
389d641d646Sdanielk1977  }
390d641d646Sdanielk1977  set ::TRIGGER
391d641d646Sdanielk1977} {trig2 4 5 6}
392d641d646Sdanielk1977do_test alter-3.1.6 {
393d641d646Sdanielk1977  execsql {
394d641d646Sdanielk1977    DROP TRIGGER trig2;
395d641d646Sdanielk1977  }
396d641d646Sdanielk1977} {}
397d641d646Sdanielk1977do_test alter-3.1.7 {
398d641d646Sdanielk1977  execsql {
399d641d646Sdanielk1977    CREATE TRIGGER trig3 AFTER INSERT ON main.'t8'BEGIN
400d641d646Sdanielk1977      SELECT trigfunc('trig3', new.a, new.b, new.c);
401d641d646Sdanielk1977    END;
402d641d646Sdanielk1977    INSERT INTO t8 VALUES(1, 2, 3);
403d641d646Sdanielk1977  }
404d641d646Sdanielk1977  set ::TRIGGER
405d641d646Sdanielk1977} {trig3 1 2 3}
406d641d646Sdanielk1977do_test alter-3.1.8 {
407d641d646Sdanielk1977  execsql {
408d641d646Sdanielk1977    ALTER TABLE t8 RENAME TO t9;
409d641d646Sdanielk1977    INSERT INTO t9 VALUES(4, 5, 6);
410d641d646Sdanielk1977  }
411d641d646Sdanielk1977  set ::TRIGGER
412d641d646Sdanielk1977} {trig3 4 5 6}
413d641d646Sdanielk1977
414d641d646Sdanielk1977# Make sure "ON" cannot be used as a database, table or column name without
415d641d646Sdanielk1977# quoting. Otherwise the sqlite_alter_trigger() function might not work.
416fda06befSmistachkinforcedelete test3.db
417fda06befSmistachkinforcedelete test3.db-journal
4185a8f9374Sdanielk1977ifcapable attach {
419d641d646Sdanielk1977  do_test alter-3.2.1 {
420d641d646Sdanielk1977    catchsql {
421d641d646Sdanielk1977      ATTACH 'test3.db' AS ON;
422d641d646Sdanielk1977    }
423d641d646Sdanielk1977  } {1 {near "ON": syntax error}}
424d641d646Sdanielk1977  do_test alter-3.2.2 {
425d641d646Sdanielk1977    catchsql {
426d641d646Sdanielk1977      ATTACH 'test3.db' AS 'ON';
427d641d646Sdanielk1977    }
428d641d646Sdanielk1977  } {0 {}}
429d641d646Sdanielk1977  do_test alter-3.2.3 {
430d641d646Sdanielk1977    catchsql {
431d641d646Sdanielk1977      CREATE TABLE ON.t1(a, b, c);
432d641d646Sdanielk1977    }
433d641d646Sdanielk1977  } {1 {near "ON": syntax error}}
434d641d646Sdanielk1977  do_test alter-3.2.4 {
435d641d646Sdanielk1977    catchsql {
436d641d646Sdanielk1977      CREATE TABLE 'ON'.t1(a, b, c);
437d641d646Sdanielk1977    }
438d641d646Sdanielk1977  } {0 {}}
439d641d646Sdanielk1977  do_test alter-3.2.4 {
440d641d646Sdanielk1977    catchsql {
441d641d646Sdanielk1977      CREATE TABLE 'ON'.ON(a, b, c);
442d641d646Sdanielk1977    }
443d641d646Sdanielk1977  } {1 {near "ON": syntax error}}
444d641d646Sdanielk1977  do_test alter-3.2.5 {
445d641d646Sdanielk1977    catchsql {
446d641d646Sdanielk1977      CREATE TABLE 'ON'.'ON'(a, b, c);
447d641d646Sdanielk1977    }
448d641d646Sdanielk1977  } {0 {}}
4495a8f9374Sdanielk1977}
450d641d646Sdanielk1977do_test alter-3.2.6 {
451d641d646Sdanielk1977  catchsql {
452d641d646Sdanielk1977    CREATE TABLE t10(a, ON, c);
453d641d646Sdanielk1977  }
454d641d646Sdanielk1977} {1 {near "ON": syntax error}}
455d641d646Sdanielk1977do_test alter-3.2.7 {
456d641d646Sdanielk1977  catchsql {
457d641d646Sdanielk1977    CREATE TABLE t10(a, 'ON', c);
458d641d646Sdanielk1977  }
459d641d646Sdanielk1977} {0 {}}
460d641d646Sdanielk1977do_test alter-3.2.8 {
461d641d646Sdanielk1977  catchsql {
462d641d646Sdanielk1977    CREATE TRIGGER trig4 AFTER INSERT ON ON BEGIN SELECT 1; END;
463d641d646Sdanielk1977  }
464d641d646Sdanielk1977} {1 {near "ON": syntax error}}
4655a8f9374Sdanielk1977ifcapable attach {
466d641d646Sdanielk1977  do_test alter-3.2.9 {
467d641d646Sdanielk1977    catchsql {
468d641d646Sdanielk1977      CREATE TRIGGER 'on'.trig4 AFTER INSERT ON 'ON' BEGIN SELECT 1; END;
469d641d646Sdanielk1977    }
470d641d646Sdanielk1977  } {0 {}}
4715a8f9374Sdanielk1977}
472343e9261Sdanielk1977do_test alter-3.2.10 {
473343e9261Sdanielk1977  execsql {
474343e9261Sdanielk1977    DROP TABLE t10;
475343e9261Sdanielk1977  }
476343e9261Sdanielk1977} {}
477d641d646Sdanielk1977
478343e9261Sdanielk1977do_test alter-3.3.1 {
47953c0f748Sdanielk1977  execsql [subst {
480343e9261Sdanielk1977    CREATE TABLE tbl1(a, b, c);
48153c0f748Sdanielk1977    CREATE $::temp TRIGGER trig1 AFTER INSERT ON tbl1 BEGIN
482343e9261Sdanielk1977      SELECT trigfunc('trig1', new.a, new.b, new.c);
483343e9261Sdanielk1977    END;
48453c0f748Sdanielk1977  }]
485343e9261Sdanielk1977} {}
486343e9261Sdanielk1977do_test alter-3.3.2 {
487343e9261Sdanielk1977  execsql {
488343e9261Sdanielk1977    INSERT INTO tbl1 VALUES('a', 'b', 'c');
489343e9261Sdanielk1977  }
490343e9261Sdanielk1977  set ::TRIGGER
491343e9261Sdanielk1977} {trig1 a b c}
492343e9261Sdanielk1977do_test alter-3.3.3 {
493343e9261Sdanielk1977  execsql {
494343e9261Sdanielk1977    ALTER TABLE tbl1 RENAME TO tbl2;
495343e9261Sdanielk1977    INSERT INTO tbl2 VALUES('d', 'e', 'f');
496343e9261Sdanielk1977  }
497343e9261Sdanielk1977  set ::TRIGGER
498343e9261Sdanielk1977} {trig1 d e f}
499343e9261Sdanielk1977do_test alter-3.3.4 {
50053c0f748Sdanielk1977  execsql [subst {
50153c0f748Sdanielk1977    CREATE $::temp TRIGGER trig2 AFTER UPDATE ON tbl2 BEGIN
502343e9261Sdanielk1977      SELECT trigfunc('trig2', new.a, new.b, new.c);
503343e9261Sdanielk1977    END;
50453c0f748Sdanielk1977  }]
505343e9261Sdanielk1977} {}
506343e9261Sdanielk1977do_test alter-3.3.5 {
507343e9261Sdanielk1977  execsql {
508343e9261Sdanielk1977    ALTER TABLE tbl2 RENAME TO tbl3;
509343e9261Sdanielk1977    INSERT INTO tbl3 VALUES('g', 'h', 'i');
510343e9261Sdanielk1977  }
511343e9261Sdanielk1977  set ::TRIGGER
512343e9261Sdanielk1977} {trig1 g h i}
513343e9261Sdanielk1977do_test alter-3.3.6 {
514343e9261Sdanielk1977  execsql {
515343e9261Sdanielk1977    UPDATE tbl3 SET a = 'G' where a = 'g';
516343e9261Sdanielk1977  }
517343e9261Sdanielk1977  set ::TRIGGER
518343e9261Sdanielk1977} {trig2 G h i}
519343e9261Sdanielk1977do_test alter-3.3.7 {
520343e9261Sdanielk1977  execsql {
521343e9261Sdanielk1977    DROP TABLE tbl3;
52253c0f748Sdanielk1977  }
52353c0f748Sdanielk1977} {}
52453c0f748Sdanielk1977ifcapable tempdb {
52553c0f748Sdanielk1977  do_test alter-3.3.8 {
52653c0f748Sdanielk1977    execsql {
527e0a04a36Sdrh      SELECT * FROM temp.sqlite_master WHERE type = 'trigger';
528343e9261Sdanielk1977    }
529343e9261Sdanielk1977  } {}
53053c0f748Sdanielk1977}
531343e9261Sdanielk1977
532aacd732bSdanielk1977} ;# ifcapable trigger
533aacd732bSdanielk1977
534aacd732bSdanielk1977# If the build does not include AUTOINCREMENT fields, omit alter-4.*.
535aacd732bSdanielk1977ifcapable autoinc {
536aacd732bSdanielk1977
537aacd732bSdanielk1977do_test alter-4.1 {
538aacd732bSdanielk1977  execsql {
539aacd732bSdanielk1977    CREATE TABLE tbl1(a INTEGER PRIMARY KEY AUTOINCREMENT);
540aacd732bSdanielk1977    INSERT INTO tbl1 VALUES(10);
541aacd732bSdanielk1977  }
542aacd732bSdanielk1977} {}
543aacd732bSdanielk1977do_test alter-4.2 {
544aacd732bSdanielk1977  execsql {
545aacd732bSdanielk1977    INSERT INTO tbl1 VALUES(NULL);
546aacd732bSdanielk1977    SELECT a FROM tbl1;
547aacd732bSdanielk1977  }
548aacd732bSdanielk1977} {10 11}
549aacd732bSdanielk1977do_test alter-4.3 {
550aacd732bSdanielk1977  execsql {
551aacd732bSdanielk1977    ALTER TABLE tbl1 RENAME TO tbl2;
552aacd732bSdanielk1977    DELETE FROM tbl2;
553aacd732bSdanielk1977    INSERT INTO tbl2 VALUES(NULL);
554aacd732bSdanielk1977    SELECT a FROM tbl2;
555aacd732bSdanielk1977  }
556aacd732bSdanielk1977} {12}
55781e9674bSdanielk1977do_test alter-4.4 {
55881e9674bSdanielk1977  execsql {
55981e9674bSdanielk1977    DROP TABLE tbl2;
56081e9674bSdanielk1977  }
56181e9674bSdanielk1977} {}
562aacd732bSdanielk1977
563aacd732bSdanielk1977} ;# ifcapable autoinc
564aacd732bSdanielk1977
56581e9674bSdanielk1977# Test that it is Ok to execute an ALTER TABLE immediately after
56681e9674bSdanielk1977# opening a database.
56781e9674bSdanielk1977do_test alter-5.1 {
56881e9674bSdanielk1977  execsql {
56981e9674bSdanielk1977    CREATE TABLE tbl1(a, b, c);
57081e9674bSdanielk1977    INSERT INTO tbl1 VALUES('x', 'y', 'z');
57181e9674bSdanielk1977  }
57281e9674bSdanielk1977} {}
57381e9674bSdanielk1977do_test alter-5.2 {
57481e9674bSdanielk1977  sqlite3 db2 test.db
57581e9674bSdanielk1977  execsql {
57681e9674bSdanielk1977    ALTER TABLE tbl1 RENAME TO tbl2;
57781e9674bSdanielk1977    SELECT * FROM tbl2;
57881e9674bSdanielk1977  } db2
57981e9674bSdanielk1977} {x y z}
58081e9674bSdanielk1977do_test alter-5.3 {
58181e9674bSdanielk1977  db2 close
58281e9674bSdanielk1977} {}
58381e9674bSdanielk1977
584819d7f47Sdanielk1977foreach tblname [execsql {
585545f587fSdrh  SELECT name FROM sqlite_master
586545f587fSdrh   WHERE type='table' AND name NOT GLOB 'sqlite*'
587819d7f47Sdanielk1977}] {
588819d7f47Sdanielk1977  execsql "DROP TABLE \"$tblname\""
589819d7f47Sdanielk1977}
590819d7f47Sdanielk1977
59179f27df6Sdanielk1977set ::tbl_name "abc\uABCDdef"
592819d7f47Sdanielk1977do_test alter-6.1 {
59379f27df6Sdanielk1977  string length $::tbl_name
59479f27df6Sdanielk1977} {7}
595819d7f47Sdanielk1977do_test alter-6.2 {
59679f27df6Sdanielk1977  execsql "
59779f27df6Sdanielk1977    CREATE TABLE ${tbl_name}(a, b, c);
59879f27df6Sdanielk1977  "
5991576cd92Sdanielk1977  set ::oid [execsql {SELECT max(oid) FROM sqlite_master}]
6003bdca9c9Sdanielk1977  execsql "
6011576cd92Sdanielk1977    SELECT sql FROM sqlite_master WHERE oid = $::oid;
6023bdca9c9Sdanielk1977  "
60379f27df6Sdanielk1977} "{CREATE TABLE ${::tbl_name}(a, b, c)}"
604819d7f47Sdanielk1977execsql "
605819d7f47Sdanielk1977  SELECT * FROM ${::tbl_name}
606819d7f47Sdanielk1977"
60779f27df6Sdanielk1977set ::tbl_name2 "abcXdef"
608819d7f47Sdanielk1977do_test alter-6.3 {
60979f27df6Sdanielk1977  execsql "
61079f27df6Sdanielk1977    ALTER TABLE $::tbl_name RENAME TO $::tbl_name2
61179f27df6Sdanielk1977  "
6123bdca9c9Sdanielk1977  execsql "
6133bdca9c9Sdanielk1977    SELECT sql FROM sqlite_master WHERE oid = $::oid
6143bdca9c9Sdanielk1977  "
6158e5b5f8eSdrh} "{CREATE TABLE \"${::tbl_name2}\"(a, b, c)}"
616819d7f47Sdanielk1977do_test alter-6.4 {
61779f27df6Sdanielk1977  execsql "
61879f27df6Sdanielk1977    ALTER TABLE $::tbl_name2 RENAME TO $::tbl_name
61979f27df6Sdanielk1977  "
6203bdca9c9Sdanielk1977  execsql "
6213bdca9c9Sdanielk1977    SELECT sql FROM sqlite_master WHERE oid = $::oid
6223bdca9c9Sdanielk1977  "
6238e5b5f8eSdrh} "{CREATE TABLE \"${::tbl_name}\"(a, b, c)}"
62479f27df6Sdanielk1977set ::col_name ghi\1234\jkl
625819d7f47Sdanielk1977do_test alter-6.5 {
62679f27df6Sdanielk1977  execsql "
62779f27df6Sdanielk1977    ALTER TABLE $::tbl_name ADD COLUMN $::col_name VARCHAR
62879f27df6Sdanielk1977  "
6293bdca9c9Sdanielk1977  execsql "
6303bdca9c9Sdanielk1977    SELECT sql FROM sqlite_master WHERE oid = $::oid
6313bdca9c9Sdanielk1977  "
6328e5b5f8eSdrh} "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR)}"
63379f27df6Sdanielk1977set ::col_name2 B\3421\A
634819d7f47Sdanielk1977do_test alter-6.6 {
63579f27df6Sdanielk1977  db close
63679f27df6Sdanielk1977  sqlite3 db test.db
63779f27df6Sdanielk1977  execsql "
63879f27df6Sdanielk1977    ALTER TABLE $::tbl_name ADD COLUMN $::col_name2
63979f27df6Sdanielk1977  "
6403bdca9c9Sdanielk1977  execsql "
6413bdca9c9Sdanielk1977    SELECT sql FROM sqlite_master WHERE oid = $::oid
6423bdca9c9Sdanielk1977  "
6438e5b5f8eSdrh} "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR, $::col_name2)}"
644819d7f47Sdanielk1977do_test alter-6.7 {
64579f27df6Sdanielk1977  execsql "
64679f27df6Sdanielk1977    INSERT INTO ${::tbl_name} VALUES(1, 2, 3, 4, 5);
64779f27df6Sdanielk1977    SELECT $::col_name, $::col_name2 FROM $::tbl_name;
64879f27df6Sdanielk1977  "
64979f27df6Sdanielk1977} {4 5}
65079f27df6Sdanielk1977
651ff22e18bSdrh# Ticket #1665:  Make sure ALTER TABLE ADD COLUMN works on a table
652ff22e18bSdrh# that includes a COLLATE clause.
653ff22e18bSdrh#
65433f5379cSdando_realnum_test alter-7.1 {
655ff22e18bSdrh  execsql {
656ff22e18bSdrh    CREATE TABLE t1(a TEXT COLLATE BINARY);
657ff22e18bSdrh    ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE;
65805f7c19aSdrh    INSERT INTO t1 VALUES(1,'-2');
659598f1340Sdrh    INSERT INTO t1 VALUES(5.4e-08,'5.4e-08');
660ff22e18bSdrh    SELECT typeof(a), a, typeof(b), b FROM t1;
661ff22e18bSdrh  }
662598f1340Sdrh} {text 1 integer -2 text 5.4e-08 real 5.4e-08}
66379f27df6Sdanielk1977
664945498f3Sdrh# Make sure that when a column is added by ALTER TABLE ADD COLUMN and has
665945498f3Sdrh# a default value that the default value is used by aggregate functions.
666945498f3Sdrh#
667945498f3Sdrhdo_test alter-8.1 {
668945498f3Sdrh  execsql {
669945498f3Sdrh    CREATE TABLE t2(a INTEGER);
670945498f3Sdrh    INSERT INTO t2 VALUES(1);
671945498f3Sdrh    INSERT INTO t2 VALUES(1);
672945498f3Sdrh    INSERT INTO t2 VALUES(2);
673945498f3Sdrh    ALTER TABLE t2 ADD COLUMN b INTEGER DEFAULT 9;
674945498f3Sdrh    SELECT sum(b) FROM t2;
675945498f3Sdrh  }
676945498f3Sdrh} {27}
677945498f3Sdrhdo_test alter-8.2 {
678945498f3Sdrh  execsql {
679945498f3Sdrh    SELECT a, sum(b) FROM t2 GROUP BY a;
680945498f3Sdrh  }
681945498f3Sdrh} {1 18 2 9}
682945498f3Sdrh
683dce872b9Sdanielk1977#--------------------------------------------------------------------------
684141e119aSdan# alter-9.X - Special test: Make sure the sqlite_rename_column() and
685dce872b9Sdanielk1977# rename_table() functions do not crash when handed bad input.
686dce872b9Sdanielk1977#
687171c50ecSdrhsqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
688dce872b9Sdanielk1977do_test alter-9.1 {
689b87a9a8aSdan  execsql {SELECT SQLITE_RENAME_COLUMN(0,0,0,0,0,0,0,0,0)}
690dce872b9Sdanielk1977} {{}}
691141e119aSdanforeach {tn sql} {
69265372fa9Sdan    1 { SELECT SQLITE_RENAME_TABLE(0,0,0,0,0,0,0) }
69365372fa9Sdan    2 { SELECT SQLITE_RENAME_TABLE(10,20,30,40,50,60,70) }
69465372fa9Sdan    3 { SELECT SQLITE_RENAME_TABLE('foo','foo','foo','foo','foo','foo','foo') }
695141e119aSdan} {
69665372fa9Sdan  do_test alter-9.2.$tn {
69765372fa9Sdan    catch { execsql $sql }
69865372fa9Sdan  } 1
699dce872b9Sdanielk1977}
700171c50ecSdrhsqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
701eea8eb6dSdrh
702eea8eb6dSdrh# If the INTERNAL_FUNCTIONS test-control is disabled (which is the default),
703eea8eb6dSdrh# then the sqlite_rename_table() SQL function is not accessible to ordinary SQL.
704eea8eb6dSdrh#
705eea8eb6dSdrhdo_catchsql_test alter-9.3 {
706eea8eb6dSdrh  SELECT sqlite_rename_table(0,0,0,0,0,0,0);
707eea8eb6dSdrh} {1 {no such function: sqlite_rename_table}}
708dce872b9Sdanielk1977
7094e5dd851Sdrh#------------------------------------------------------------------------
7104e5dd851Sdrh# alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters
7114e5dd851Sdrh# in the names.
7124e5dd851Sdrh#
7134e5dd851Sdrhdo_test alter-10.1 {
7144e5dd851Sdrh  execsql "CREATE TABLE xyz(x UNIQUE)"
7154e5dd851Sdrh  execsql "ALTER TABLE xyz RENAME TO xyz\u1234abc"
716545f587fSdrh  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
7174e5dd851Sdrh} [list xyz\u1234abc]
7184e5dd851Sdrhdo_test alter-10.2 {
719545f587fSdrh  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
7204e5dd851Sdrh} [list sqlite_autoindex_xyz\u1234abc_1]
7214e5dd851Sdrhdo_test alter-10.3 {
7224e5dd851Sdrh  execsql "ALTER TABLE xyz\u1234abc RENAME TO xyzabc"
723545f587fSdrh  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
7244e5dd851Sdrh} [list xyzabc]
7254e5dd851Sdrhdo_test alter-10.4 {
726545f587fSdrh  execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
7274e5dd851Sdrh} [list sqlite_autoindex_xyzabc_1]
7284e5dd851Sdrh
7294e5dd851Sdrhdo_test alter-11.1 {
7304e5dd851Sdrh  sqlite3_exec db {CREATE TABLE t11(%c6%c6)}
7314e5dd851Sdrh  execsql {
7324e5dd851Sdrh    ALTER TABLE t11 ADD COLUMN abc;
7334e5dd851Sdrh  }
7344e5dd851Sdrh  catchsql {
7354e5dd851Sdrh    ALTER TABLE t11 ADD COLUMN abc;
7364e5dd851Sdrh  }
7374e5dd851Sdrh} {1 {duplicate column name: abc}}
7387e326c09Sdrhset isutf16 [regexp 16 [db one {PRAGMA encoding}]]
7397e326c09Sdrhif {!$isutf16} {
740eab7f3feSdrh  do_test alter-11.2 {
7419a087a99Sdrh    execsql {INSERT INTO t11 VALUES(1,2)}
7429a087a99Sdrh    sqlite3_exec db {SELECT %c6%c6 AS xyz, abc FROM t11}
7439a087a99Sdrh  } {0 {xyz abc 1 2}}
7447e326c09Sdrh}
7459a087a99Sdrhdo_test alter-11.3 {
746eab7f3feSdrh  sqlite3_exec db {CREATE TABLE t11b("%81%82%83" text)}
747eab7f3feSdrh  execsql {
748eab7f3feSdrh    ALTER TABLE t11b ADD COLUMN abc;
749eab7f3feSdrh  }
750eab7f3feSdrh  catchsql {
751eab7f3feSdrh    ALTER TABLE t11b ADD COLUMN abc;
752eab7f3feSdrh  }
753eab7f3feSdrh} {1 {duplicate column name: abc}}
7547e326c09Sdrhif {!$isutf16} {
7559a087a99Sdrh  do_test alter-11.4 {
7569a087a99Sdrh    execsql {INSERT INTO t11b VALUES(3,4)}
7579a087a99Sdrh    sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11b}
7589a087a99Sdrh  } {0 {xyz abc 3 4}}
7599a087a99Sdrh  do_test alter-11.5 {
7609a087a99Sdrh    sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11b}
7619a087a99Sdrh  } {0 {xyz abc 3 4}}
7629a087a99Sdrh  do_test alter-11.6 {
7639a087a99Sdrh    sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11b}
7649a087a99Sdrh  } {0 {xyz abc 3 4}}
7657e326c09Sdrh}
7669a087a99Sdrhdo_test alter-11.7 {
7679a087a99Sdrh  sqlite3_exec db {CREATE TABLE t11c(%81%82%83 text)}
7689a087a99Sdrh  execsql {
7699a087a99Sdrh    ALTER TABLE t11c ADD COLUMN abc;
7709a087a99Sdrh  }
7719a087a99Sdrh  catchsql {
7729a087a99Sdrh    ALTER TABLE t11c ADD COLUMN abc;
7739a087a99Sdrh  }
7749a087a99Sdrh} {1 {duplicate column name: abc}}
7757e326c09Sdrhif {!$isutf16} {
7769a087a99Sdrh  do_test alter-11.8 {
7779a087a99Sdrh    execsql {INSERT INTO t11c VALUES(5,6)}
7789a087a99Sdrh    sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11c}
7799a087a99Sdrh  } {0 {xyz abc 5 6}}
7809a087a99Sdrh  do_test alter-11.9 {
7819a087a99Sdrh    sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11c}
7829a087a99Sdrh  } {0 {xyz abc 5 6}}
7839a087a99Sdrh  do_test alter-11.10 {
7849a087a99Sdrh    sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11c}
7859a087a99Sdrh  } {0 {xyz abc 5 6}}
7867e326c09Sdrh}
7879a087a99Sdrh
78861116ae1Sdanielk1977do_test alter-12.1 {
78961116ae1Sdanielk1977  execsql {
79061116ae1Sdanielk1977    CREATE TABLE t12(a, b, c);
79161116ae1Sdanielk1977    CREATE VIEW v1 AS SELECT * FROM t12;
79261116ae1Sdanielk1977  }
79361116ae1Sdanielk1977} {}
79461116ae1Sdanielk1977do_test alter-12.2 {
79561116ae1Sdanielk1977  catchsql {
79661116ae1Sdanielk1977    ALTER TABLE v1 RENAME TO v2;
79761116ae1Sdanielk1977  }
79861116ae1Sdanielk1977} {1 {view v1 may not be altered}}
79961116ae1Sdanielk1977do_test alter-12.3 {
80061116ae1Sdanielk1977  execsql { SELECT * FROM v1; }
80161116ae1Sdanielk1977} {}
80261116ae1Sdanielk1977do_test alter-12.4 {
80361116ae1Sdanielk1977  db close
80461116ae1Sdanielk1977  sqlite3 db test.db
80561116ae1Sdanielk1977  execsql { SELECT * FROM v1; }
80661116ae1Sdanielk1977} {}
80761116ae1Sdanielk1977do_test alter-12.5 {
80861116ae1Sdanielk1977  catchsql {
80961116ae1Sdanielk1977    ALTER TABLE v1 ADD COLUMN new_column;
81061116ae1Sdanielk1977  }
81161116ae1Sdanielk1977} {1 {Cannot add a column to a view}}
81261116ae1Sdanielk1977
81373829451Sdrh# Ticket #3102:
81473829451Sdrh# Verify that comments do not interfere with the table rename
81573829451Sdrh# algorithm.
81673829451Sdrh#
81773829451Sdrhdo_test alter-13.1 {
81873829451Sdrh  execsql {
81973829451Sdrh    CREATE TABLE /* hi */ t3102a(x);
82073829451Sdrh    CREATE TABLE t3102b -- comment
82173829451Sdrh    (y);
82273829451Sdrh    CREATE INDEX t3102c ON t3102a(x);
823545f587fSdrh    SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
82473829451Sdrh  }
82573829451Sdrh} {t3102a t3102b t3102c}
82673829451Sdrhdo_test alter-13.2 {
82773829451Sdrh  execsql {
82873829451Sdrh    ALTER TABLE t3102a RENAME TO t3102a_rename;
829545f587fSdrh    SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
83073829451Sdrh  }
83173829451Sdrh} {t3102a_rename t3102b t3102c}
83273829451Sdrhdo_test alter-13.3 {
83373829451Sdrh  execsql {
83473829451Sdrh    ALTER TABLE t3102b RENAME TO t3102b_rename;
835545f587fSdrh    SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
83673829451Sdrh  }
83773829451Sdrh} {t3102a_rename t3102b_rename t3102c}
838ff22e18bSdrh
8390388123fSdrh# Ticket #3651
8400388123fSdrhdo_test alter-14.1 {
8410388123fSdrh  catchsql {
8420388123fSdrh    CREATE TABLE t3651(a UNIQUE);
8439e5fdc41Sdrh    INSERT INTO t3651 VALUES(5);
8440388123fSdrh    ALTER TABLE t3651 ADD COLUMN b UNIQUE;
8450388123fSdrh  }
8460388123fSdrh} {1 {Cannot add a UNIQUE column}}
8470388123fSdrhdo_test alter-14.2 {
8480388123fSdrh  catchsql {
8490388123fSdrh    ALTER TABLE t3651 ADD COLUMN b PRIMARY KEY;
8500388123fSdrh  }
8510388123fSdrh} {1 {Cannot add a PRIMARY KEY column}}
8520388123fSdrh
8530388123fSdrh
854be535003Sdan#-------------------------------------------------------------------------
855be535003Sdan# Test that it is not possible to use ALTER TABLE on any system table.
856be535003Sdan#
857be535003Sdanset system_table_list {1 sqlite_master}
858be535003Sdancatchsql ANALYZE
859be535003Sdanifcapable analyze { lappend system_table_list 2 sqlite_stat1 }
860f52bb8d3Sdanifcapable stat4   { lappend system_table_list 4 sqlite_stat4 }
861be535003Sdan
862be535003Sdanforeach {tn tbl} $system_table_list {
863be535003Sdan  do_test alter-15.$tn.1 {
864be535003Sdan    catchsql "ALTER TABLE $tbl RENAME TO xyz"
865be535003Sdan  } [list 1 "table $tbl may not be altered"]
866be535003Sdan
867be535003Sdan  do_test alter-15.$tn.2 {
868be535003Sdan    catchsql "ALTER TABLE $tbl ADD COLUMN xyz"
869be535003Sdan  } [list 1 "table $tbl may not be altered"]
870be535003Sdan}
871be535003Sdan
87281eba73eSdrh#------------------------------------------------------------------------
8735969da4aSdrh# Verify that ALTER TABLE works on tables with the WITHOUT rowid option.
87481eba73eSdrh#
87581eba73eSdrhdo_execsql_test alter-16.1 {
8765969da4aSdrh  CREATE TABLE t16a(a TEXT, b REAL, c INT, PRIMARY KEY(a,b)) WITHOUT rowid;
87781eba73eSdrh  INSERT INTO t16a VALUES('abc',1.25,99);
87881eba73eSdrh  ALTER TABLE t16a ADD COLUMN d TEXT DEFAULT 'xyzzy';
87981eba73eSdrh  INSERT INTO t16a VALUES('cba',5.5,98,'fizzle');
88081eba73eSdrh  SELECT * FROM t16a ORDER BY a;
88181eba73eSdrh} {abc 1.25 99 xyzzy cba 5.5 98 fizzle}
88281eba73eSdrhdo_execsql_test alter-16.2 {
88381eba73eSdrh  ALTER TABLE t16a RENAME TO t16a_rn;
88481eba73eSdrh  SELECT * FROM t16a_rn ORDER BY a;
88581eba73eSdrh} {abc 1.25 99 xyzzy cba 5.5 98 fizzle}
886be535003Sdan
88795f78d98Sdrh# 2018-09-16 ticket b41031ea2b5372378cb3d2d43cf9fe2a4a5c2510
88895f78d98Sdrh#
88995f78d98Sdrhifcapable rtree {
89095f78d98Sdrh  db close
89195f78d98Sdrh  sqlite3 db :memory:
89295f78d98Sdrh  do_execsql_test alter-17.100 {
89395f78d98Sdrh    CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
89495f78d98Sdrh    CREATE VIRTUAL TABLE t2 USING rtree(id,x0,x1);
89595f78d98Sdrh    INSERT INTO t1 VALUES(1,'apple'),(2,'fig'),(3,'pear');
89695f78d98Sdrh    INSERT INTO t2 VALUES(1,1.0,2.0),(2,2.0,3.0),(3,1.5,3.5);
89795f78d98Sdrh    CREATE TRIGGER r1 AFTER UPDATE ON t1 BEGIN
89895f78d98Sdrh      DELETE FROM t2 WHERE id = OLD.a;
89995f78d98Sdrh    END;
90095f78d98Sdrh    ALTER TABLE t1 RENAME TO t3;
90195f78d98Sdrh    UPDATE t3 SET b='peach' WHERE a=2;
90295f78d98Sdrh    SELECT * FROM t2 ORDER BY 1;
90395f78d98Sdrh  } {1 1.0 2.0 3 1.5 3.5}
90495f78d98Sdrh}
905141e119aSdan
906e58b2b4aSdrh# 2021-03-08 dbsqlfuzz 3f0a7245b69cd08617d7d7781ebaedb0fe765a93
907e58b2b4aSdrhreset_db
908e58b2b4aSdrhdo_catchsql_test alter-18.1 {
909e58b2b4aSdrh  CREATE TABLE t1(a,b,c);
910e58b2b4aSdrh  CREATE TABLE log(a INTEGER PRIMARY KEY,b,c);
911e58b2b4aSdrh  CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
912e58b2b4aSdrh    INSERT INTO logx(a,b,c) VALUES(new.a,new.b,new.c)
913e58b2b4aSdrh    ON CONFLICT(a) DO UPDATE SET c=excluded.c, b=new.b;
914e58b2b4aSdrh  END;
915e58b2b4aSdrh  ALTER TABLE log RENAME COLUMN a TO x;
916e58b2b4aSdrh} {1 {error in trigger tr1: no such table: main.logx}}
917e58b2b4aSdrh
918*febf0352Sdrh# 2021-10-13 dbsqlfuzz e89174cbfad2d904f06b5e24df0a22510b6a1c1e
919*febf0352Sdrhreset_db
920*febf0352Sdrhdo_execsql_test alter-19.1 {
921*febf0352Sdrh  CREATE TABLE t1(x);
922*febf0352Sdrh  CREATE TABLE t2(c);
923*febf0352Sdrh  CREATE TRIGGER r1 AFTER INSERT ON t2 BEGIN
924*febf0352Sdrh    UPDATE t2 SET (c)=(
925*febf0352Sdrh       EXISTS(SELECT 1 WHERE (WITH cte1(a) AS (SELECT 1 FROM t1 WHERE (SELECT 1 WHERE (WITH cte2(b) AS (VALUES(1))SELECT b FROM cte2)))SELECT a FROM cte1))
926*febf0352Sdrh    );
927*febf0352Sdrh  END;
928*febf0352Sdrh  ALTER TABLE t2 RENAME TO t3;
929*febf0352Sdrh} {}
930*febf0352Sdrhdo_execsql_test alter-19.2 {
931*febf0352Sdrh  SELECT name FROM sqlite_schema WHERE sql LIKE '%t2%';
932*febf0352Sdrh} {}
933*febf0352Sdrhdo_execsql_test alter-19.3 {
934*febf0352Sdrh  SELECT name FROM sqlite_schema WHERE sql LIKE '%t3%' ORDER BY name;
935*febf0352Sdrh} {r1 t3}
936*febf0352Sdrh
937*febf0352Sdrh
93895f78d98Sdrhfinish_test
939