Annotation of embedaddon/sqlite3/test/alter.test, revision 1.1.1.1
1.1 misho 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.32 2009/03/24 15:08:10 drh Exp $
15: #
16:
17: set testdir [file dirname $argv0]
18: source $testdir/tester.tcl
19:
20: # If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
21: ifcapable !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: #
47: do_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}
71: do_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: #
102: integrity_check alter-1.3.0
103: do_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: } {}
110: integrity_check alter-1.3.1
111: do_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}
118: do_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: #
147: ifcapable 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: # Create bogus application-defined functions for functions used
177: # internally by ALTER TABLE, to ensure that ALTER TABLE falls back
178: # to the built-in functions.
179: #
180: proc failing_app_func {args} {error "bad function"}
181: do_test alter-1.7-prep {
182: db func substr failing_app_func
183: db func like failing_app_func
184: db func sqlite_rename_table failing_app_func
185: db func sqlite_rename_trigger failing_app_func
186: db func sqlite_rename_parent failing_app_func
187: catchsql {SELECT substr(name,1,3) FROM sqlite_master}
188: } {1 {bad function}}
189:
190: # Make sure the ALTER TABLE statements work with the
191: # non-callback API
192: #
193: do_test alter-1.7 {
194: stepsql $DB {
195: ALTER TABLE [-t1-] RENAME to [*t1*];
196: ALTER TABLE T2 RENAME TO [<t2>];
197: }
198: execsql {
199: DELETE FROM objlist;
200: INSERT INTO objlist SELECT type, name, tbl_name
201: FROM sqlite_master WHERE NAME!='objlist';
202: }
203: catchsql {
204: INSERT INTO objlist SELECT type, name, tbl_name
205: FROM sqlite_temp_master WHERE NAME!='objlist';
206: }
207: execsql {
208: SELECT type, name, tbl_name FROM objlist ORDER BY tbl_name, type desc, name;
209: }
210: } [list \
211: table *t1* *t1* \
212: index t1i1 *t1* \
213: index t1i2 *t1* \
214: table <t2> <t2> \
215: index i3 <t2> \
216: index {sqlite_autoindex_<t2>_1} <t2> \
217: index {sqlite_autoindex_<t2>_2} <t2> \
218: ]
219:
220: # Check that ALTER TABLE works on attached databases.
221: #
222: ifcapable attach {
223: do_test alter-1.8.1 {
224: forcedelete test2.db
225: forcedelete test2.db-journal
226: execsql {
227: ATTACH 'test2.db' AS aux;
228: }
229: } {}
230: do_test alter-1.8.2 {
231: execsql {
232: CREATE TABLE t4(a PRIMARY KEY, b, c);
233: CREATE TABLE aux.t4(a PRIMARY KEY, b, c);
234: CREATE INDEX i4 ON t4(b);
235: CREATE INDEX aux.i4 ON t4(b);
236: }
237: } {}
238: do_test alter-1.8.3 {
239: execsql {
240: INSERT INTO t4 VALUES('main', 'main', 'main');
241: INSERT INTO aux.t4 VALUES('aux', 'aux', 'aux');
242: SELECT * FROM t4 WHERE a = 'main';
243: }
244: } {main main main}
245: do_test alter-1.8.4 {
246: execsql {
247: ALTER TABLE t4 RENAME TO t5;
248: SELECT * FROM t4 WHERE a = 'aux';
249: }
250: } {aux aux aux}
251: do_test alter-1.8.5 {
252: execsql {
253: SELECT * FROM t5;
254: }
255: } {main main main}
256: do_test alter-1.8.6 {
257: execsql {
258: SELECT * FROM t5 WHERE b = 'main';
259: }
260: } {main main main}
261: do_test alter-1.8.7 {
262: execsql {
263: ALTER TABLE aux.t4 RENAME TO t5;
264: SELECT * FROM aux.t5 WHERE b = 'aux';
265: }
266: } {aux aux aux}
267: }
268:
269: do_test alter-1.9.1 {
270: execsql {
271: CREATE TABLE tbl1 (a, b, c);
272: INSERT INTO tbl1 VALUES(1, 2, 3);
273: }
274: } {}
275: do_test alter-1.9.2 {
276: execsql {
277: SELECT * FROM tbl1;
278: }
279: } {1 2 3}
280: do_test alter-1.9.3 {
281: execsql {
282: ALTER TABLE tbl1 RENAME TO tbl2;
283: SELECT * FROM tbl2;
284: }
285: } {1 2 3}
286: do_test alter-1.9.4 {
287: execsql {
288: DROP TABLE tbl2;
289: }
290: } {}
291:
292: # Test error messages
293: #
294: do_test alter-2.1 {
295: catchsql {
296: ALTER TABLE none RENAME TO hi;
297: }
298: } {1 {no such table: none}}
299: do_test alter-2.2 {
300: execsql {
301: CREATE TABLE t3(p,q,r);
302: }
303: catchsql {
304: ALTER TABLE [<t2>] RENAME TO t3;
305: }
306: } {1 {there is already another table or index with this name: t3}}
307: do_test alter-2.3 {
308: catchsql {
309: ALTER TABLE [<t2>] RENAME TO i3;
310: }
311: } {1 {there is already another table or index with this name: i3}}
312: do_test alter-2.4 {
313: catchsql {
314: ALTER TABLE SqLiTe_master RENAME TO master;
315: }
316: } {1 {table sqlite_master may not be altered}}
317: do_test alter-2.5 {
318: catchsql {
319: ALTER TABLE t3 RENAME TO sqlite_t3;
320: }
321: } {1 {object name reserved for internal use: sqlite_t3}}
322: do_test alter-2.6 {
323: catchsql {
324: ALTER TABLE t3 ADD COLUMN (ALTER TABLE t3 ADD COLUMN);
325: }
326: } {1 {near "(": syntax error}}
327:
328: # If this compilation does not include triggers, omit the alter-3.* tests.
329: ifcapable trigger {
330:
331: #-----------------------------------------------------------------------
332: # Tests alter-3.* test ALTER TABLE on tables that have triggers.
333: #
334: # alter-3.1.*: ALTER TABLE with triggers.
335: # alter-3.2.*: Test that the ON keyword cannot be used as a database,
336: # table or column name unquoted. This is done because part of the
337: # ALTER TABLE code (specifically the implementation of SQL function
338: # "sqlite_alter_trigger") will break in this case.
339: # alter-3.3.*: ALTER TABLE with TEMP triggers (todo).
340: #
341:
342: # An SQL user-function for triggers to fire, so that we know they
343: # are working.
344: proc trigfunc {args} {
345: set ::TRIGGER $args
346: }
347: db func trigfunc trigfunc
348:
349: do_test alter-3.1.0 {
350: execsql {
351: CREATE TABLE t6(a, b, c);
352: CREATE TRIGGER trig1 AFTER INSERT ON t6 BEGIN
353: SELECT trigfunc('trig1', new.a, new.b, new.c);
354: END;
355: }
356: } {}
357: do_test alter-3.1.1 {
358: execsql {
359: INSERT INTO t6 VALUES(1, 2, 3);
360: }
361: set ::TRIGGER
362: } {trig1 1 2 3}
363: do_test alter-3.1.2 {
364: execsql {
365: ALTER TABLE t6 RENAME TO t7;
366: INSERT INTO t7 VALUES(4, 5, 6);
367: }
368: set ::TRIGGER
369: } {trig1 4 5 6}
370: do_test alter-3.1.3 {
371: execsql {
372: DROP TRIGGER trig1;
373: }
374: } {}
375: do_test alter-3.1.4 {
376: execsql {
377: CREATE TRIGGER trig2 AFTER INSERT ON main.t7 BEGIN
378: SELECT trigfunc('trig2', new.a, new.b, new.c);
379: END;
380: INSERT INTO t7 VALUES(1, 2, 3);
381: }
382: set ::TRIGGER
383: } {trig2 1 2 3}
384: do_test alter-3.1.5 {
385: execsql {
386: ALTER TABLE t7 RENAME TO t8;
387: INSERT INTO t8 VALUES(4, 5, 6);
388: }
389: set ::TRIGGER
390: } {trig2 4 5 6}
391: do_test alter-3.1.6 {
392: execsql {
393: DROP TRIGGER trig2;
394: }
395: } {}
396: do_test alter-3.1.7 {
397: execsql {
398: CREATE TRIGGER trig3 AFTER INSERT ON main.'t8'BEGIN
399: SELECT trigfunc('trig3', new.a, new.b, new.c);
400: END;
401: INSERT INTO t8 VALUES(1, 2, 3);
402: }
403: set ::TRIGGER
404: } {trig3 1 2 3}
405: do_test alter-3.1.8 {
406: execsql {
407: ALTER TABLE t8 RENAME TO t9;
408: INSERT INTO t9 VALUES(4, 5, 6);
409: }
410: set ::TRIGGER
411: } {trig3 4 5 6}
412:
413: # Make sure "ON" cannot be used as a database, table or column name without
414: # quoting. Otherwise the sqlite_alter_trigger() function might not work.
415: forcedelete test3.db
416: forcedelete test3.db-journal
417: ifcapable attach {
418: do_test alter-3.2.1 {
419: catchsql {
420: ATTACH 'test3.db' AS ON;
421: }
422: } {1 {near "ON": syntax error}}
423: do_test alter-3.2.2 {
424: catchsql {
425: ATTACH 'test3.db' AS 'ON';
426: }
427: } {0 {}}
428: do_test alter-3.2.3 {
429: catchsql {
430: CREATE TABLE ON.t1(a, b, c);
431: }
432: } {1 {near "ON": syntax error}}
433: do_test alter-3.2.4 {
434: catchsql {
435: CREATE TABLE 'ON'.t1(a, b, c);
436: }
437: } {0 {}}
438: do_test alter-3.2.4 {
439: catchsql {
440: CREATE TABLE 'ON'.ON(a, b, c);
441: }
442: } {1 {near "ON": syntax error}}
443: do_test alter-3.2.5 {
444: catchsql {
445: CREATE TABLE 'ON'.'ON'(a, b, c);
446: }
447: } {0 {}}
448: }
449: do_test alter-3.2.6 {
450: catchsql {
451: CREATE TABLE t10(a, ON, c);
452: }
453: } {1 {near "ON": syntax error}}
454: do_test alter-3.2.7 {
455: catchsql {
456: CREATE TABLE t10(a, 'ON', c);
457: }
458: } {0 {}}
459: do_test alter-3.2.8 {
460: catchsql {
461: CREATE TRIGGER trig4 AFTER INSERT ON ON BEGIN SELECT 1; END;
462: }
463: } {1 {near "ON": syntax error}}
464: ifcapable attach {
465: do_test alter-3.2.9 {
466: catchsql {
467: CREATE TRIGGER 'on'.trig4 AFTER INSERT ON 'ON' BEGIN SELECT 1; END;
468: }
469: } {0 {}}
470: }
471: do_test alter-3.2.10 {
472: execsql {
473: DROP TABLE t10;
474: }
475: } {}
476:
477: do_test alter-3.3.1 {
478: execsql [subst {
479: CREATE TABLE tbl1(a, b, c);
480: CREATE $::temp TRIGGER trig1 AFTER INSERT ON tbl1 BEGIN
481: SELECT trigfunc('trig1', new.a, new.b, new.c);
482: END;
483: }]
484: } {}
485: do_test alter-3.3.2 {
486: execsql {
487: INSERT INTO tbl1 VALUES('a', 'b', 'c');
488: }
489: set ::TRIGGER
490: } {trig1 a b c}
491: do_test alter-3.3.3 {
492: execsql {
493: ALTER TABLE tbl1 RENAME TO tbl2;
494: INSERT INTO tbl2 VALUES('d', 'e', 'f');
495: }
496: set ::TRIGGER
497: } {trig1 d e f}
498: do_test alter-3.3.4 {
499: execsql [subst {
500: CREATE $::temp TRIGGER trig2 AFTER UPDATE ON tbl2 BEGIN
501: SELECT trigfunc('trig2', new.a, new.b, new.c);
502: END;
503: }]
504: } {}
505: do_test alter-3.3.5 {
506: execsql {
507: ALTER TABLE tbl2 RENAME TO tbl3;
508: INSERT INTO tbl3 VALUES('g', 'h', 'i');
509: }
510: set ::TRIGGER
511: } {trig1 g h i}
512: do_test alter-3.3.6 {
513: execsql {
514: UPDATE tbl3 SET a = 'G' where a = 'g';
515: }
516: set ::TRIGGER
517: } {trig2 G h i}
518: do_test alter-3.3.7 {
519: execsql {
520: DROP TABLE tbl3;
521: }
522: } {}
523: ifcapable tempdb {
524: do_test alter-3.3.8 {
525: execsql {
526: SELECT * FROM sqlite_temp_master WHERE type = 'trigger';
527: }
528: } {}
529: }
530:
531: } ;# ifcapable trigger
532:
533: # If the build does not include AUTOINCREMENT fields, omit alter-4.*.
534: ifcapable autoinc {
535:
536: do_test alter-4.1 {
537: execsql {
538: CREATE TABLE tbl1(a INTEGER PRIMARY KEY AUTOINCREMENT);
539: INSERT INTO tbl1 VALUES(10);
540: }
541: } {}
542: do_test alter-4.2 {
543: execsql {
544: INSERT INTO tbl1 VALUES(NULL);
545: SELECT a FROM tbl1;
546: }
547: } {10 11}
548: do_test alter-4.3 {
549: execsql {
550: ALTER TABLE tbl1 RENAME TO tbl2;
551: DELETE FROM tbl2;
552: INSERT INTO tbl2 VALUES(NULL);
553: SELECT a FROM tbl2;
554: }
555: } {12}
556: do_test alter-4.4 {
557: execsql {
558: DROP TABLE tbl2;
559: }
560: } {}
561:
562: } ;# ifcapable autoinc
563:
564: # Test that it is Ok to execute an ALTER TABLE immediately after
565: # opening a database.
566: do_test alter-5.1 {
567: execsql {
568: CREATE TABLE tbl1(a, b, c);
569: INSERT INTO tbl1 VALUES('x', 'y', 'z');
570: }
571: } {}
572: do_test alter-5.2 {
573: sqlite3 db2 test.db
574: execsql {
575: ALTER TABLE tbl1 RENAME TO tbl2;
576: SELECT * FROM tbl2;
577: } db2
578: } {x y z}
579: do_test alter-5.3 {
580: db2 close
581: } {}
582:
583: foreach tblname [execsql {
584: SELECT name FROM sqlite_master
585: WHERE type='table' AND name NOT GLOB 'sqlite*'
586: }] {
587: execsql "DROP TABLE \"$tblname\""
588: }
589:
590: set ::tbl_name "abc\uABCDdef"
591: do_test alter-6.1 {
592: string length $::tbl_name
593: } {7}
594: do_test alter-6.2 {
595: execsql "
596: CREATE TABLE ${tbl_name}(a, b, c);
597: "
598: set ::oid [execsql {SELECT max(oid) FROM sqlite_master}]
599: execsql "
600: SELECT sql FROM sqlite_master WHERE oid = $::oid;
601: "
602: } "{CREATE TABLE ${::tbl_name}(a, b, c)}"
603: execsql "
604: SELECT * FROM ${::tbl_name}
605: "
606: set ::tbl_name2 "abcXdef"
607: do_test alter-6.3 {
608: execsql "
609: ALTER TABLE $::tbl_name RENAME TO $::tbl_name2
610: "
611: execsql "
612: SELECT sql FROM sqlite_master WHERE oid = $::oid
613: "
614: } "{CREATE TABLE \"${::tbl_name2}\"(a, b, c)}"
615: do_test alter-6.4 {
616: execsql "
617: ALTER TABLE $::tbl_name2 RENAME TO $::tbl_name
618: "
619: execsql "
620: SELECT sql FROM sqlite_master WHERE oid = $::oid
621: "
622: } "{CREATE TABLE \"${::tbl_name}\"(a, b, c)}"
623: set ::col_name ghi\1234\jkl
624: do_test alter-6.5 {
625: execsql "
626: ALTER TABLE $::tbl_name ADD COLUMN $::col_name VARCHAR
627: "
628: execsql "
629: SELECT sql FROM sqlite_master WHERE oid = $::oid
630: "
631: } "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR)}"
632: set ::col_name2 B\3421\A
633: do_test alter-6.6 {
634: db close
635: sqlite3 db test.db
636: execsql "
637: ALTER TABLE $::tbl_name ADD COLUMN $::col_name2
638: "
639: execsql "
640: SELECT sql FROM sqlite_master WHERE oid = $::oid
641: "
642: } "{CREATE TABLE \"${::tbl_name}\"(a, b, c, $::col_name VARCHAR, $::col_name2)}"
643: do_test alter-6.7 {
644: execsql "
645: INSERT INTO ${::tbl_name} VALUES(1, 2, 3, 4, 5);
646: SELECT $::col_name, $::col_name2 FROM $::tbl_name;
647: "
648: } {4 5}
649:
650: # Ticket #1665: Make sure ALTER TABLE ADD COLUMN works on a table
651: # that includes a COLLATE clause.
652: #
653: do_realnum_test alter-7.1 {
654: execsql {
655: CREATE TABLE t1(a TEXT COLLATE BINARY);
656: ALTER TABLE t1 ADD COLUMN b INTEGER COLLATE NOCASE;
657: INSERT INTO t1 VALUES(1,'-2');
658: INSERT INTO t1 VALUES(5.4e-08,'5.4e-08');
659: SELECT typeof(a), a, typeof(b), b FROM t1;
660: }
661: } {text 1 integer -2 text 5.4e-08 real 5.4e-08}
662:
663: # Make sure that when a column is added by ALTER TABLE ADD COLUMN and has
664: # a default value that the default value is used by aggregate functions.
665: #
666: do_test alter-8.1 {
667: execsql {
668: CREATE TABLE t2(a INTEGER);
669: INSERT INTO t2 VALUES(1);
670: INSERT INTO t2 VALUES(1);
671: INSERT INTO t2 VALUES(2);
672: ALTER TABLE t2 ADD COLUMN b INTEGER DEFAULT 9;
673: SELECT sum(b) FROM t2;
674: }
675: } {27}
676: do_test alter-8.2 {
677: execsql {
678: SELECT a, sum(b) FROM t2 GROUP BY a;
679: }
680: } {1 18 2 9}
681:
682: #--------------------------------------------------------------------------
683: # alter-9.X - Special test: Make sure the sqlite_rename_trigger() and
684: # rename_table() functions do not crash when handed bad input.
685: #
686: ifcapable trigger {
687: do_test alter-9.1 {
688: execsql {SELECT SQLITE_RENAME_TRIGGER(0,0)}
689: } {{}}
690: }
691: do_test alter-9.2 {
692: execsql {
693: SELECT SQLITE_RENAME_TABLE(0,0);
694: SELECT SQLITE_RENAME_TABLE(10,20);
695: SELECT SQLITE_RENAME_TABLE('foo', 'foo');
696: }
697: } {{} {} {}}
698:
699: #------------------------------------------------------------------------
700: # alter-10.X - Make sure ALTER TABLE works with multi-byte UTF-8 characters
701: # in the names.
702: #
703: do_test alter-10.1 {
704: execsql "CREATE TABLE xyz(x UNIQUE)"
705: execsql "ALTER TABLE xyz RENAME TO xyz\u1234abc"
706: execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
707: } [list xyz\u1234abc]
708: do_test alter-10.2 {
709: execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
710: } [list sqlite_autoindex_xyz\u1234abc_1]
711: do_test alter-10.3 {
712: execsql "ALTER TABLE xyz\u1234abc RENAME TO xyzabc"
713: execsql {SELECT name FROM sqlite_master WHERE name GLOB 'xyz*'}
714: } [list xyzabc]
715: do_test alter-10.4 {
716: execsql {SELECT name FROM sqlite_master WHERE name GLOB 'sqlite_autoindex*'}
717: } [list sqlite_autoindex_xyzabc_1]
718:
719: do_test alter-11.1 {
720: sqlite3_exec db {CREATE TABLE t11(%c6%c6)}
721: execsql {
722: ALTER TABLE t11 ADD COLUMN abc;
723: }
724: catchsql {
725: ALTER TABLE t11 ADD COLUMN abc;
726: }
727: } {1 {duplicate column name: abc}}
728: set isutf16 [regexp 16 [db one {PRAGMA encoding}]]
729: if {!$isutf16} {
730: do_test alter-11.2 {
731: execsql {INSERT INTO t11 VALUES(1,2)}
732: sqlite3_exec db {SELECT %c6%c6 AS xyz, abc FROM t11}
733: } {0 {xyz abc 1 2}}
734: }
735: do_test alter-11.3 {
736: sqlite3_exec db {CREATE TABLE t11b("%81%82%83" text)}
737: execsql {
738: ALTER TABLE t11b ADD COLUMN abc;
739: }
740: catchsql {
741: ALTER TABLE t11b ADD COLUMN abc;
742: }
743: } {1 {duplicate column name: abc}}
744: if {!$isutf16} {
745: do_test alter-11.4 {
746: execsql {INSERT INTO t11b VALUES(3,4)}
747: sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11b}
748: } {0 {xyz abc 3 4}}
749: do_test alter-11.5 {
750: sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11b}
751: } {0 {xyz abc 3 4}}
752: do_test alter-11.6 {
753: sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11b}
754: } {0 {xyz abc 3 4}}
755: }
756: do_test alter-11.7 {
757: sqlite3_exec db {CREATE TABLE t11c(%81%82%83 text)}
758: execsql {
759: ALTER TABLE t11c ADD COLUMN abc;
760: }
761: catchsql {
762: ALTER TABLE t11c ADD COLUMN abc;
763: }
764: } {1 {duplicate column name: abc}}
765: if {!$isutf16} {
766: do_test alter-11.8 {
767: execsql {INSERT INTO t11c VALUES(5,6)}
768: sqlite3_exec db {SELECT %81%82%83 AS xyz, abc FROM t11c}
769: } {0 {xyz abc 5 6}}
770: do_test alter-11.9 {
771: sqlite3_exec db {SELECT [%81%82%83] AS xyz, abc FROM t11c}
772: } {0 {xyz abc 5 6}}
773: do_test alter-11.10 {
774: sqlite3_exec db {SELECT "%81%82%83" AS xyz, abc FROM t11c}
775: } {0 {xyz abc 5 6}}
776: }
777:
778: do_test alter-12.1 {
779: execsql {
780: CREATE TABLE t12(a, b, c);
781: CREATE VIEW v1 AS SELECT * FROM t12;
782: }
783: } {}
784: do_test alter-12.2 {
785: catchsql {
786: ALTER TABLE v1 RENAME TO v2;
787: }
788: } {1 {view v1 may not be altered}}
789: do_test alter-12.3 {
790: execsql { SELECT * FROM v1; }
791: } {}
792: do_test alter-12.4 {
793: db close
794: sqlite3 db test.db
795: execsql { SELECT * FROM v1; }
796: } {}
797: do_test alter-12.5 {
798: catchsql {
799: ALTER TABLE v1 ADD COLUMN new_column;
800: }
801: } {1 {Cannot add a column to a view}}
802:
803: # Ticket #3102:
804: # Verify that comments do not interfere with the table rename
805: # algorithm.
806: #
807: do_test alter-13.1 {
808: execsql {
809: CREATE TABLE /* hi */ t3102a(x);
810: CREATE TABLE t3102b -- comment
811: (y);
812: CREATE INDEX t3102c ON t3102a(x);
813: SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
814: }
815: } {t3102a t3102b t3102c}
816: do_test alter-13.2 {
817: execsql {
818: ALTER TABLE t3102a RENAME TO t3102a_rename;
819: SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
820: }
821: } {t3102a_rename t3102b t3102c}
822: do_test alter-13.3 {
823: execsql {
824: ALTER TABLE t3102b RENAME TO t3102b_rename;
825: SELECT name FROM sqlite_master WHERE name GLOB 't3102*' ORDER BY 1;
826: }
827: } {t3102a_rename t3102b_rename t3102c}
828:
829: # Ticket #3651
830: do_test alter-14.1 {
831: catchsql {
832: CREATE TABLE t3651(a UNIQUE);
833: ALTER TABLE t3651 ADD COLUMN b UNIQUE;
834: }
835: } {1 {Cannot add a UNIQUE column}}
836: do_test alter-14.2 {
837: catchsql {
838: ALTER TABLE t3651 ADD COLUMN b PRIMARY KEY;
839: }
840: } {1 {Cannot add a PRIMARY KEY column}}
841:
842:
843: #-------------------------------------------------------------------------
844: # Test that it is not possible to use ALTER TABLE on any system table.
845: #
846: set system_table_list {1 sqlite_master}
847: catchsql ANALYZE
848: ifcapable analyze { lappend system_table_list 2 sqlite_stat1 }
849: ifcapable stat3 { lappend system_table_list 4 sqlite_stat3 }
850:
851: foreach {tn tbl} $system_table_list {
852: do_test alter-15.$tn.1 {
853: catchsql "ALTER TABLE $tbl RENAME TO xyz"
854: } [list 1 "table $tbl may not be altered"]
855:
856: do_test alter-15.$tn.2 {
857: catchsql "ALTER TABLE $tbl ADD COLUMN xyz"
858: } [list 1 "table $tbl may not be altered"]
859: }
860:
861:
862: finish_test
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>