1# 2004 November 10 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#************************************************************************* 11# This file implements regression tests for SQLite library. The 12# focus of this script is testing the ALTER TABLE statement. 13# 14# $Id: alter.test,v 1.29 2008/02/09 14:30:30 drh Exp $ 15# 16 17set testdir [file dirname $argv0] 18source $testdir/tester.tcl 19 20# If SQLITE_OMIT_ALTERTABLE is defined, omit this file. 21ifcapable !altertable { 22 finish_test 23 return 24} 25 26#---------------------------------------------------------------------- 27# Test organization: 28# 29# alter-1.1.* - alter-1.7.*: Basic tests of ALTER TABLE, including tables 30# with implicit and explicit indices. These tests came from an earlier 31# fork of SQLite that also supported ALTER TABLE. 32# alter-1.8.*: Tests for ALTER TABLE when the table resides in an 33# attached database. 34# alter-1.9.*: Tests for ALTER TABLE when their is whitespace between the 35# table name and left parenthesis token. i.e: 36# "CREATE TABLE abc (a, b, c);" 37# alter-2.*: Test error conditions and messages. 38# alter-3.*: Test ALTER TABLE on tables that have TRIGGERs attached to them. 39# alter-4.*: Test ALTER TABLE on tables that have AUTOINCREMENT fields. 40# ... 41# alter-12.*: Test ALTER TABLE on views. 42# 43 44# Create some tables to rename. Be sure to include some TEMP tables 45# and some tables with odd names. 46# 47do_test alter-1.1 { 48 ifcapable tempdb { 49 set ::temp TEMP 50 } else { 51 set ::temp {} 52 } 53 execsql [subst -nocommands { 54 CREATE TABLE t1(a,b); 55 INSERT INTO t1 VALUES(1,2); 56 CREATE TABLE [t1'x1](c UNIQUE, b PRIMARY KEY); 57 INSERT INTO [t1'x1] VALUES(3,4); 58 CREATE INDEX t1i1 ON T1(B); 59 CREATE INDEX t1i2 ON t1(a,b); 60 CREATE INDEX i3 ON [t1'x1](b,c); 61 CREATE $::temp TABLE "temp table"(e,f,g UNIQUE); 62 CREATE INDEX i2 ON [temp table](f); 63 INSERT INTO [temp table] VALUES(5,6,7); 64 }] 65 execsql { 66 SELECT 't1', * FROM t1; 67 SELECT 't1''x1', * FROM "t1'x1"; 68 SELECT * FROM [temp table]; 69 } 70} {t1 1 2 t1'x1 3 4 5 6 7} 71do_test alter-1.2 { 72 execsql [subst { 73 CREATE $::temp TABLE objlist(type, name, tbl_name); 74 INSERT INTO objlist SELECT type, name, tbl_name 75 FROM sqlite_master WHERE NAME!='objlist'; 76 }] 77 ifcapable tempdb { 78 execsql { 79 INSERT INTO objlist SELECT type, name, tbl_name 80 FROM sqlite_temp_master WHERE NAME!='objlist'; 81 } 82 } 83 84 execsql { 85 SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name; 86 } 87} [list \ 88 table t1 t1 \ 89 index t1i1 t1 \ 90 index t1i2 t1 \ 91 table t1'x1 t1'x1 \ 92 index i3 t1'x1 \ 93 index {sqlite_autoindex_t1'x1_1} t1'x1 \ 94 index {sqlite_autoindex_t1'x1_2} t1'x1 \ 95 table {temp table} {temp table} \ 96 index i2 {temp table} \ 97 index {sqlite_autoindex_temp table_1} {temp table} \ 98 ] 99 100# Make some changes 101# 102integrity_check alter-1.3.0 103do_test alter-1.3 { 104 execsql { 105 ALTER TABLE [T1] RENAME to [-t1-]; 106 ALTER TABLE "t1'x1" RENAME TO T2; 107 ALTER TABLE [temp table] RENAME to TempTab; 108 } 109} {} 110integrity_check alter-1.3.1 111do_test alter-1.4 { 112 execsql { 113 SELECT 't1', * FROM [-t1-]; 114 SELECT 't2', * FROM t2; 115 SELECT * FROM temptab; 116 } 117} {t1 1 2 t2 3 4 5 6 7} 118do_test alter-1.5 { 119 execsql { 120 DELETE FROM objlist; 121 INSERT INTO objlist SELECT type, name, tbl_name 122 FROM sqlite_master WHERE NAME!='objlist'; 123 } 124 catchsql { 125 INSERT INTO objlist SELECT type, name, tbl_name 126 FROM sqlite_temp_master WHERE NAME!='objlist'; 127 } 128 execsql { 129 SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name; 130 } 131} [list \ 132 table -t1- -t1- \ 133 index t1i1 -t1- \ 134 index t1i2 -t1- \ 135 table T2 T2 \ 136 index i3 T2 \ 137 index {sqlite_autoindex_T2_1} T2 \ 138 index {sqlite_autoindex_T2_2} T2 \ 139 table {TempTab} {TempTab} \ 140 index i2 {TempTab} \ 141 index {sqlite_autoindex_TempTab_1} {TempTab} \ 142 ] 143 144# Make sure the changes persist after restarting the database. 145# (The TEMP table will not persist, of course.) 146# 147ifcapable tempdb { 148 do_test alter-1.6 { 149 db close 150 sqlite3 db test.db 151 set DB [sqlite3_connection_pointer db] 152 execsql { 153 CREATE TEMP TABLE objlist(type, name, tbl_name); 154 INSERT INTO objlist SELECT type, name, tbl_name FROM sqlite_master; 155 INSERT INTO objlist 156 SELECT type, name, tbl_name FROM sqlite_temp_master 157 WHERE NAME!='objlist'; 158 SELECT type, name, tbl_name FROM objlist 159 ORDER BY tbl_name, type desc, name; 160 } 161 } [list \ 162 table -t1- -t1- \ 163 index t1i1 -t1- \ 164 index t1i2 -t1- \ 165 table T2 T2 \ 166 index i3 T2 \ 167 index {sqlite_autoindex_T2_1} T2 \ 168 index {sqlite_autoindex_T2_2} T2 \ 169 ] 170} else { 171 execsql { 172 DROP TABLE TempTab; 173 } 174} 175 176# Make sure the ALTER TABLE statements work with the 177# non-callback API 178# 179do_test alter-1.7 { 180 stepsql $DB { 181 ALTER TABLE [-t1-] RENAME to [*t1*]; 182 ALTER TABLE T2 RENAME TO [<t2>]; 183 } 184 execsql { 185 DELETE FROM objlist; 186 INSERT INTO objlist SELECT type, name, tbl_name 187 FROM sqlite_master WHERE NAME!='objlist'; 188 } 189 catchsql { 190 INSERT INTO objlist SELECT type, name, tbl_name 191 FROM sqlite_temp_master WHERE NAME!='objlist'; 192 } 193 execsql { 194 SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name; 195 } 196} [list \ 197 table *t1* *t1* \ 198 index t1i1 *t1* \ 199 index t1i2 *t1* \ 200 table <t2> <t2> \ 201 index i3 <t2> \ 202 index {sqlite_autoindex_<t2>_1} <t2> \ 203 index {sqlite_autoindex_<t2>_2} <t2> \ 204 ] 205 206# Check that ALTER TABLE works on attached databases. 207# 208ifcapable attach { 209 do_test alter-1.8.1 { 210 file delete -force test2.db 211 file delete -force test2.db-journal 212 execsql { 213 ATTACH 'test2.db' AS aux; 214 } 215 } {} 216 do_test alter-1.8.2 { 217 execsql { 218 CREATE TABLE t4(a PRIMARY KEY, b, c); 219 CREATE TABLE aux.t4(a PRIMARY KEY, b, c); 220 CREATE INDEX i4 ON t4(b); 221 CREATE INDEX aux.i4 ON t4(b); 222 } 223 } {} 224 do_test alter-1.8.3 { 225 execsql { 226 INSERT INTO t4 VALUES('main', 'main', 'main'); 227 INSERT INTO aux.t4 VALUES('aux', 'aux', 'aux'); 228 SELECT * FROM t4 WHERE a = 'main'; 229 } 230 } {main main main} 231 do_test alter-1.8.4 { 232 execsql { 233 ALTER TABLE t4 RENAME TO t5; 234 SELECT * FROM t4 WHERE a = 'aux'; 235 } 236 } {aux aux aux} 237 do_test alter-1.8.5 { 238 execsql { 239 SELECT * FROM t5; 240 } 241 } {main main main} 242 do_test alter-1.8.6 { 243 execsql { 244 SELECT * FROM t5 WHERE b = 'main'; 245 } 246 } {main main main} 247 do_test alter-1.8.7 { 248 execsql { 249 ALTER TABLE aux.t4 RENAME TO t5; 250 SELECT * FROM aux.t5 WHERE b = 'aux'; 251 } 252 } {aux aux aux} 253} 254 255do_test alter-1.9.1 { 256 execsql { 257 CREATE TABLE tbl1 (a, b, c); 258 INSERT INTO tbl1 VALUES(1, 2, 3); 259 } 260} {} 261do_test alter-1.9.2 { 262 execsql { 263 SELECT * FROM tbl1; 264 } 265} {1 2 3} 266do_test alter-1.9.3 { 267 execsql { 268 ALTER TABLE tbl1 RENAME TO tbl2; 269 SELECT * FROM tbl2; 270 } 271} {1 2 3} 272do_test alter-1.9.4 { 273 execsql { 274 DROP TABLE tbl2; 275 } 276} {} 277 278# Test error messages 279# 280do_test alter-2.1 { 281 catchsql { 282 ALTER TABLE none RENAME TO hi; 283 } 284} {1 {no such table: none}} 285do_test alter-2.2 { 286 execsql { 287 CREATE TABLE t3(p,q,r); 288 } 289 catchsql { 290 ALTER TABLE [<t2>] RENAME TO t3; 291 } 292} {1 {there is already another table or index with this name: t3}} 293do_test alter-2.3 { 294 catchsql { 295 ALTER TABLE [<t2>] RENAME TO i3; 296 } 297} {1 {there is already another table or index with this name: i3}} 298do_test alter-2.4 { 299 catchsql { 300 ALTER TABLE SqLiTe_master RENAME TO master; 301 } 302} {1 {table sqlite_master may not be altered}} 303do_test alter-2.5 { 304 catchsql { 305 ALTER TABLE t3 RENAME TO sqlite_t3; 306 } 307} {1 {object name reserved for internal use: sqlite_t3}} 308do_test alter-2.6 { 309 catchsql { 310 ALTER TABLE t3 ADD COLUMN (ALTER TABLE t3 ADD COLUMN); 311 } 312} {1 {near "(": syntax error}} 313 314# If this compilation does not include triggers, omit the alter-3.* tests. 315ifcapable trigger { 316 317#----------------------------------------------------------------------- 318# Tests alter-3.* test ALTER TABLE on tables that have triggers. 319# 320# alter-3.1.*: ALTER TABLE with triggers. 321# alter-3.2.*: Test that the ON keyword cannot be used as a database, 322# table or column name unquoted. This is done because part of the 323# ALTER TABLE code (specifically the implementation of SQL function 324# "sqlite_alter_trigger") will break in this case. 325# alter-3.3.*: ALTER TABLE with TEMP triggers (todo). 326# 327 328# An SQL user-function for triggers to fire, so that we know they 329# are working. 330proc trigfunc {args} { 331 set ::TRIGGER $args 332} 333db func trigfunc trigfunc 334 335do_test alter-3.1.0 { 336 execsql { 337 CREATE TABLE t6(a, b, c); 338 CREATE TRIGGER trig1 AFTER INSERT ON t6 BEGIN 339 SELECT trigfunc('trig1', new.a, new.b, new.c); 340 END; 341 } 342} {} 343do_test alter-3.1.1 { 344 execsql { 345 INSERT INTO t6 VALUES(1, 2, 3); 346 } 347 set ::TRIGGER 348} {trig1 1 2 3} 349do_test alter-3.1.2 { 350 execsql { 351 ALTER TABLE t6 RENAME TO t7; 352 INSERT INTO t7 VALUES(4, 5, 6); 353 } 354 set ::TRIGGER 355} {trig1 4 5 6} 356do_test alter-3.1.3 { 357 execsql { 358 DROP TRIGGER trig1; 359 } 360} {} 361do_test alter-3.1.4 { 362 execsql { 363 CREATE TRIGGER trig2 AFTER INSERT ON main.t7 BEGIN 364 SELECT trigfunc('trig2', new.a, new.b, new.c); 365 END; 366 INSERT INTO t7 VALUES(1, 2, 3); 367 } 368 set ::TRIGGER 369} {trig2 1 2 3} 370do_test alter-3.1.5 { 371 execsql { 372 ALTER TABLE t7 RENAME TO t8; 373 INSERT INTO t8 VALUES(4, 5, 6); 374 } 375 set ::TRIGGER 376} {trig2 4 5 6} 377do_test alter-3.1.6 { 378 execsql { 379 DROP TRIGGER trig2; 380 } 381} {} 382do_test alter-3.1.7 { 383 execsql { 384 CREATE TRIGGER trig3 AFTER INSERT ON main.'t8'BEGIN 385 SELECT trigfunc('trig3', new.a, new.b, new.c); 386 END; 387 INSERT INTO t8 VALUES(1, 2, 3); 388 } 389 set ::TRIGGER 390} {trig3 1 2 3} 391do_test alter-3.1.8 { 392 execsql { 393 ALTER TABLE t8 RENAME TO t9; 394 INSERT INTO t9 VALUES(4, 5, 6); 395 } 396 set ::TRIGGER 397} {trig3 4 5 6} 398 399# Make sure "ON" cannot be used as a database, table or column name without 400# quoting. Otherwise the sqlite_alter_trigger() function might not work. 401file delete -force test3.db 402file delete -force test3.db-journal 403ifcapable attach { 404 do_test alter-3.2.1 { 405 catchsql { 406 ATTACH 'test3.db' AS ON; 407 } 408 } {1 {near "ON": syntax error}} 409 do_test alter-3.2.2 { 410 catchsql { 411 ATTACH 'test3.db' AS 'ON'; 412 } 413 } {0 {}} 414 do_test alter-3.2.3 { 415 catchsql { 416 CREATE TABLE ON.t1(a, b, c); 417 } 418 } {1 {near "ON": syntax error}} 419 do_test alter-3.2.4 { 420 catchsql { 421 CREATE TABLE 'ON'.t1(a, b, c); 422 } 423 } {0 {}} 424 do_test alter-3.2.4 { 425 catchsql { 426 CREATE TABLE 'ON'.ON(a, b, c); 427 } 428 } {1 {near "ON": syntax error}} 429 do_test alter-3.2.5 { 430 catchsql { 431 CREATE TABLE 'ON'.'ON'(a, b, c); 432 } 433 } {0 {}} 434} 435do_test alter-3.2.6 { 436 catchsql { 437 CREATE TABLE t10(a, ON, c); 438 } 439} {1 {near "ON": syntax error}} 440do_test alter-3.2.7 { 441 catchsql { 442 CREATE TABLE t10(a, 'ON', c); 443 } 444} {0 {}} 445do_test alter-3.2.8 { 446 catchsql { 447 CREATE TRIGGER trig4 AFTER INSERT ON ON BEGIN SELECT 1; END; 448 } 449} {1 {near "ON": syntax error}} 450ifcapable attach { 451 do_test alter-3.2.9 { 452 catchsql { 453 CREATE TRIGGER 'on'.trig4 AFTER INSERT ON 'ON' BEGIN SELECT 1; END; 454 } 455 } {0 {}} 456} 457do_test alter-3.2.10 { 458 execsql { 459 DROP TABLE t10; 460 } 461} {} 462 463do_test alter-3.3.1 { 464 execsql [subst { 465 CREATE TABLE tbl1(a, b, c); 466 CREATE $::temp TRIGGER trig1 AFTER INSERT ON tbl1 BEGIN 467 SELECT trigfunc('trig1', new.a, new.b, new.c); 468 END; 469 }] 470} {} 471do_test alter-3.3.2 { 472 execsql { 473 INSERT INTO tbl1 VALUES('a', 'b', 'c'); 474 } 475 set ::TRIGGER 476} {trig1 a b c} 477do_test alter-3.3.3 { 478 execsql { 479 ALTER TABLE tbl1 RENAME TO tbl2; 480 INSERT INTO tbl2 VALUES('d', 'e', 'f'); 481 } 482 set ::TRIGGER 483} {trig1 d e f} 484do_test alter-3.3.4 { 485 execsql [subst { 486 CREATE $::temp TRIGGER trig2 AFTER UPDATE ON tbl2 BEGIN 487 SELECT trigfunc('trig2', new.a, new.b, new.c); 488 END; 489 }] 490} {} 491do_test alter-3.3.5 { 492 execsql { 493 ALTER TABLE tbl2 RENAME TO tbl3; 494 INSERT INTO tbl3 VALUES('g', 'h', 'i'); 495 } 496 set ::TRIGGER 497} {trig1 g h i} 498do_test alter-3.3.6 { 499 execsql { 500 UPDATE tbl3 SET a = 'G' where a = 'g'; 501 } 502 set ::TRIGGER 503} {trig2 G h i} 504do_test alter-3.3.7 { 505 execsql { 506 DROP TABLE tbl3; 507 } 508} {} 509ifcapable tempdb { 510 do_test alter-3.3.8 { 511 execsql { 512 SELECT * FROM sqlite_temp_master WHERE type = 'trigger'; 513 } 514 } {} 515} 516 517} ;# ifcapable trigger 518 519# If the build does not include AUTOINCREMENT fields, omit alter-4.*. 520ifcapable autoinc { 521 522do_test alter-4.1 { 523 execsql { 524 CREATE TABLE tbl1(a INTEGER PRIMARY KEY AUTOINCREMENT); 525 INSERT INTO tbl1 VALUES(10); 526 } 527} {} 528do_test alter-4.2 { 529 execsql { 530 INSERT INTO tbl1 VALUES(NULL); 531 SELECT a FROM tbl1; 532 } 533} {10 11} 534do_test alter-4.3 { 535 execsql { 536 ALTER TABLE tbl1 RENAME TO tbl2; 537 DELETE FROM tbl2; 538 INSERT INTO tbl2 VALUES(NULL); 539 SELECT a FROM tbl2; 540 } 541} {12} 542do_test alter-4.4 { 543 execsql { 544 DROP TABLE tbl2; 545 } 546} {} 547 548} ;# ifcapable autoinc 549 550# Test that it is Ok to execute an ALTER TABLE immediately after 551# opening a database. 552do_test alter-5.1 { 553 execsql { 554 CREATE TABLE tbl1(a, b, c); 555 INSERT INTO tbl1 VALUES('x', 'y', 'z'); 556 } 557} {} 558do_test alter-5.2 { 559 sqlite3 db2 test.db 560 execsql { 561 ALTER TABLE tbl1 RENAME TO tbl2; 562 SELECT * FROM tbl2; 563 } db2 564} {x y z} 565do_test alter-5.3 { 566 db2 close 567} {} 568 569foreach tblname [execsql { 570 SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite%' 571}] { 572 execsql "DROP TABLE \"$tblname\"" 573} 574 575set ::tbl_name "abc\uABCDdef" 576do_test alter-6.1 { 577 string length $::tbl_name 578} {7} 579do_test alter-6.2 { 580 execsql " 581 CREATE TABLE ${tbl_name}(a, b, c); 582 " 583 set ::oid [execsql {SELECT max(oid) FROM sqlite_master}] 584 execsql " 585 SELECT sql FROM sqlite_master WHERE oid = $::oid; 586 " 587} "{CREATE TABLE ${::tbl_name}(a, b, c)}" 588execsql " 589 SELECT * FROM ${::tbl_name} 590" 591set ::tbl_name2 "abcXdef" 592do_test alter-6.3 { 593 execsql " 594 ALTER TABLE $::tbl_name RENAME TO $::tbl_name2 595 " 596 execsql " 597 SELECT sql FROM sqlite_master WHERE oid = $::oid 598 " 599} "{CREATE TABLE \"${::tbl_name2}\"(a, b, c)}" 600do_test alter-6.4 { 601 execsql " 602 ALTER TABLE $::tbl_name2 RENAME TO $::tbl_name 603 " 604 execsql " 605 SELECT sql FROM sqlite_master WHERE oid = $::oid 606 " 607} "{CREATE TABLE \"${::tbl_name}\"(a, b, c)}" 608set ::col_name ghi\1234\jkl 609do_test alter-6.5 { 610 execsql " 611 ALTER TABLE $::tbl_name ADD COLUMN $::col_name VARCHAR 612 " 613 execsql " 614 SELECT sql FROM sqlite_master WHERE oid = $::oid 615 " 616} "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR)}" 617set ::col_name2 B\3421\A 618do_test alter-6.6 { 619 db close 620 sqlite3 db test.db 621 execsql " 622 ALTER TABLE $::tbl_name ADD COLUMN $::col_name2 623 " 624 execsql " 625 SELECT sql FROM sqlite_master WHERE oid = $::oid 626 " 627} "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR, $::col_name2)}" 628do_test alter-6.7 { 629 execsql " 630 INSERT INTO ${::tbl_name} VALUES(1, 2, 3, 4, 5); 631 SELECT $::col_name, $::col_name2 FROM $::tbl_name; 632 " 633} {4 5} 634 635# Ticket #1665: Make sure ALTER TABLE ADD COLUMN works on a table 636# that includes a COLLATE clause. 637# 638do_test alter-7.1 { 639 execsql { 640 CREATE TABLE t1(a TEXT COLLATE BINARY); 641 ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE; 642 INSERT INTO t1 VALUES(1,'-2'); 643 INSERT INTO t1 VALUES(5.4e-08,'5.4e-08'); 644 SELECT typeof(a), a, typeof(b), b FROM t1; 645 } 646} {text 1 integer -2 text 5.4e-08 real 5.4e-08} 647 648# Make sure that when a column is added by ALTER TABLE ADD COLUMN and has 649# a default value that the default value is used by aggregate functions. 650# 651do_test alter-8.1 { 652 execsql { 653 CREATE TABLE t2(a INTEGER); 654 INSERT INTO t2 VALUES(1); 655 INSERT INTO t2 VALUES(1); 656 INSERT INTO t2 VALUES(2); 657 ALTER TABLE t2 ADD COLUMN b INTEGER DEFAULT 9; 658 SELECT sum(b) FROM t2; 659 } 660} {27} 661do_test alter-8.2 { 662 execsql { 663 SELECT a, sum(b) FROM t2 GROUP BY a; 664 } 665} {1 18 2 9} 666 667#-------------------------------------------------------------------------- 668# alter-9.X - Special test: Make sure the sqlite_rename_trigger() and 669# rename_table() functions do not crash when handed bad input. 670# 671ifcapable trigger { 672 do_test alter-9.1 { 673 execsql {SELECT SQLITE_RENAME_TRIGGER(0,0)} 674 } {{}} 675} 676do_test alter-9.2 { 677 execsql { 678 SELECT SQLITE_RENAME_TABLE(0,0); 679 SELECT SQLITE_RENAME_TABLE(10,20); 680 SELECT SQLITE_RENAME_TABLE("foo", "foo"); 681 } 682} {{} {} {}} 683 684#------------------------------------------------------------------------ 685# alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters 686# in the names. 687# 688do_test alter-10.1 { 689 execsql "CREATE TABLE xyz(x UNIQUE)" 690 execsql "ALTER TABLE xyz RENAME TO xyz\u1234abc" 691 execsql {SELECT name FROM sqlite_master WHERE name LIKE 'xyz%'} 692} [list xyz\u1234abc] 693do_test alter-10.2 { 694 execsql {SELECT name FROM sqlite_master WHERE name LIKE 'sqlite_autoindex%'} 695} [list sqlite_autoindex_xyz\u1234abc_1] 696do_test alter-10.3 { 697 execsql "ALTER TABLE xyz\u1234abc RENAME TO xyzabc" 698 execsql {SELECT name FROM sqlite_master WHERE name LIKE 'xyz%'} 699} [list xyzabc] 700do_test alter-10.4 { 701 execsql {SELECT name FROM sqlite_master WHERE name LIKE 'sqlite_autoindex%'} 702} [list sqlite_autoindex_xyzabc_1] 703 704do_test alter-11.1 { 705 sqlite3_exec db {CREATE TABLE t11(%c6%c6)} 706 execsql { 707 ALTER TABLE t11 ADD COLUMN abc; 708 } 709 catchsql { 710 ALTER TABLE t11 ADD COLUMN abc; 711 } 712} {1 {duplicate column name: abc}} 713set isutf16 [regexp 16 [db one {PRAGMA encoding}]] 714if {!$isutf16} { 715 do_test alter-11.2 { 716 execsql {INSERT INTO t11 VALUES(1,2)} 717 sqlite3_exec db {SELECT %c6%c6 AS xyz, abc FROM t11} 718 } {0 {xyz abc 1 2}} 719} 720do_test alter-11.3 { 721 sqlite3_exec db {CREATE TABLE t11b("%81%82%83" text)} 722 execsql { 723 ALTER TABLE t11b ADD COLUMN abc; 724 } 725 catchsql { 726 ALTER TABLE t11b ADD COLUMN abc; 727 } 728} {1 {duplicate column name: abc}} 729if {!$isutf16} { 730 do_test alter-11.4 { 731 execsql {INSERT INTO t11b VALUES(3,4)} 732 sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11b} 733 } {0 {xyz abc 3 4}} 734 do_test alter-11.5 { 735 sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11b} 736 } {0 {xyz abc 3 4}} 737 do_test alter-11.6 { 738 sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11b} 739 } {0 {xyz abc 3 4}} 740} 741do_test alter-11.7 { 742 sqlite3_exec db {CREATE TABLE t11c(%81%82%83 text)} 743 execsql { 744 ALTER TABLE t11c ADD COLUMN abc; 745 } 746 catchsql { 747 ALTER TABLE t11c ADD COLUMN abc; 748 } 749} {1 {duplicate column name: abc}} 750if {!$isutf16} { 751 do_test alter-11.8 { 752 execsql {INSERT INTO t11c VALUES(5,6)} 753 sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11c} 754 } {0 {xyz abc 5 6}} 755 do_test alter-11.9 { 756 sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11c} 757 } {0 {xyz abc 5 6}} 758 do_test alter-11.10 { 759 sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11c} 760 } {0 {xyz abc 5 6}} 761} 762 763do_test alter-12.1 { 764 execsql { 765 CREATE TABLE t12(a, b, c); 766 CREATE VIEW v1 AS SELECT * FROM t12; 767 } 768} {} 769do_test alter-12.2 { 770 catchsql { 771 ALTER TABLE v1 RENAME TO v2; 772 } 773} {1 {view v1 may not be altered}} 774do_test alter-12.3 { 775 execsql { SELECT * FROM v1; } 776} {} 777do_test alter-12.4 { 778 db close 779 sqlite3 db test.db 780 execsql { SELECT * FROM v1; } 781} {} 782do_test alter-12.5 { 783 catchsql { 784 ALTER TABLE v1 ADD COLUMN new_column; 785 } 786} {1 {Cannot add a column to a view}} 787 788 789finish_test 790