000001  # 2010 November 30
000002  #
000003  # The author disclaims copyright to this source code.  In place of
000004  # a legal notice, here is a blessing:
000005  #
000006  #    May you do good and not evil.
000007  #    May you find forgiveness for yourself and forgive others.
000008  #    May you share freely, never taking more than you give.
000009  #
000010  #***********************************************************************
000011  #
000012  # This file implements tests to verify that the "testable statements" in 
000013  # the lang_dropview.html document are correct.
000014  #
000015  
000016  set testdir [file dirname $argv0]
000017  source $testdir/tester.tcl
000018  set ::testprefix e_dropview
000019  
000020  proc dropview_reopen_db {} {
000021    db close
000022    forcedelete test.db test.db2
000023    sqlite3 db test.db
000024  
000025    db eval {
000026      ATTACH 'test.db2' AS aux;
000027      CREATE TABLE t1(a, b); 
000028      INSERT INTO t1 VALUES('a main', 'b main');
000029      CREATE VIEW v1 AS SELECT * FROM t1;
000030      CREATE VIEW v2 AS SELECT * FROM t1;
000031  
000032      CREATE TEMP TABLE t1(a, b);
000033      INSERT INTO temp.t1 VALUES('a temp', 'b temp');
000034      CREATE VIEW temp.v1 AS SELECT * FROM t1;
000035  
000036      CREATE TABLE aux.t1(a, b);
000037      INSERT INTO aux.t1 VALUES('a aux', 'b aux');
000038      CREATE VIEW aux.v1 AS SELECT * FROM t1;
000039      CREATE VIEW aux.v2 AS SELECT * FROM t1;
000040      CREATE VIEW aux.v3 AS SELECT * FROM t1;
000041    }
000042  }
000043  
000044  proc list_all_views {{db db}} {
000045    set res [list]
000046    $db eval { PRAGMA database_list } {
000047      set tbl "$name.sqlite_master"
000048      if {$name == "temp"} { set tbl temp.sqlite_master }
000049  
000050      set sql "SELECT '$name.' || name FROM $tbl WHERE type = 'view'"
000051      lappend res {*}[$db eval $sql]
000052    }
000053    set res
000054  }
000055  
000056  proc list_all_data {{db db}} {
000057    set res [list]
000058    $db eval { PRAGMA database_list } {
000059      set tbl "$name.sqlite_master"
000060      if {$name == "temp"} { set tbl sqlite_temp_master }
000061  
000062      db eval "SELECT '$name.' || name AS x FROM $tbl WHERE type = 'table'" {
000063        lappend res [list $x [db eval "SELECT * FROM $x"]]
000064      }
000065    }
000066    set res
000067  }
000068  
000069  proc do_dropview_tests {nm args} {
000070    uplevel do_select_tests $nm $args
000071  }
000072  
000073  # -- syntax diagram drop-view-stmt
000074  #
000075  # All paths in the syntax diagram for DROP VIEW are tested by tests 1.*.
000076  #
000077  do_dropview_tests 1 -repair {
000078    dropview_reopen_db
000079  } -tclquery {
000080    list_all_views
000081  } {
000082    1   "DROP VIEW v1"                  {main.v1 main.v2 aux.v1 aux.v2 aux.v3}
000083    2   "DROP VIEW v2"                  {main.v1 temp.v1 aux.v1 aux.v2 aux.v3}
000084    3   "DROP VIEW main.v1"             {main.v2 temp.v1 aux.v1 aux.v2 aux.v3}
000085    4   "DROP VIEW main.v2"             {main.v1 temp.v1 aux.v1 aux.v2 aux.v3}
000086    5   "DROP VIEW IF EXISTS v1"        {main.v1 main.v2 aux.v1 aux.v2 aux.v3}
000087    6   "DROP VIEW IF EXISTS v2"        {main.v1 temp.v1 aux.v1 aux.v2 aux.v3}
000088    7   "DROP VIEW IF EXISTS main.v1"   {main.v2 temp.v1 aux.v1 aux.v2 aux.v3}
000089    8   "DROP VIEW IF EXISTS main.v2"   {main.v1 temp.v1 aux.v1 aux.v2 aux.v3}
000090  }
000091  
000092  # EVIDENCE-OF: R-27002-52307 The DROP VIEW statement removes a view
000093  # created by the CREATE VIEW statement.
000094  #
000095  dropview_reopen_db
000096  do_execsql_test 2.1 {
000097    CREATE VIEW "new view" AS SELECT * FROM t1 AS x, t1 AS y;
000098    SELECT * FROM "new view";
000099  } {{a main} {b main} {a main} {b main}}
000100  do_execsql_test 2.2 {;
000101    SELECT * FROM sqlite_master WHERE name = 'new view';
000102  } {
000103    view {new view} {new view} 0 
000104    {CREATE VIEW "new view" AS SELECT * FROM t1 AS x, t1 AS y}
000105  }
000106  do_execsql_test 2.3 {
000107    DROP VIEW "new view";
000108    SELECT * FROM sqlite_master WHERE name = 'new view';
000109  } {}
000110  do_catchsql_test 2.4 {
000111    SELECT * FROM "new view"
000112  } {1 {no such table: new view}}
000113  
000114  # EVIDENCE-OF: R-00359-41639 The view definition is removed from the
000115  # database schema, but no actual data in the underlying base tables is
000116  # modified.
000117  #
000118  #     For each view in the database, check that it can be queried. Then drop
000119  #     it. Check that it can no longer be queried and is no longer listed
000120  #     in any schema table. Then check that the contents of the db tables have 
000121  #     not changed
000122  #
000123  set databasedata [list_all_data]
000124  
000125  do_execsql_test  3.1.0 { SELECT * FROM temp.v1 } {{a temp} {b temp}}
000126  do_execsql_test  3.1.1 { DROP VIEW temp.v1 } {}
000127  do_catchsql_test 3.1.2 { SELECT * FROM temp.v1 } {1 {no such table: temp.v1}}
000128  do_test          3.1.3 { list_all_views } {main.v1 main.v2 aux.v1 aux.v2 aux.v3}
000129  do_test          3.1.4 { list_all_data  } $databasedata
000130  
000131  do_execsql_test  3.2.0 { SELECT * FROM v1 } {{a main} {b main}}
000132  do_execsql_test  3.2.1 { DROP VIEW v1 } {}
000133  do_catchsql_test 3.2.2 { SELECT * FROM main.v1 } {1 {no such table: main.v1}}
000134  do_test          3.2.3 { list_all_views } {main.v2 aux.v1 aux.v2 aux.v3}
000135  do_test          3.2.4 { list_all_data  } $databasedata
000136  
000137  do_execsql_test  3.3.0 { SELECT * FROM v2 } {{a main} {b main}}
000138  do_execsql_test  3.3.1 { DROP VIEW v2 } {}
000139  do_catchsql_test 3.3.2 { SELECT * FROM main.v2 } {1 {no such table: main.v2}}
000140  do_test          3.3.3 { list_all_views } {aux.v1 aux.v2 aux.v3}
000141  do_test          3.3.4 { list_all_data  } $databasedata
000142  
000143  do_execsql_test  3.4.0 { SELECT * FROM v1 } {{a aux} {b aux}}
000144  do_execsql_test  3.4.1 { DROP VIEW v1 } {}
000145  do_catchsql_test 3.4.2 { SELECT * FROM v1 } {1 {no such table: v1}}
000146  do_test          3.4.3 { list_all_views } {aux.v2 aux.v3}
000147  do_test          3.4.4 { list_all_data  } $databasedata
000148  
000149  do_execsql_test  3.4.0 { SELECT * FROM aux.v2 } {{a aux} {b aux}}
000150  do_execsql_test  3.4.1 { DROP VIEW aux.v2 } {}
000151  do_catchsql_test 3.4.2 { SELECT * FROM aux.v2 } {1 {no such table: aux.v2}}
000152  do_test          3.4.3 { list_all_views } {aux.v3}
000153  do_test          3.4.4 { list_all_data  } $databasedata
000154  
000155  do_execsql_test  3.5.0 { SELECT * FROM v3 } {{a aux} {b aux}}
000156  do_execsql_test  3.5.1 { DROP VIEW v3 } {}
000157  do_catchsql_test 3.5.2 { SELECT * FROM v3 } {1 {no such table: v3}}
000158  do_test          3.5.3 { list_all_views } {}
000159  do_test          3.5.4 { list_all_data  } $databasedata
000160  
000161  # EVIDENCE-OF: R-25558-37487 If the specified view cannot be found and
000162  # the IF EXISTS clause is not present, it is an error.
000163  #
000164  do_dropview_tests 4 -repair {
000165    dropview_reopen_db 
000166  } -errorformat {
000167    no such view: %s
000168  } {
000169    1   "DROP VIEW xx"                  xx
000170    2   "DROP VIEW main.xx"             main.xx
000171    3   "DROP VIEW temp.v2"             temp.v2
000172  }
000173  
000174  # EVIDENCE-OF: R-07490-32536 If the specified view cannot be found and
000175  # an IF EXISTS clause is present in the DROP VIEW statement, then the
000176  # statement is a no-op.
000177  #
000178  do_dropview_tests 5 -repair {
000179    dropview_reopen_db
000180  } -tclquery {
000181    list_all_views
000182    expr {[list_all_views] == "main.v1 main.v2 temp.v1 aux.v1 aux.v2 aux.v3"}
000183  } {
000184    1    "DROP VIEW IF EXISTS xx"       1
000185    2    "DROP VIEW IF EXISTS main.xx"  1
000186    3    "DROP VIEW IF EXISTS temp.v2"  1
000187  }
000188  
000189  
000190  
000191  
000192  finish_test