github.com/jdgcs/sqlite3@v1.12.1-0.20210908114423-bc5f96e4dd51/testdata/tcl/altercol.test (about)

     1  # 2009 February 2
     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 that SQLite can handle a subtle 
    13  # file format change that may be used in the future to implement
    14  # "ALTER TABLE ... RENAME COLUMN ... TO".
    15  #
    16  
    17  set testdir [file dirname $argv0]
    18  source $testdir/tester.tcl
    19  set testprefix altercol
    20  
    21  # If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
    22  ifcapable !altertable {
    23    finish_test
    24    return
    25  }
    26  
    27  # Drop all the tables and views in the 'main' database of database connect
    28  # [db]. Sort the objects by name before dropping them.
    29  #
    30  proc drop_all_tables_and_views {db} {
    31    set SQL {
    32      SELECT name, type FROM sqlite_master 
    33      WHERE type IN ('table', 'view') AND name NOT LIKE 'sqlite_%'
    34      ORDER BY 1
    35    }
    36    foreach {z t} [db eval $SQL] {
    37      db eval "DROP $t $z"
    38    }
    39  }
    40  
    41  foreach {tn before after} {
    42    1 {CREATE TABLE t1(a INTEGER, b TEXT, c BLOB)}
    43      {CREATE TABLE t1(a INTEGER, d TEXT, c BLOB)}
    44  
    45    2 {CREATE TABLE t1(a INTEGER, x TEXT, "b" BLOB)}
    46      {CREATE TABLE t1(a INTEGER, x TEXT, "d" BLOB)}
    47  
    48    3 {CREATE TABLE t1(a INTEGER, b TEXT, c BLOB, CHECK(b!=''))}
    49      {CREATE TABLE t1(a INTEGER, d TEXT, c BLOB, CHECK(d!=''))}
    50  
    51    4 {CREATE TABLE t1(a INTEGER, b TEXT, c BLOB, CHECK(t1.b!=''))}
    52      {CREATE TABLE t1(a INTEGER, d TEXT, c BLOB, CHECK(t1.d!=''))}
    53  
    54    5 {CREATE TABLE t1(a INTEGER, b TEXT, c BLOB, CHECK( coalesce(b,c) ))}
    55      {CREATE TABLE t1(a INTEGER, d TEXT, c BLOB, CHECK( coalesce(d,c) ))}
    56  
    57    6 {CREATE TABLE t1(a INTEGER, "b"TEXT, c BLOB, CHECK( coalesce(b,c) ))}
    58      {CREATE TABLE t1(a INTEGER, "d"TEXT, c BLOB, CHECK( coalesce(d,c) ))}
    59  
    60    7 {CREATE TABLE t1(a INTEGER, b TEXT, c BLOB, PRIMARY KEY(b, c))}
    61      {CREATE TABLE t1(a INTEGER, d TEXT, c BLOB, PRIMARY KEY(d, c))}
    62  
    63    8 {CREATE TABLE t1(a INTEGER, b TEXT PRIMARY KEY, c BLOB)}
    64      {CREATE TABLE t1(a INTEGER, d TEXT PRIMARY KEY, c BLOB)}
    65  
    66    9 {CREATE TABLE t1(a, b TEXT, c, PRIMARY KEY(a, b), UNIQUE("B"))}
    67      {CREATE TABLE t1(a, d TEXT, c, PRIMARY KEY(a, d), UNIQUE("d"))}
    68  
    69   10 {CREATE TABLE t1(a, b, c);   CREATE INDEX t1i ON t1(a, c)}
    70      {{CREATE TABLE t1(a, d, c)} {CREATE INDEX t1i ON t1(a, c)}}
    71  
    72   11 {CREATE TABLE t1(a, b, c);   CREATE INDEX t1i ON t1(b, c)}
    73      {{CREATE TABLE t1(a, d, c)} {CREATE INDEX t1i ON t1(d, c)}}
    74  
    75   12 {CREATE TABLE t1(a, b, c);   CREATE INDEX t1i ON t1(b+b+b+b, c) WHERE b>0}
    76      {{CREATE TABLE t1(a, d, c)} {CREATE INDEX t1i ON t1(d+d+d+d, c) WHERE d>0}}
    77  
    78   13 {CREATE TABLE t1(a, b, c, FOREIGN KEY (b) REFERENCES t2)}
    79      {CREATE TABLE t1(a, d, c, FOREIGN KEY (d) REFERENCES t2)}
    80  
    81   14 {CREATE TABLE t1(a INTEGER, b TEXT, c BLOB, PRIMARY KEY(b))}
    82      {CREATE TABLE t1(a INTEGER, d TEXT, c BLOB, PRIMARY KEY(d))}
    83  
    84   15 {CREATE TABLE t1(a INTEGER, b INTEGER, c BLOB, PRIMARY KEY(b))}
    85      {CREATE TABLE t1(a INTEGER, d INTEGER, c BLOB, PRIMARY KEY(d))}
    86  
    87   16 {CREATE TABLE t1(a INTEGER, b INTEGER PRIMARY KEY, c BLOB)}
    88      {CREATE TABLE t1(a INTEGER, d INTEGER PRIMARY KEY, c BLOB)}
    89  
    90   17  {CREATE TABLE t1(a INTEGER, b INTEGER PRIMARY KEY, c BLOB, FOREIGN KEY (b) REFERENCES t2)}
    91       {CREATE TABLE t1(a INTEGER, d INTEGER PRIMARY KEY, c BLOB, FOREIGN KEY (d) REFERENCES t2)}
    92  
    93  } {
    94    reset_db
    95    do_execsql_test 1.$tn.0 $before
    96  
    97    do_execsql_test 1.$tn.1 {
    98      INSERT INTO t1 VALUES(1, 2, 3);
    99    }
   100  
   101    do_execsql_test 1.$tn.2 {
   102      ALTER TABLE t1 RENAME COLUMN b TO d;
   103    }
   104  
   105    do_execsql_test 1.$tn.3 {
   106      SELECT * FROM t1;
   107    } {1 2 3}
   108  
   109    if {[string first INDEX $before]>0} {
   110      set res $after
   111    } else {
   112      set res [list $after]
   113    }
   114    do_execsql_test 1.$tn.4 {
   115      SELECT sql FROM sqlite_master WHERE tbl_name='t1' AND sql!=''
   116    } $res
   117  }
   118  
   119  #-------------------------------------------------------------------------
   120  #
   121  do_execsql_test 2.0 {
   122    CREATE TABLE t3(a, b, c, d, e, f, g, h, i, j, k, l, m, FOREIGN KEY (b, c, d, e, f, g, h, i, j, k, l, m) REFERENCES t4);
   123  }
   124  
   125  sqlite3 db2 test.db
   126  do_execsql_test -db db2 2.1 { SELECT b FROM t3 }
   127  
   128  do_execsql_test 2.2 {
   129    ALTER TABLE t3 RENAME b TO biglongname;
   130    SELECT sql FROM sqlite_master WHERE name='t3';
   131  } {{CREATE TABLE t3(a, biglongname, c, d, e, f, g, h, i, j, k, l, m, FOREIGN KEY (biglongname, c, d, e, f, g, h, i, j, k, l, m) REFERENCES t4)}}
   132  
   133  do_execsql_test -db db2 2.3 { SELECT biglongname FROM t3 }
   134  
   135  #-------------------------------------------------------------------------
   136  #
   137  do_execsql_test 3.0 {
   138    CREATE TABLE t4(x, y, z);
   139    CREATE TRIGGER ttt AFTER INSERT ON t4 WHEN new.y<0 BEGIN
   140      SELECT x, y, z FROM t4;
   141      DELETE FROM t4 WHERE y=32;
   142      UPDATE t4 SET x=y+1, y=0 WHERE y=32;
   143      INSERT INTO t4(x, y, z) SELECT 4, 5, 6 WHERE 0;
   144    END;
   145    INSERT INTO t4 VALUES(3, 2, 1);
   146  }
   147  
   148  do_execsql_test 3.1 {
   149    ALTER TABLE t4 RENAME y TO abc;
   150    SELECT sql FROM sqlite_master WHERE name='t4';
   151  } {{CREATE TABLE t4(x, abc, z)}}
   152  
   153  do_execsql_test 3.2 {
   154    SELECT * FROM t4;
   155  } {3 2 1}
   156  
   157  do_execsql_test 3.3 { INSERT INTO t4 VALUES(6, 5, 4); } {}
   158  
   159  do_execsql_test 3.4 { SELECT sql FROM sqlite_master WHERE type='trigger' } {
   160  {CREATE TRIGGER ttt AFTER INSERT ON t4 WHEN new.abc<0 BEGIN
   161      SELECT x, abc, z FROM t4;
   162      DELETE FROM t4 WHERE abc=32;
   163      UPDATE t4 SET x=abc+1, abc=0 WHERE abc=32;
   164      INSERT INTO t4(x, abc, z) SELECT 4, 5, 6 WHERE 0;
   165    END}
   166  }
   167  
   168  #-------------------------------------------------------------------------
   169  #
   170  do_execsql_test 4.0 {
   171    CREATE TABLE c1(a, b, FOREIGN KEY (a, b) REFERENCES p1(c, d));
   172    CREATE TABLE p1(c, d, PRIMARY KEY(c, d));
   173    PRAGMA foreign_keys = 1;
   174    INSERT INTO p1 VALUES(1, 2);
   175    INSERT INTO p1 VALUES(3, 4);
   176  }
   177  
   178  do_execsql_test 4.1 {
   179    ALTER TABLE p1 RENAME d TO "silly name";
   180    SELECT sql FROM sqlite_master WHERE name IN ('c1', 'p1');
   181  } {
   182    {CREATE TABLE c1(a, b, FOREIGN KEY (a, b) REFERENCES p1(c, "silly name"))}
   183    {CREATE TABLE p1(c, "silly name", PRIMARY KEY(c, "silly name"))}
   184  }
   185  
   186  do_execsql_test 4.2 { INSERT INTO c1 VALUES(1, 2); }
   187  
   188  do_execsql_test 4.3 {
   189    CREATE TABLE c2(a, b, FOREIGN KEY (a, b) REFERENCES p1);
   190  }
   191  
   192  do_execsql_test 4.4 {
   193    ALTER TABLE p1 RENAME "silly name" TO reasonable;
   194    SELECT sql FROM sqlite_master WHERE name IN ('c1', 'c2', 'p1');
   195  } {
   196    {CREATE TABLE c1(a, b, FOREIGN KEY (a, b) REFERENCES p1(c, "reasonable"))}
   197    {CREATE TABLE p1(c, "reasonable", PRIMARY KEY(c, "reasonable"))}
   198    {CREATE TABLE c2(a, b, FOREIGN KEY (a, b) REFERENCES p1)}
   199  }
   200  
   201  #-------------------------------------------------------------------------
   202  
   203  do_execsql_test 5.0 {
   204    CREATE TABLE t5(a, b, c);
   205    CREATE INDEX t5a ON t5(a);
   206    INSERT INTO t5 VALUES(1, 2, 3), (4, 5, 6);
   207    ANALYZE;
   208  }
   209  
   210  do_execsql_test 5.1 {
   211    ALTER TABLE t5 RENAME b TO big;
   212    SELECT big FROM t5;
   213  } {2 5}
   214  
   215  do_catchsql_test 6.1 {
   216    ALTER TABLE sqlite_stat1 RENAME tbl TO thetable;
   217  } {1 {table sqlite_stat1 may not be altered}}
   218  
   219  #-------------------------------------------------------------------------
   220  #
   221  do_execsql_test 6.0 {
   222    CREATE TABLE blob(
   223      rid INTEGER PRIMARY KEY,
   224      rcvid INTEGER,
   225      size INTEGER,
   226      uuid TEXT UNIQUE NOT NULL,
   227      content BLOB,
   228      CHECK( length(uuid)>=40 AND rid>0 )
   229    );
   230  }
   231  
   232  do_execsql_test 6.1 {
   233    ALTER TABLE "blob" RENAME COLUMN "rid" TO "a1";
   234  }
   235  
   236  do_catchsql_test 6.2 {
   237    ALTER TABLE "blob" RENAME COLUMN "a1" TO [where];
   238  } {0 {}}
   239  
   240  do_execsql_test 6.3 {
   241    SELECT "where" FROM blob;
   242  } {}
   243  
   244  #-------------------------------------------------------------------------
   245  # Triggers.
   246  #
   247  db close
   248  db2 close
   249  reset_db
   250  do_execsql_test 7.0 {
   251    CREATE TABLE c(x);
   252    INSERT INTO c VALUES(0);
   253    CREATE TABLE t6("col a", "col b", "col c");
   254    CREATE TRIGGER zzz AFTER UPDATE OF "col a", "col c" ON t6 BEGIN
   255      UPDATE c SET x=x+1;
   256    END;
   257  }
   258  
   259  do_execsql_test 7.1.1 {
   260    INSERT INTO t6 VALUES(0, 0, 0);
   261    UPDATE t6 SET "col c" = 1;
   262    SELECT * FROM c;
   263  } {1}
   264  
   265  do_execsql_test 7.1.2 {
   266    ALTER TABLE t6 RENAME "col c" TO "col 3";
   267  }
   268  
   269  do_execsql_test 7.1.3 {
   270    UPDATE t6 SET "col 3" = 0;
   271    SELECT * FROM c;
   272  } {2}
   273  
   274  #-------------------------------------------------------------------------
   275  # Views.
   276  #
   277  reset_db
   278  do_execsql_test 8.0 {
   279    CREATE TABLE a1(x INTEGER, y TEXT, z BLOB, PRIMARY KEY(x));
   280    CREATE TABLE a2(a, b, c);
   281    CREATE VIEW v1 AS SELECT x, y, z FROM a1;
   282  }
   283  
   284  do_execsql_test 8.1 {
   285    ALTER TABLE a1 RENAME y TO yyy;
   286    SELECT sql FROM sqlite_master WHERE type='view';
   287  } {{CREATE VIEW v1 AS SELECT x, yyy, z FROM a1}}
   288  
   289  do_execsql_test 8.2.1 {
   290    DROP VIEW v1;
   291    CREATE VIEW v2 AS SELECT x, x+x, a, a+a FROM a1, a2;
   292  } {}
   293  do_execsql_test 8.2.2 {
   294    ALTER TABLE a1 RENAME x TO xxx;
   295  }
   296  do_execsql_test 8.2.3 {
   297    SELECT sql FROM sqlite_master WHERE type='view';
   298  } {{CREATE VIEW v2 AS SELECT xxx, xxx+xxx, a, a+a FROM a1, a2}}
   299  
   300  do_execsql_test 8.3.1 {
   301    DROP TABLE a2;
   302    DROP VIEW v2;
   303    CREATE TABLE a2(a INTEGER PRIMARY KEY, b, c);
   304    CREATE VIEW v2 AS SELECT xxx, xxx+xxx, a, a+a FROM a1, a2;
   305  } {}
   306  do_execsql_test 8.3.2 {
   307    ALTER TABLE a1 RENAME xxx TO x;
   308  }
   309  do_execsql_test 8.3.3 {
   310    SELECT sql FROM sqlite_master WHERE type='view';
   311  } {{CREATE VIEW v2 AS SELECT x, x+x, a, a+a FROM a1, a2}}
   312  
   313  do_execsql_test 8.4.0 {
   314    CREATE TABLE b1(a, b, c);
   315    CREATE TABLE b2(x, y, z);
   316  }
   317  
   318  do_execsql_test 8.4.1 {
   319    CREATE VIEW vvv AS SELECT c+c || coalesce(c, c) FROM b1, b2 WHERE x=c GROUP BY c HAVING c>0;
   320    ALTER TABLE b1 RENAME c TO "a;b";
   321    SELECT sql FROM sqlite_master WHERE name='vvv';
   322  } {{CREATE VIEW vvv AS SELECT "a;b"+"a;b" || coalesce("a;b", "a;b") FROM b1, b2 WHERE x="a;b" GROUP BY "a;b" HAVING "a;b">0}}
   323  
   324  do_execsql_test 8.4.2 {
   325    CREATE VIEW www AS SELECT b FROM b1 UNION ALL SELECT y FROM b2;
   326    ALTER TABLE b1 RENAME b TO bbb;
   327    SELECT sql FROM sqlite_master WHERE name='www';
   328  } {{CREATE VIEW www AS SELECT bbb FROM b1 UNION ALL SELECT y FROM b2}}
   329  
   330  db collate nocase {string compare}
   331  
   332  do_execsql_test 8.4.3 {
   333    CREATE VIEW xxx AS SELECT a FROM b1 UNION SELECT x FROM b2 ORDER BY 1 COLLATE nocase;
   334  }
   335  
   336  do_execsql_test 8.4.4 {
   337    ALTER TABLE b2 RENAME x TO hello;
   338    SELECT sql FROM sqlite_master WHERE name='xxx';
   339  } {{CREATE VIEW xxx AS SELECT a FROM b1 UNION SELECT hello FROM b2 ORDER BY 1 COLLATE nocase}}
   340  
   341  do_catchsql_test 8.4.5 {
   342    CREATE VIEW zzz AS SELECT george, ringo FROM b1;
   343    ALTER TABLE b1 RENAME a TO aaa;
   344  } {1 {error in view zzz: no such column: george}}
   345  
   346  #-------------------------------------------------------------------------
   347  # More triggers.
   348  #
   349  proc do_rename_column_test {tn old new lSchema} {
   350    for {set i 0} {$i < 2} {incr i} {
   351      drop_all_tables_and_views db
   352  
   353      set lSorted [list]
   354      foreach sql $lSchema { 
   355        execsql $sql 
   356        lappend lSorted [string trim $sql]
   357      }
   358      set lSorted [lsort $lSorted]
   359  
   360      do_execsql_test $tn.$i.1 {
   361        SELECT sql FROM sqlite_master WHERE sql!='' ORDER BY 1
   362      } $lSorted
   363  
   364      if {$i==1} {
   365        db close
   366        sqlite3 db test.db
   367      }
   368  
   369      do_execsql_test $tn.$i.2 "ALTER TABLE t1 RENAME $old TO $new"
   370  
   371      do_execsql_test $tn.$i.3 {
   372        SELECT sql FROM sqlite_master ORDER BY 1
   373      } [string map [list $old $new] $lSorted]
   374    }
   375  }
   376  
   377  foreach {tn old new lSchema} {
   378    1 _x_ _xxx_ {
   379      { CREATE TABLE t1(a, b, _x_) }
   380      { CREATE TRIGGER AFTER INSERT ON t1 BEGIN
   381          SELECT _x_ FROM t1;
   382        END }
   383    }
   384  
   385    2 _x_ _xxx_ {
   386      { CREATE TABLE t1(a, b, _x_) }
   387      { CREATE TABLE t2(c, d, e) }
   388      { CREATE TRIGGER ttt AFTER INSERT ON t2 BEGIN
   389          SELECT _x_ FROM t1;
   390        END }
   391    }
   392  
   393    3 _x_ _xxx_ {
   394      { CREATE TABLE t1(a, b, _x_ INTEGER, PRIMARY KEY(_x_), CHECK(_x_>0)) }
   395      { CREATE TABLE t2(c, d, e) }
   396      { CREATE TRIGGER ttt AFTER UPDATE  ON t1 BEGIN
   397          INSERT INTO t2 VALUES(new.a, new.b, new._x_);
   398        END }
   399    }
   400  
   401    4 _x_ _xxx_ {
   402      { CREATE TABLE t1(a, b, _x_ INTEGER, PRIMARY KEY(_x_), CHECK(_x_>0)) }
   403      { CREATE TRIGGER ttt AFTER UPDATE  ON t1 BEGIN
   404          INSERT INTO t1 VALUES(new.a, new.b, new._x_)
   405            ON CONFLICT (_x_) WHERE _x_>10 DO UPDATE SET _x_ = _x_+1;
   406        END }
   407    }
   408  
   409    4 _x_ _xxx_ {
   410      { CREATE TABLE t1(a, b, _x_ INTEGER, PRIMARY KEY(_x_), CHECK(_x_>0)) }
   411      { CREATE TRIGGER ttt AFTER UPDATE  ON t1 BEGIN
   412          INSERT INTO t1 VALUES(new.a, new.b, new._x_)
   413            ON CONFLICT (_x_) WHERE _x_>10 DO NOTHING;
   414        END }
   415    }
   416  } {
   417    do_rename_column_test 9.$tn $old $new $lSchema
   418  }
   419  
   420  #-------------------------------------------------------------------------
   421  # Test that views can be edited even if there are missing collation 
   422  # sequences or user defined functions.
   423  #
   424  reset_db
   425  
   426  ifcapable vtab {
   427    foreach {tn old new lSchema} {
   428      1 _x_ _xxx_ {
   429        { CREATE TABLE t1(a, b, _x_) }
   430        { CREATE VIEW s1 AS SELECT a, b, _x_ FROM t1 WHERE _x_='abc' COLLATE xyz }
   431      }
   432    
   433      2 _x_ _xxx_ {
   434        { CREATE TABLE t1(a, b, _x_) }
   435        { CREATE VIEW v1 AS SELECT a, b, _x_ FROM t1 WHERE scalar(_x_) }
   436      }
   437    
   438      3 _x_ _xxx_ {
   439        { CREATE TABLE t1(a, b, _x_) }
   440        { CREATE VIEW v1 AS SELECT a, b, _x_ FROM t1 WHERE _x_ = unicode(1, 2, 3) }
   441      }
   442    
   443      4 _x_ _xxx_ {
   444        { CREATE TABLE t1(a, b, _x_) }
   445        { CREATE VIRTUAL TABLE e1 USING echo(t1) }
   446      }
   447    } {
   448      register_echo_module db
   449      do_rename_column_test 10.$tn $old $new $lSchema
   450    }
   451    
   452    #--------------------------------------------------------------------------
   453    # Test that if a view or trigger refers to a virtual table for which the
   454    # module is not available, RENAME COLUMN cannot proceed.
   455    #
   456    reset_db
   457    register_echo_module db
   458    do_execsql_test 11.0 {
   459      CREATE TABLE x1(a, b, c);
   460      CREATE VIRTUAL TABLE e1 USING echo(x1);
   461    }
   462    db close
   463    sqlite3 db test.db
   464    
   465    do_execsql_test 11.1 {
   466      ALTER TABLE x1 RENAME b TO bbb;
   467      SELECT sql FROM sqlite_master;
   468    } { {CREATE TABLE x1(a, bbb, c)} {CREATE VIRTUAL TABLE e1 USING echo(x1)} }
   469    
   470    do_execsql_test 11.2 {
   471      CREATE VIEW v1 AS SELECT e1.*, x1.c FROM e1, x1;
   472    }
   473    
   474    do_catchsql_test 11.3 {
   475      ALTER TABLE x1 RENAME c TO ccc;
   476    } {1 {error in view v1: no such module: echo}}
   477  }
   478  
   479  #-------------------------------------------------------------------------
   480  # Test some error conditions:
   481  #
   482  #   1. Renaming a column of a system table,
   483  #   2. Renaming a column of a VIEW,
   484  #   3. Renaming a column of a virtual table.
   485  #   4. Renaming a column that does not exist.
   486  #   5. Renaming a column of a table that does not exist.
   487  #
   488  reset_db
   489  do_execsql_test 12.1.1 {
   490    CREATE TABLE t1(a, b);
   491    CREATE INDEX t1a ON t1(a);
   492    INSERT INTO t1 VALUES(1, 1), (2, 2), (3, 4);
   493    ANALYZE;
   494  }
   495  do_catchsql_test 12.1.2 {
   496    ALTER TABLE sqlite_stat1 RENAME idx TO theindex;
   497  } {1 {table sqlite_stat1 may not be altered}}
   498  do_execsql_test 12.1.3 {
   499    SELECT sql FROM sqlite_master WHERE tbl_name = 'sqlite_stat1'
   500  } {{CREATE TABLE sqlite_stat1(tbl,idx,stat)}}
   501  
   502  do_execsql_test 12.2.1 {
   503    CREATE VIEW v1 AS SELECT * FROM t1;
   504    CREATE VIEW v2(c, d) AS SELECT * FROM t1;
   505  }
   506  do_catchsql_test 12.2.2 {
   507    ALTER TABLE v1 RENAME a TO z;
   508  } {1 {cannot rename columns of view "v1"}}
   509  do_catchsql_test 12.2.3 {
   510    ALTER TABLE v2 RENAME c TO y;
   511  } {1 {cannot rename columns of view "v2"}}
   512  
   513  ifcapable fts5 {
   514    do_execsql_test 12.3.1 {
   515      CREATE VIRTUAL TABLE ft USING fts5(a, b, c);
   516    }
   517    do_catchsql_test 12.3.2 {
   518      ALTER TABLE ft RENAME a TO z;
   519    } {1 {cannot rename columns of virtual table "ft"}}
   520  }
   521  
   522  do_execsql_test 12.4.1 {
   523    CREATE TABLE t2(x, y, z);
   524  }
   525  do_catchsql_test 12.4.2 {
   526    ALTER TABLE t2 RENAME COLUMN a TO b;
   527  } {1 {no such column: "a"}}
   528  
   529  do_catchsql_test 12.5.1 {
   530    ALTER TABLE t3 RENAME COLUMN a TO b;
   531  } {1 {no such table: t3}}
   532  
   533  #-------------------------------------------------------------------------
   534  # Test the effect of some parse/resolve errors.
   535  #
   536  reset_db
   537  do_execsql_test 13.1.1 {
   538    CREATE TABLE x1(i INTEGER, t TEXT UNIQUE);
   539    CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN
   540      SELECT * FROM nosuchtable;
   541    END;
   542  }
   543  
   544  do_catchsql_test 13.1.2 {
   545    ALTER TABLE x1 RENAME COLUMN t TO ttt;
   546  } {1 {error in trigger tr1: no such table: main.nosuchtable}}
   547  
   548  do_execsql_test 13.1.3 {
   549    DROP TRIGGER tr1;
   550    CREATE INDEX x1i ON x1(i);
   551    SELECT sql FROM sqlite_master WHERE name='x1i';
   552  } {{CREATE INDEX x1i ON x1(i)}}
   553  
   554  sqlite3_db_config db DEFENSIVE 0
   555  do_execsql_test 13.1.4 {
   556    PRAGMA writable_schema = 1;
   557    UPDATE sqlite_master SET sql = 'CREATE INDEX x1i ON x1(j)' WHERE name='x1i';
   558  } {}
   559  
   560  do_catchsql_test 13.1.5 {
   561    ALTER TABLE x1 RENAME COLUMN t TO ttt;
   562  } {1 {error in index x1i: no such column: j}}
   563  
   564  do_execsql_test 13.1.6 {
   565    UPDATE sqlite_master SET sql = '' WHERE name='x1i';
   566  } {}
   567  
   568  do_catchsql_test 13.1.7 {
   569    ALTER TABLE x1 RENAME COLUMN t TO ttt;
   570  } {1 {error in index x1i: }}
   571  
   572  do_execsql_test 13.1.8 {
   573    DELETE FROM sqlite_master WHERE name = 'x1i';
   574  }
   575  
   576  do_execsql_test 13.2.0 {
   577    CREATE TABLE data(x UNIQUE, y, z);
   578  }
   579  foreach {tn trigger error} {
   580    1 {
   581      CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN
   582        UPDATE data SET x=x+1 WHERE zzz=new.i;
   583      END;
   584    } {no such column: zzz}
   585  
   586    2 {
   587      CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN
   588        INSERT INTO data(x, y) VALUES(new.i, new.t, 1) 
   589          ON CONFLICT (x) DO UPDATE SET z=zz+1;
   590      END;
   591    } {no such column: zz}
   592  
   593    3 {
   594      CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN
   595        INSERT INTO x1(i, t) VALUES(new.i+1, new.t||'1') 
   596          ON CONFLICT (tttttt) DO UPDATE SET t=i+1;
   597      END;
   598    } {no such column: tttttt}
   599  
   600    4 {
   601      CREATE TRIGGER tr1 AFTER INSERT ON x1 BEGIN
   602        INSERT INTO nosuchtable VALUES(new.i, new.t);
   603      END;
   604    } {no such table: main.nosuchtable}
   605  } {
   606    do_execsql_test 13.2.$tn.1 "
   607      DROP TRIGGER IF EXISTS tr1;
   608      $trigger
   609    "
   610  
   611    do_catchsql_test 13.2.$tn.2 {
   612      ALTER TABLE x1 RENAME COLUMN t TO ttt;
   613    } "1 {error in trigger tr1: $error}"
   614  }
   615  
   616  #-------------------------------------------------------------------------
   617  # Passing invalid parameters directly to sqlite_rename_column().
   618  #
   619  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
   620  do_execsql_test 14.1 {
   621    CREATE TABLE ddd(sql, type, object, db, tbl, icol, znew, bquote);
   622    INSERT INTO ddd VALUES(
   623        'CREATE TABLE x1(i INTEGER, t TEXT)',
   624        'table', 'x1', 'main', 'x1', -1, 'zzz', 0
   625    ), (
   626        'CREATE TABLE x1(i INTEGER, t TEXT)',
   627        'table', 'x1', 'main', 'x1', 2, 'zzz', 0
   628    ), (
   629        'CREATE TABLE x1(i INTEGER, t TEXT)',
   630        'table', 'x1', 'main', 'notable', 0, 'zzz', 0
   631    ), (
   632        'CREATE TABLE x1(i INTEGER, t TEXT)',
   633        'table', 'x1', 'main', 'ddd', -1, 'zzz', 0
   634    );
   635  } {}
   636  
   637  do_execsql_test 14.2 {
   638    SELECT 
   639    sqlite_rename_column(sql, type, object, db, tbl, icol, znew, bquote, 0)
   640    FROM ddd;
   641  } {{} {} {} {}}
   642  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
   643  
   644  # If the INTERNAL_FUNCTIONS test-control is disabled (which is the default)
   645  # then the sqlite_rename_table() SQL function is not accessible to
   646  # ordinary SQL.
   647  #
   648  do_catchsql_test 14.3 {
   649    SELECT sqlite_rename_column(0,0,0,0,0,0,0,0,0);
   650  } {1 {no such function: sqlite_rename_column}}
   651  
   652  #-------------------------------------------------------------------------
   653  #
   654  reset_db
   655  do_execsql_test 15.0 {
   656    CREATE TABLE xxx(a, b, c);
   657    SELECT a AS d FROM xxx WHERE d=0;
   658  }
   659  
   660  do_execsql_test 15.1 {
   661    CREATE VIEW vvv AS SELECT a AS d FROM xxx WHERE d=0;
   662    ALTER TABLE xxx RENAME a TO xyz;
   663  }
   664  
   665  do_execsql_test 15.2 {
   666    SELECT sql FROM sqlite_master WHERE type='view';
   667  } {{CREATE VIEW vvv AS SELECT xyz AS d FROM xxx WHERE d=0}}
   668  
   669  #-------------------------------------------------------------------------
   670  #
   671  do_execsql_test 16.1.0 {
   672    CREATE TABLE t1(a,b,c);
   673    CREATE TABLE t2(d,e,f);
   674    INSERT INTO t1 VALUES(1,2,3);
   675    INSERT INTO t2 VALUES(4,5,6);
   676    CREATE VIEW v4 AS SELECT a, d FROM t1, t2;
   677    SELECT * FROM v4;
   678  } {1 4}
   679  
   680  do_catchsql_test 16.1.1 {
   681    ALTER TABLE t2 RENAME d TO a;
   682  } {1 {error in view v4 after rename: ambiguous column name: a}}
   683  
   684  do_execsql_test 16.1.2 {
   685    SELECT * FROM v4;
   686  } {1 4}
   687  
   688  do_execsql_test 16.1.3 {
   689    CREATE UNIQUE INDEX t2d ON t2(d);
   690    CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
   691      INSERT INTO t2 VALUES(new.a, new.b, new.c)
   692        ON CONFLICT(d) DO UPDATE SET f = excluded.f;
   693    END;
   694  }
   695  
   696  do_execsql_test 16.1.4 {
   697    INSERT INTO t1 VALUES(4, 8, 456);
   698    SELECT * FROM t2;
   699  } {4 5 456}
   700  
   701  do_execsql_test 16.1.5 {
   702    ALTER TABLE t2 RENAME COLUMN f TO "big f";
   703    INSERT INTO t1 VALUES(4, 0, 20456);
   704    SELECT * FROM t2;
   705  } {4 5 20456}
   706  
   707  do_execsql_test 16.1.6 {
   708    ALTER TABLE t1 RENAME COLUMN c TO "big c";
   709    INSERT INTO t1 VALUES(4, 0, 0);
   710    SELECT * FROM t2;
   711  } {4 5 0}
   712  
   713  do_execsql_test 16.2.1 {
   714    CREATE VIEW temp.v5 AS SELECT "big c" FROM t1; 
   715    SELECT * FROM v5;
   716  } {3 456 20456 0}
   717  
   718  do_execsql_test 16.2.2 {
   719    ALTER TABLE t1 RENAME COLUMN "big c" TO reallybigc;
   720  } {}
   721  
   722  do_execsql_test 16.2.3 {
   723    SELECT * FROM v5;
   724  } {3 456 20456 0}
   725  
   726  #-------------------------------------------------------------------------
   727  #
   728  do_execsql_test 17.0 {
   729    CREATE TABLE u7(x, y, z);
   730    CREATE TRIGGER u7t AFTER INSERT ON u7 BEGIN
   731      INSERT INTO u8 VALUES(new.x, new.y, new.z);
   732    END;
   733  } {}
   734  do_catchsql_test 17.1 {
   735    ALTER TABLE u7 RENAME x TO xxx;
   736  } {1 {error in trigger u7t: no such table: main.u8}}
   737  
   738  do_execsql_test 17.2 {
   739    CREATE TEMP TABLE uu7(x, y, z);
   740    CREATE TRIGGER uu7t AFTER INSERT ON uu7 BEGIN
   741      INSERT INTO u8 VALUES(new.x, new.y, new.z);
   742    END;
   743  } {}
   744  do_catchsql_test 17.3 {
   745    ALTER TABLE uu7 RENAME x TO xxx;
   746  } {1 {error in trigger uu7t: no such table: u8}}
   747  
   748  reset_db
   749  forcedelete test.db2
   750  do_execsql_test 18.0 {
   751    ATTACH 'test.db2' AS aux;
   752    CREATE TABLE t1(a);
   753    CREATE TABLE aux.log(v);
   754    CREATE TEMP TRIGGER tr1 AFTER INSERT ON t1 BEGIN
   755      INSERT INTO log VALUES(new.a);
   756    END;
   757    INSERT INTO t1 VALUES(111);
   758    SELECT v FROM log;
   759  } {111}
   760  
   761  do_execsql_test 18.1 {
   762    ALTER TABLE t1 RENAME a TO b;
   763  }
   764  
   765  reset_db
   766  do_execsql_test 19.0 {
   767    CREATE TABLE t1(a, b);
   768    CREATE TABLE t2(c, d);
   769    CREATE VIEW v2(e) AS SELECT coalesce(t2.c,t1.a) FROM t1, t2 WHERE t1.b=t2.d;
   770  }
   771  
   772  do_execsql_test 19.1 {
   773    ALTER TABLE t1 RENAME a TO f;
   774    SELECT sql FROM sqlite_master WHERE name = 'v2';
   775  } {
   776    {CREATE VIEW v2(e) AS SELECT coalesce(t2.c,t1.f) FROM t1, t2 WHERE t1.b=t2.d}
   777  }
   778  
   779  # 2019-01-08: https://www.sqlite.org/src/tktview/bc8d94f0fbd633fd9a051e3
   780  #
   781  # ALTER TABLE RENAME COLUMN does not work for tables that have redundant
   782  # UNIQUE constraints.
   783  #
   784  sqlite3 db :memory:
   785  do_execsql_test 20.100 {
   786    CREATE TABLE t1(aaa,b,c,UNIQUE(aaA),PRIMARY KEY(aAa),UNIQUE(aAA));
   787    ALTER TABLE t1 RENAME aaa TO bbb;
   788    SELECT sql FROM sqlite_master WHERE name='t1';
   789  } {{CREATE TABLE t1(bbb,b,c,UNIQUE(bbb),PRIMARY KEY(bbb),UNIQUE(bbb))}}
   790  do_execsql_test 20.105 {
   791    DROP TABLE t1;
   792    CREATE TABLE t1(aaa,b,c,UNIQUE(aaA),PRIMARY KEY(aAa),UNIQUE(aAA))WITHOUT ROWID;
   793    ALTER TABLE t1 RENAME aaa TO bbb;
   794    SELECT sql FROM sqlite_master WHERE name='t1';
   795  } {{CREATE TABLE t1(bbb,b,c,UNIQUE(bbb),PRIMARY KEY(bbb),UNIQUE(bbb))WITHOUT ROWID}}
   796  do_execsql_test 20.110 {
   797    DROP TABLE t1;
   798    CREATE TABLE t1(aa UNIQUE,bb UNIQUE,cc UNIQUE,UNIQUE(aA),PRIMARY KEY(bB),UNIQUE(cC));
   799    ALTER TABLE t1 RENAME aa TO xx;
   800    ALTER TABLE t1 RENAME bb TO yy;
   801    ALTER TABLE t1 RENAME cc TO zz;
   802    SELECT sql FROM sqlite_master WHERE name='t1';
   803  } {{CREATE TABLE t1(xx UNIQUE,yy UNIQUE,zz UNIQUE,UNIQUE(xx),PRIMARY KEY(yy),UNIQUE(zz))}}
   804  
   805  #-------------------------------------------------------------------------
   806  reset_db
   807  do_execsql_test 21.0 {
   808    CREATE TABLE t1(a, b, c NOT NULL);
   809    CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN new.c IS NOT NULL BEGIN
   810      SELECT c NOT NULL FROM t1;
   811    END;
   812  }
   813  
   814  do_execsql_test 21.1 {
   815    ALTER TABLE t1 RENAME c TO d;
   816  }
   817  
   818  do_execsql_test 21.2 {
   819    SELECT sql FROM sqlite_schema WHERE name IS 'tr1'
   820  } {{CREATE TRIGGER tr1 AFTER INSERT ON t1 WHEN new.d IS NOT NULL BEGIN
   821      SELECT d NOT NULL FROM t1;
   822    END}
   823  }
   824  
   825  #-------------------------------------------------------------------------
   826  #
   827  reset_db
   828  do_execsql_test 22.0 {
   829    CREATE TABLE t1(a, b);
   830    CREATE TABLE t2(c, othername, extra AS (c + 1));
   831    ALTER TABLE t1 RENAME a to othername;
   832    SELECT sql FROM sqlite_schema;
   833  } {
   834    {CREATE TABLE t1(othername, b)}
   835    {CREATE TABLE t2(c, othername, extra AS (c + 1))}
   836  }
   837  
   838  #-------------------------------------------------------------------------
   839  #
   840  reset_db
   841  do_execsql_test 22.0 {
   842    CREATE TABLE t1(a, b);
   843    CREATE INDEX x1 on t1("c"=b);
   844    INSERT INTO t1 VALUES('a', 'a');
   845    INSERT INTO t1 VALUES('b', 'b');
   846    INSERT INTO t1 VALUES('c', 'c');
   847    ALTER TABLE t1 RENAME COLUMN a TO "c";
   848    PRAGMA integrity_check;
   849  } {ok}
   850  
   851  reset_db
   852  do_execsql_test 23.0 {
   853    CREATE TABLE t1('a'"b",c);
   854    CREATE INDEX i1 ON t1('a');
   855    INSERT INTO t1 VALUES(1,2), (3,4);
   856    ALTER TABLE t1 RENAME COLUMN a TO x;
   857    PRAGMA integrity_check;
   858    SELECT sql FROM sqlite_schema WHERE name='t1';
   859  
   860  } {ok {CREATE TABLE t1("x" "b",c)}}
   861  
   862  
   863  finish_test