persistentstorage/sqlite3api/TEST/TclScript/alter.test
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     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.30 2008/05/09 14:17:52 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 # Make sure the ALTER TABLE statements work with the
       
   177 # non-callback API
       
   178 #
       
   179 do_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 #
       
   208 ifcapable 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 
       
   255 do_test alter-1.9.1 {
       
   256   execsql {
       
   257     CREATE TABLE tbl1   (a, b, c);
       
   258     INSERT INTO tbl1 VALUES(1, 2, 3);
       
   259   }
       
   260 } {}
       
   261 do_test alter-1.9.2 {
       
   262   execsql {
       
   263     SELECT * FROM tbl1;
       
   264   }
       
   265 } {1 2 3}
       
   266 do_test alter-1.9.3 {
       
   267   execsql {
       
   268     ALTER TABLE tbl1 RENAME TO tbl2;
       
   269     SELECT * FROM tbl2;
       
   270   }
       
   271 } {1 2 3}
       
   272 do_test alter-1.9.4 {
       
   273   execsql {
       
   274     DROP TABLE tbl2;
       
   275   }
       
   276 } {}
       
   277 
       
   278 # Test error messages
       
   279 #
       
   280 do_test alter-2.1 {
       
   281   catchsql {
       
   282     ALTER TABLE none RENAME TO hi;
       
   283   }
       
   284 } {1 {no such table: none}}
       
   285 do_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}}
       
   293 do_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}}
       
   298 do_test alter-2.4 {
       
   299   catchsql {
       
   300     ALTER TABLE SqLiTe_master RENAME TO master;
       
   301   }
       
   302 } {1 {table sqlite_master may not be altered}}
       
   303 do_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}}
       
   308 do_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.
       
   315 ifcapable 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.
       
   330 proc trigfunc {args} {
       
   331   set ::TRIGGER $args
       
   332 }
       
   333 db func trigfunc trigfunc
       
   334 
       
   335 do_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 } {}
       
   343 do_test alter-3.1.1 {
       
   344   execsql {
       
   345     INSERT INTO t6 VALUES(1, 2, 3);
       
   346   }
       
   347   set ::TRIGGER
       
   348 } {trig1 1 2 3}
       
   349 do_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}
       
   356 do_test alter-3.1.3 {
       
   357   execsql {
       
   358     DROP TRIGGER trig1;
       
   359   }
       
   360 } {}
       
   361 do_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}
       
   370 do_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}
       
   377 do_test alter-3.1.6 {
       
   378   execsql {
       
   379     DROP TRIGGER trig2;
       
   380   }
       
   381 } {}
       
   382 do_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}
       
   391 do_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.
       
   401 file delete -force test3.db
       
   402 file delete -force test3.db-journal
       
   403 ifcapable 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 }
       
   435 do_test alter-3.2.6 {
       
   436   catchsql {
       
   437     CREATE TABLE t10(a, ON, c);
       
   438   }
       
   439 } {1 {near "ON": syntax error}}
       
   440 do_test alter-3.2.7 {
       
   441   catchsql {
       
   442     CREATE TABLE t10(a, 'ON', c);
       
   443   }
       
   444 } {0 {}}
       
   445 do_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}}
       
   450 ifcapable 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 }
       
   457 do_test alter-3.2.10 {
       
   458   execsql {
       
   459     DROP TABLE t10;
       
   460   }
       
   461 } {}
       
   462 
       
   463 do_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 } {}
       
   471 do_test alter-3.3.2 {
       
   472   execsql {
       
   473     INSERT INTO tbl1 VALUES('a', 'b', 'c');
       
   474   }
       
   475   set ::TRIGGER
       
   476 } {trig1 a b c}
       
   477 do_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}
       
   484 do_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 } {}
       
   491 do_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}
       
   498 do_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}
       
   504 do_test alter-3.3.7 {
       
   505   execsql {
       
   506     DROP TABLE tbl3;
       
   507   }
       
   508 } {}
       
   509 ifcapable 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.*.
       
   520 ifcapable autoinc {
       
   521 
       
   522 do_test alter-4.1 {
       
   523   execsql {
       
   524     CREATE TABLE tbl1(a INTEGER PRIMARY KEY AUTOINCREMENT);
       
   525     INSERT INTO tbl1 VALUES(10);
       
   526   }
       
   527 } {}
       
   528 do_test alter-4.2 {
       
   529   execsql {
       
   530     INSERT INTO tbl1 VALUES(NULL);
       
   531     SELECT a FROM tbl1;
       
   532   }
       
   533 } {10 11}
       
   534 do_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}
       
   542 do_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.
       
   552 do_test alter-5.1 {
       
   553   execsql {
       
   554     CREATE TABLE tbl1(a, b, c);
       
   555     INSERT INTO tbl1 VALUES('x', 'y', 'z');
       
   556   }
       
   557 } {}
       
   558 do_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}
       
   565 do_test alter-5.3 {
       
   566   db2 close
       
   567 } {}
       
   568 
       
   569 foreach tblname [execsql {
       
   570   SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite%'
       
   571 }] {
       
   572   execsql "DROP TABLE \"$tblname\""
       
   573 }
       
   574 
       
   575 set ::tbl_name "abc\uABCDdef"
       
   576 do_test alter-6.1 {
       
   577   string length $::tbl_name
       
   578 } {7}
       
   579 do_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)}"
       
   588 execsql "
       
   589   SELECT * FROM ${::tbl_name}
       
   590 "
       
   591 set ::tbl_name2 "abcXdef"
       
   592 do_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)}"
       
   600 do_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)}"
       
   608 set ::col_name ghi\1234\jkl
       
   609 do_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)}"
       
   617 set ::col_name2 B\3421\A
       
   618 do_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)}"
       
   628 do_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 #
       
   638 do_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 #
       
   651 do_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}
       
   661 do_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 #
       
   671 ifcapable trigger {
       
   672   do_test alter-9.1 {
       
   673     execsql {SELECT SQLITE_RENAME_TRIGGER(0,0)}
       
   674   } {{}}
       
   675 }
       
   676 do_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 #
       
   688 do_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]
       
   693 do_test alter-10.2 {
       
   694   execsql {SELECT name FROM sqlite_master WHERE name LIKE 'sqlite_autoindex%'}
       
   695 } [list sqlite_autoindex_xyz\u1234abc_1]
       
   696 do_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]
       
   700 do_test alter-10.4 {
       
   701   execsql {SELECT name FROM sqlite_master WHERE name LIKE 'sqlite_autoindex%'}
       
   702 } [list sqlite_autoindex_xyzabc_1]
       
   703 
       
   704 do_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}}
       
   713 set isutf16 [regexp 16 [db one {PRAGMA encoding}]]
       
   714 if {!$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 }
       
   720 do_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}}
       
   729 if {!$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 }
       
   741 do_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}}
       
   750 if {!$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 
       
   763 do_test alter-12.1 {
       
   764   execsql {
       
   765     CREATE TABLE t12(a, b, c);
       
   766     CREATE VIEW v1 AS SELECT * FROM t12;
       
   767   }
       
   768 } {}
       
   769 do_test alter-12.2 {
       
   770   catchsql {
       
   771     ALTER TABLE v1 RENAME TO v2;
       
   772   }
       
   773 } {1 {view v1 may not be altered}}
       
   774 do_test alter-12.3 {
       
   775   execsql { SELECT * FROM v1; }
       
   776 } {}
       
   777 do_test alter-12.4 {
       
   778   db close
       
   779   sqlite3 db test.db
       
   780   execsql { SELECT * FROM v1; }
       
   781 } {}
       
   782 do_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 # Ticket #3102:
       
   789 # Verify that comments do not interfere with the table rename
       
   790 # algorithm.
       
   791 #
       
   792 do_test alter-13.1 {
       
   793   execsql {
       
   794     CREATE TABLE /* hi */ t3102a(x);
       
   795     CREATE TABLE t3102b -- comment
       
   796     (y);
       
   797     CREATE INDEX t3102c ON t3102a(x);
       
   798     SELECT name FROM sqlite_master WHERE name LIKE 't3102%' ORDER BY 1;
       
   799   }
       
   800 } {t3102a t3102b t3102c}
       
   801 do_test alter-13.2 {
       
   802   execsql {
       
   803     ALTER TABLE t3102a RENAME TO t3102a_rename;
       
   804     SELECT name FROM sqlite_master WHERE name LIKE 't3102%' ORDER BY 1;
       
   805   }
       
   806 } {t3102a_rename t3102b t3102c}
       
   807 do_test alter-13.3 {
       
   808   execsql {
       
   809     ALTER TABLE t3102b RENAME TO t3102b_rename;
       
   810     SELECT name FROM sqlite_master WHERE name LIKE 't3102%' ORDER BY 1;
       
   811   }
       
   812 } {t3102a_rename t3102b_rename t3102c}
       
   813 
       
   814 finish_test