gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/laststmtchanges.test (about)

     1  #
     2  # The author disclaims copyright to this source code.  In place of
     3  # a legal notice, here is a blessing:
     4  #
     5  #    May you do good and not evil.
     6  #    May you find forgiveness for yourself and forgive others.
     7  #    May you share freely, never taking more than you give.
     8  #
     9  #***********************************************************************
    10  #
    11  # Tests to make sure that values returned by changes() and total_changes()
    12  # are updated properly, especially inside triggers
    13  #
    14  # Note 1: changes() remains constant within a statement and only updates
    15  #         once the statement is finished (triggers count as part of
    16  #         statement).
    17  # Note 2: changes() is changed within the context of a trigger much like 
    18  #         last_insert_rowid() (see lastinsert.test), but is restored once
    19  #         the trigger exits.
    20  # Note 3: changes() is not changed by a change to a view (since everything
    21  #         is done within instead of trigger context).
    22  #
    23  # $Id: laststmtchanges.test,v 1.7 2008/10/27 13:59:34 danielk1977 Exp $
    24  
    25  set testdir [file dirname $argv0]
    26  source $testdir/tester.tcl
    27  
    28  # ----------------------------------------------------------------------------
    29  # 1.x - basic tests (no triggers)
    30  
    31  # changes() set properly after insert
    32  do_test laststmtchanges-1.1 {
    33      catchsql {
    34          create table t0 (x);
    35          insert into t0 values (1);
    36          insert into t0 values (1);
    37          insert into t0 values (2);
    38          insert into t0 values (2);
    39          insert into t0 values (1);
    40          insert into t0 values (1);
    41          insert into t0 values (1);
    42          insert into t0 values (2);
    43          select changes(), total_changes();
    44      }
    45  } {0 {1 8}}
    46  
    47  # changes() set properly after update
    48  do_test laststmtchanges-1.2 {
    49      catchsql {
    50          update t0 set x=3 where x=1;
    51          select changes(), total_changes();
    52      }
    53  } {0 {5 13}}
    54  
    55  # There was some goofy change-counting logic in sqlite3_exec() that
    56  # appears to have been left over from SQLite version 2.  This test
    57  # makes sure it has been removed.
    58  #
    59  do_test laststmtchanges-1.2.1 {
    60      db cache flush
    61      sqlite3_exec_printf db {update t0 set x=4 where x=3; select 1;} {}
    62      execsql {select changes()}
    63  } {5}
    64  
    65  # changes() unchanged within an update statement
    66  do_test laststmtchanges-1.3 {
    67      execsql {update t0 set x=3 where x=4}
    68      catchsql {
    69          update t0 set x=x+changes() where x=3;
    70          select count() from t0 where x=8;
    71      }
    72  } {0 5}
    73  
    74  # changes() set properly after update on table where no rows changed
    75  do_test laststmtchanges-1.4 {
    76      catchsql {
    77          update t0 set x=77 where x=88;
    78          select changes();
    79      }
    80  } {0 0}
    81  
    82  # changes() set properly after delete from table
    83  do_test laststmtchanges-1.5 {
    84      catchsql {
    85          delete from t0 where x=2;
    86          select changes();
    87      }
    88  } {0 3}
    89  
    90  # All remaining tests involve triggers.  Skip them if triggers are not
    91  # supported in this build.
    92  #
    93  ifcapable {!trigger} {
    94    finish_test
    95    return
    96  }
    97  
    98  
    99  # ----------------------------------------------------------------------------
   100  # 2.x - tests with after insert trigger
   101  
   102  # changes() changed properly after insert into table containing after trigger
   103  do_test laststmtchanges-2.1 {
   104      set ::tc [db total_changes]
   105      catchsql {
   106          create table t1 (k integer primary key);
   107          create table t2 (k integer primary key, v1, v2);
   108          create trigger r1 after insert on t1 for each row begin
   109              insert into t2 values (NULL, changes(), NULL);
   110              update t0 set x=x;
   111              update t2 set v2=changes();
   112          end;
   113          insert into t1 values (77);
   114          select changes();
   115      }
   116  } {0 1}
   117  
   118  # changes() unchanged upon entry into after insert trigger
   119  do_test laststmtchanges-2.2 {
   120      catchsql {
   121          select v1 from t2;
   122      }
   123  } {0 3}
   124  
   125  # changes() changed properly by update within context of after insert trigger
   126  do_test laststmtchanges-2.3 {
   127      catchsql {
   128          select v2 from t2;
   129      }
   130  } {0 5}
   131  
   132  # Total changes caused by firing the trigger above:
   133  #
   134  #   1 from "insert into t1 values(77)" + 
   135  #   1 from "insert into t2 values (NULL, changes(), NULL);" +
   136  #   5 from "update t0 set x=x;" +
   137  #   1 from "update t2 set v2=changes();"
   138  #
   139  do_test laststmtchanges-2.4 {
   140    expr [db total_changes] - $::tc
   141  } {8}
   142  
   143  # ----------------------------------------------------------------------------
   144  # 3.x - tests with after update trigger
   145  
   146  # changes() changed properly after update into table containing after trigger
   147  do_test laststmtchanges-3.1 {
   148      catchsql {
   149          drop trigger r1;
   150          delete from t2; delete from t2;
   151          create trigger r1 after update on t1 for each row begin
   152              insert into t2 values (NULL, changes(), NULL);
   153              delete from t0 where oid=1 or oid=2;
   154              update t2 set v2=changes();
   155          end;
   156          update t1 set k=k;
   157          select changes();
   158      }
   159  } {0 1}
   160  
   161  # changes() unchanged upon entry into after update trigger
   162  do_test laststmtchanges-3.2 {
   163      catchsql {
   164          select v1 from t2;
   165      }
   166  } {0 0}
   167  
   168  # changes() changed properly by delete within context of after update trigger
   169  do_test laststmtchanges-3.3 {
   170      catchsql {
   171          select v2 from t2;
   172      }
   173  } {0 2}
   174  
   175  # ----------------------------------------------------------------------------
   176  # 4.x - tests with before delete trigger
   177  
   178  # changes() changed properly on delete from table containing before trigger
   179  do_test laststmtchanges-4.1 {
   180      catchsql {
   181          drop trigger r1;
   182          delete from t2; delete from t2;
   183          create trigger r1 before delete on t1 for each row begin
   184              insert into t2 values (NULL, changes(), NULL);
   185              insert into t0 values (5);
   186              update t2 set v2=changes();
   187          end;
   188          delete from t1;
   189          select changes();
   190      }
   191  } {0 1}
   192  
   193  # changes() unchanged upon entry into before delete trigger
   194  do_test laststmtchanges-4.2 {
   195      catchsql {
   196          select v1 from t2;
   197      }
   198  } {0 0}
   199  
   200  # changes() changed properly by insert within context of before delete trigger
   201  do_test laststmtchanges-4.3 {
   202      catchsql {
   203          select v2 from t2;
   204      }
   205  } {0 1}
   206  
   207  # ----------------------------------------------------------------------------
   208  # 5.x - complex tests with temporary tables and nested instead of triggers
   209  # These tests cannot run if the library does not have view support enabled.
   210  
   211  ifcapable view&&tempdb {
   212  
   213  do_test laststmtchanges-5.1 {
   214      catchsql {
   215          drop table t0; drop table t1; drop table t2;
   216          create temp table t0(x);
   217          create temp table t1 (k integer primary key);
   218          create temp table t2 (k integer primary key);
   219          create temp view v1 as select * from t1;
   220          create temp view v2 as select * from t2;
   221          create temp table n1 (k integer primary key, n);
   222          create temp table n2 (k integer primary key, n);
   223          insert into t0 values (1);
   224          insert into t0 values (2);
   225          insert into t0 values (1);
   226          insert into t0 values (1);
   227          insert into t0 values (1);
   228          insert into t0 values (2);
   229          insert into t0 values (2);
   230          insert into t0 values (1);
   231          create temp trigger r1 instead of insert on v1 for each row begin
   232              insert into n1 values (NULL, changes());
   233              update t0 set x=x*10 where x=1;
   234              insert into n1 values (NULL, changes());
   235              insert into t1 values (NEW.k);
   236              insert into n1 values (NULL, changes());
   237              update t0 set x=x*10 where x=0;
   238              insert into v2 values (100+NEW.k);
   239              insert into n1 values (NULL, changes());
   240          end;
   241          create temp trigger r2 instead of insert on v2 for each row begin
   242              insert into n2 values (NULL, changes());
   243              insert into t2 values (1000+NEW.k);
   244              insert into n2 values (NULL, changes());
   245              update t0 set x=x*100 where x=0;
   246              insert into n2 values (NULL, changes());
   247              delete from t0 where x=2;
   248              insert into n2 values (NULL, changes());
   249          end;
   250          insert into t1 values (77);
   251          select changes();
   252      }
   253  } {0 1}
   254  
   255  do_test laststmtchanges-5.2 {
   256      catchsql {
   257          delete from t1 where k=88;
   258          select changes();
   259      }
   260  } {0 0}
   261  
   262  do_test laststmtchanges-5.3 {
   263      catchsql {
   264          insert into v1 values (5);
   265          select changes();
   266      }
   267  } {0 0}
   268  
   269  do_test laststmtchanges-5.4 {
   270      catchsql {
   271          select n from n1;
   272      }
   273  } {0 {0 5 1 0}}
   274  
   275  do_test laststmtchanges-5.5 {
   276      catchsql {
   277          select n from n2;
   278      }
   279  } {0 {0 1 0 3}}
   280  
   281  } ;# ifcapable view
   282  
   283  
   284  # ----------------------------------------------------------------------------
   285  # 6.x - Test "DELETE FROM <table>" in the absence of triggers
   286  #
   287  do_test laststmtchanges-6.1 {
   288    execsql {
   289      CREATE TABLE t3(a, b, c);
   290      INSERT INTO t3 VALUES(1, 2, 3);
   291      INSERT INTO t3 VALUES(4, 5, 6);
   292    }
   293  } {}
   294  do_test laststmtchanges-6.2 {
   295    execsql {
   296      BEGIN;
   297      DELETE FROM t3;
   298      SELECT changes();
   299    }
   300  } {2}
   301  do_test laststmtchanges-6.3 {
   302    execsql {
   303      ROLLBACK;
   304      BEGIN;
   305      DELETE FROM t3 WHERE a IS NOT NULL;
   306      SELECT changes();
   307    }
   308  } {2}
   309  do_test laststmtchanges-6.4 {
   310    execsql {
   311      ROLLBACK;
   312      CREATE INDEX t3_i1 ON t3(a);
   313      BEGIN;
   314      DELETE FROM t3;
   315      SELECT changes();
   316    }
   317  } {2}
   318  do_test laststmtchanges-6.5 {
   319    execsql { ROLLBACK }
   320    set nTotalChange [execsql {SELECT total_changes()}]
   321    expr 0
   322  } {0}
   323  do_test laststmtchanges-6.6 {
   324    execsql {
   325      SELECT total_changes();
   326      DELETE FROM t3;
   327      SELECT total_changes();
   328    }
   329  } [list $nTotalChange [expr $nTotalChange+2]]
   330  
   331  finish_test