SQLite

Check-in [914d6e6549]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add tests to make sure statement journals are only opened when necessary. (CVS 2500)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 914d6e6549446a6ddf25e5da57d2fe9446750625
User & Date: drh 2005-06-07 02:12:30.000
Context
2005-06-07
07:58
Add "#ifndef OMIT_DISKIO" condition around sqlite3_opentemp_count variable in test interface code. (CVS 2501) (check-in: f2ce662e81 user: danielk1977 tags: trunk)
02:12
Add tests to make sure statement journals are only opened when necessary. (CVS 2500) (check-in: 914d6e6549 user: drh tags: trunk)
01:43
Do not open a statement journal unless absolutely necessary. (CVS 2499) (check-in: 989573a53b user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/pager.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.206 2005/05/22 20:30:39 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.207 2005/06/07 02:12:30 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
1535
1536
1537
1538
1539
1540
1541







1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552

1553
1554
1555
1556
1557
1558
1559
  pPager->noSync =  level==1 || pPager->tempFile;
  pPager->fullSync = level==3 && !pPager->tempFile;
  if( pPager->noSync ) pPager->needSync = 0;
}
#endif

/*







** Open a temporary file.  Write the name of the file into zName
** (zName must be at least SQLITE_TEMPNAME_SIZE bytes long.)  Write
** the file descriptor into *fd.  Return SQLITE_OK on success or some
** other error code if we fail.
**
** The OS will automatically delete the temporary file when it is
** closed.
*/
static int sqlite3pager_opentemp(char *zFile, OsFile *fd){
  int cnt = 8;
  int rc;

  do{
    cnt--;
    sqlite3OsTempFileName(zFile);
    rc = sqlite3OsOpenExclusive(zFile, fd, 1);
  }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
  return rc;
}







>
>
>
>
>
>
>
|
|









>







1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
  pPager->noSync =  level==1 || pPager->tempFile;
  pPager->fullSync = level==3 && !pPager->tempFile;
  if( pPager->noSync ) pPager->needSync = 0;
}
#endif

/*
** The following global variable is incremented whenever the library
** attempts to open a temporary file.  This information is used for
** testing and analysis only.  
*/
int sqlite3_opentemp_count = 0;

/*
** Open a temporary file.  Write the name of the file into zFile
** (zFile must be at least SQLITE_TEMPNAME_SIZE bytes long.)  Write
** the file descriptor into *fd.  Return SQLITE_OK on success or some
** other error code if we fail.
**
** The OS will automatically delete the temporary file when it is
** closed.
*/
static int sqlite3pager_opentemp(char *zFile, OsFile *fd){
  int cnt = 8;
  int rc;
  sqlite3_opentemp_count++;  /* Used for testing and analysis only */
  do{
    cnt--;
    sqlite3OsTempFileName(zFile);
    rc = sqlite3OsOpenExclusive(zFile, fd, 1);
  }while( cnt>0 && rc!=SQLITE_OK && rc!=SQLITE_NOMEM );
  return rc;
}
Changes to src/test1.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.141 2005/06/06 17:54:56 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>








|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.142 2005/06/07 02:12:30 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

3070
3071
3072
3073
3074
3075
3076

3077
3078
3079
3080
3081
3082
3083
     { "sqlite3_test_errstr",     test_errstr, 0             },
     { "tcl_variable_type",       tcl_variable_type, 0       },
  };
  static int bitmask_size = sizeof(Bitmask)*8;
  int i;
  extern int sqlite3_os_trace;
  extern int sqlite3_sync_count, sqlite3_fullsync_count;

 

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 







>







3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
     { "sqlite3_test_errstr",     test_errstr, 0             },
     { "tcl_variable_type",       tcl_variable_type, 0       },
  };
  static int bitmask_size = sizeof(Bitmask)*8;
  int i;
  extern int sqlite3_os_trace;
  extern int sqlite3_sync_count, sqlite3_fullsync_count;
  extern int sqlite3_opentemp_count;
 

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 
3091
3092
3093
3094
3095
3096
3097


3098
3099
3100
3101
3102
3103
3104
      (char*)&sqlite3_interrupt_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_open_file_count", 
      (char*)&sqlite3_open_file_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_current_time", 
      (char*)&sqlite3_current_time, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_os_trace",
      (char*)&sqlite3_os_trace, TCL_LINK_INT);


  Tcl_LinkVar(interp, "sqlite_static_bind_value",
      (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
  Tcl_LinkVar(interp, "sqlite_temp_directory",
      (char*)&sqlite3_temp_directory, TCL_LINK_STRING);
  Tcl_LinkVar(interp, "bitmask_size",
      (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
#if OS_UNIX







>
>







3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
      (char*)&sqlite3_interrupt_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_open_file_count", 
      (char*)&sqlite3_open_file_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_current_time", 
      (char*)&sqlite3_current_time, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_os_trace",
      (char*)&sqlite3_os_trace, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_opentemp_count",
      (char*)&sqlite3_opentemp_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_static_bind_value",
      (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
  Tcl_LinkVar(interp, "sqlite_temp_directory",
      (char*)&sqlite3_temp_directory, TCL_LINK_STRING);
  Tcl_LinkVar(interp, "bitmask_size",
      (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY);
#if OS_UNIX
Changes to test/conflict.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the conflict resolution extension
# to SQLite.
#
# $Id: conflict.test,v 1.23 2005/03/20 19:10:13 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create tables for the first group of tests.
#
do_test conflict-1.0 {
  execsql {
    CREATE TABLE t1(a, b, c, UNIQUE(a,b));
    CREATE TABLE t2(x);
    SELECT c FROM t1 ORDER BY c;
  }
} {}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test
#   conf   The conflict resolution algorithm on the BEGIN statement
#   cmd    An INSERT or REPLACE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "c" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t2

#
foreach {i conf cmd t0 t1 t2} {
  1 {}       INSERT                  1 {}  1
  2 {}       {INSERT OR IGNORE}      0 3   1
  3 {}       {INSERT OR REPLACE}     0 4   1
  4 {}       REPLACE                 0 4   1
  5 {}       {INSERT OR FAIL}        1 {}  1
  6 {}       {INSERT OR ABORT}       1 {}  1
  7 {}       {INSERT OR ROLLBACK}    1 {}  {}
} {
  if { $conf=={} } {

  do_test conflict-1.$i {
    if {$conf!=""} {set conf "ON CONFLICT $conf"}
    set r0 [catch {execsql [subst {
      DELETE FROM t1;
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN $conf;
      INSERT INTO t2 VALUES(1); 
      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]

    list $r0 $r1 $r2
  } [list $t0 $t1 $t2]

  }
}

# Create tables for the first group of tests.
#
do_test conflict-2.0 {
  execsql {
    DROP TABLE t1;
    DROP TABLE t2;
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(a,b));
    CREATE TABLE t2(x);
    SELECT c FROM t1 ORDER BY c;
  }
} {}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test
#   conf   The conflict resolution algorithm on the BEGIN statement
#   cmd    An INSERT or REPLACE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "c" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t2
#
foreach {i conf cmd t0 t1 t2} {
  1 {}       INSERT                  1 {}  1
  2 {}       {INSERT OR IGNORE}      0 3   1
  3 {}       {INSERT OR REPLACE}     0 4   1
  4 {}       REPLACE                 0 4   1
  5 {}       {INSERT OR FAIL}        1 {}  1
  6 {}       {INSERT OR ABORT}       1 {}  1
  7 {}       {INSERT OR ROLLBACK}    1 {}  {}
} {
  do_test conflict-2.$i {
    if {$conf!=""} {set conf "ON CONFLICT $conf"}
    set r0 [catch {execsql [subst {
      DELETE FROM t1;
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN $conf;
      INSERT INTO t2 VALUES(1); 
      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2







|

















<




>

|
|
|
|
|
|
|
|

<
<

|




|






>
|
|
<
<

















<





|
|
|
|
|
|
|
|


<




|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
104
105
106
107
108
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the conflict resolution extension
# to SQLite.
#
# $Id: conflict.test,v 1.24 2005/06/07 02:12:30 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create tables for the first group of tests.
#
do_test conflict-1.0 {
  execsql {
    CREATE TABLE t1(a, b, c, UNIQUE(a,b));
    CREATE TABLE t2(x);
    SELECT c FROM t1 ORDER BY c;
  }
} {}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test

#   cmd    An INSERT or REPLACE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "c" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t2
#   t3     Number of temporary files created by this test
#
foreach {i cmd t0 t1 t2 t3} {
  1 INSERT                  1 {}  1  0
  2 {INSERT OR IGNORE}      0 3   1  0
  3 {INSERT OR REPLACE}     0 4   1  0
  4 REPLACE                 0 4   1  0
  5 {INSERT OR FAIL}        1 {}  1  0
  6 {INSERT OR ABORT}       1 {}  1  0
  7 {INSERT OR ROLLBACK}    1 {}  {} 0
} {


  do_test conflict-1.$i {
    set ::sqlite_opentemp_count 0
    set r0 [catch {execsql [subst {
      DELETE FROM t1;
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN;
      INSERT INTO t2 VALUES(1); 
      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    set r3 $::sqlite_opentemp_count
    list $r0 $r1 $r2 $r3
  } [list $t0 $t1 $t2 $t3]


}

# Create tables for the first group of tests.
#
do_test conflict-2.0 {
  execsql {
    DROP TABLE t1;
    DROP TABLE t2;
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(a,b));
    CREATE TABLE t2(x);
    SELECT c FROM t1 ORDER BY c;
  }
} {}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test

#   cmd    An INSERT or REPLACE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "c" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t2
#
foreach {i cmd t0 t1 t2} {
  1 INSERT                  1 {}  1
  2 {INSERT OR IGNORE}      0 3   1
  3 {INSERT OR REPLACE}     0 4   1
  4 REPLACE                 0 4   1
  5 {INSERT OR FAIL}        1 {}  1
  6 {INSERT OR ABORT}       1 {}  1
  7 {INSERT OR ROLLBACK}    1 {}  {}
} {
  do_test conflict-2.$i {

    set r0 [catch {execsql [subst {
      DELETE FROM t1;
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN;
      INSERT INTO t2 VALUES(1); 
      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    SELECT c FROM t1 ORDER BY c;
  }
} {}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test
#   conf   The conflict resolution algorithm on the BEGIN statement
#   cmd    An INSERT or REPLACE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "c" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t2
#
foreach {i conf cmd t0 t1 t2} {
  1 {}       INSERT                  1 {}  1
  2 {}       {INSERT OR IGNORE}      0 3   1
  3 {}       {INSERT OR REPLACE}     0 4   1
  4 {}       REPLACE                 0 4   1
  5 {}       {INSERT OR FAIL}        1 {}  1
  6 {}       {INSERT OR ABORT}       1 {}  1
  7 {}       {INSERT OR ROLLBACK}    1 {}  {}
} {
  do_test conflict-3.$i {
    if {$conf!=""} {set conf "ON CONFLICT $conf"}
    set r0 [catch {execsql [subst {
      DELETE FROM t1;
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN $conf;
      INSERT INTO t2 VALUES(1); 
      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2







<





|
|
|
|
|
|
|
|


<




|







120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
149
150
151
152
153
    SELECT c FROM t1 ORDER BY c;
  }
} {}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test

#   cmd    An INSERT or REPLACE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "c" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t2
#
foreach {i cmd t0 t1 t2} {
  1 INSERT                  1 {}  1
  2 {INSERT OR IGNORE}      0 3   1
  3 {INSERT OR REPLACE}     0 4   1
  4 REPLACE                 0 4   1
  5 {INSERT OR FAIL}        1 {}  1
  6 {INSERT OR ABORT}       1 {}  1
  7 {INSERT OR ROLLBACK}    1 {}  {}
} {
  do_test conflict-3.$i {

    set r0 [catch {execsql [subst {
      DELETE FROM t1;
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN;
      INSERT INTO t2 VALUES(1); 
      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  }
} {}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test
#   conf1  The conflict resolution algorithm on the UNIQUE constraint
#   conf2  The conflict resolution algorithm on the BEGIN statement
#   cmd    An INSERT or REPLACE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "c" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t2
#
foreach {i conf1 conf2 cmd t0 t1 t2} {
  1 {}       {}       INSERT                  1 {}  1
  2 REPLACE  {}       INSERT                  0 4   1
  3 IGNORE   {}       INSERT                  0 3   1
  4 FAIL     {}       INSERT                  1 {}  1
  5 ABORT    {}       INSERT                  1 {}  1
  6 ROLLBACK {}       INSERT                  1 {}  {}
  7 REPLACE  {}       {INSERT OR IGNORE}      0 3   1
  8 IGNORE   {}       {INSERT OR REPLACE}     0 4   1
  9 FAIL     {}       {INSERT OR IGNORE}      0 3   1
 10 ABORT    {}       {INSERT OR REPLACE}     0 4   1
 11 ROLLBACK {}       {INSERT OR IGNORE }     0 3   1
} {
  do_test conflict-4.$i {
    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
    if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
    set r0 [catch {execsql [subst {
      DROP TABLE t1;
      CREATE TABLE t1(a,b,c,UNIQUE(a,b) $conf1);
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN $conf2;
      INSERT INTO t2 VALUES(1); 
      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2







<





|
|
|
|
|
|
|
|
|
|
|
|



<





|







162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
200
201
  }
} {}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test
#   conf1  The conflict resolution algorithm on the UNIQUE constraint

#   cmd    An INSERT or REPLACE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "c" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t2
#
foreach {i conf1 cmd t0 t1 t2} {
  1 {}       INSERT                  1 {}  1
  2 REPLACE  INSERT                  0 4   1
  3 IGNORE   INSERT                  0 3   1
  4 FAIL     INSERT                  1 {}  1
  5 ABORT    INSERT                  1 {}  1
  6 ROLLBACK INSERT                  1 {}  {}
  7 REPLACE  {INSERT OR IGNORE}      0 3   1
  8 IGNORE   {INSERT OR REPLACE}     0 4   1
  9 FAIL     {INSERT OR IGNORE}      0 3   1
 10 ABORT    {INSERT OR REPLACE}     0 4   1
 11 ROLLBACK {INSERT OR IGNORE }     0 3   1
} {
  do_test conflict-4.$i {
    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}

    set r0 [catch {execsql [subst {
      DROP TABLE t1;
      CREATE TABLE t1(a,b,c,UNIQUE(a,b) $conf1);
      DELETE FROM t2;
      INSERT INTO t1 VALUES(1,2,3);
      BEGIN;
      INSERT INTO t2 VALUES(1); 
      $cmd INTO t1 VALUES(1,2,4);
    }]} r1]
    catch {execsql {COMMIT}}
    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  }
} {}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test
#   conf1  The conflict resolution algorithm on the NOT NULL constraint
#   conf2  The conflict resolution algorithm on the BEGIN statement
#   cmd    An INSERT or REPLACE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "c" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t2
#
foreach {i conf1 conf2 cmd t0 t1 t2} {
  1 {}       {}       INSERT                  1 {}  1
  2 REPLACE  {}       INSERT                  0 5   1
  3 IGNORE   {}       INSERT                  0 {}  1
  4 FAIL     {}       INSERT                  1 {}  1
  5 ABORT    {}       INSERT                  1 {}  1
  6 ROLLBACK {}       INSERT                  1 {}  {}
  7 REPLACE  {}       {INSERT OR IGNORE}      0 {}  1
  8 IGNORE   {}       {INSERT OR REPLACE}     0 5   1
  9 FAIL     {}       {INSERT OR IGNORE}      0 {}  1
 10 ABORT    {}       {INSERT OR REPLACE}     0 5   1
 11 ROLLBACK {}       {INSERT OR IGNORE}      0 {}  1
 12 {}       {}       {INSERT OR IGNORE}      0 {}  1
 13 {}       {}       {INSERT OR REPLACE}     0 5   1
 14 {}       {}       {INSERT OR FAIL}        1 {}  1
 15 {}       {}       {INSERT OR ABORT}       1 {}  1
 16 {}       {}       {INSERT OR ROLLBACK}    1 {}  {}
} {
  if {$t0} {set t1 {t1.c may not be NULL}}
  do_test conflict-5.$i {
    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
    if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
    set r0 [catch {execsql [subst {
      DROP TABLE t1;
      CREATE TABLE t1(a,b,c NOT NULL $conf1 DEFAULT 5);
      DELETE FROM t2;
      BEGIN $conf2;
      INSERT INTO t2 VALUES(1); 
      $cmd INTO t1 VALUES(1,2,NULL);
    }]} r1]
    catch {execsql {COMMIT}}
    if {!$r0} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2







<





|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|




<




|







210
211
212
213
214
215
216

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

243
244
245
246
247
248
249
250
251
252
253
254
  }
} {}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test
#   conf1  The conflict resolution algorithm on the NOT NULL constraint

#   cmd    An INSERT or REPLACE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "c" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t2
#
foreach {i conf1 cmd t0 t1 t2} {
  1 {}       INSERT                  1 {}  1
  2 REPLACE  INSERT                  0 5   1
  3 IGNORE   INSERT                  0 {}  1
  4 FAIL     INSERT                  1 {}  1
  5 ABORT    INSERT                  1 {}  1
  6 ROLLBACK INSERT                  1 {}  {}
  7 REPLACE  {INSERT OR IGNORE}      0 {}  1
  8 IGNORE   {INSERT OR REPLACE}     0 5   1
  9 FAIL     {INSERT OR IGNORE}      0 {}  1
 10 ABORT    {INSERT OR REPLACE}     0 5   1
 11 ROLLBACK {INSERT OR IGNORE}      0 {}  1
 12 {}       {INSERT OR IGNORE}      0 {}  1
 13 {}       {INSERT OR REPLACE}     0 5   1
 14 {}       {INSERT OR FAIL}        1 {}  1
 15 {}       {INSERT OR ABORT}       1 {}  1
 16 {}       {INSERT OR ROLLBACK}    1 {}  {}
} {
  if {$t0} {set t1 {t1.c may not be NULL}}
  do_test conflict-5.$i {
    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}

    set r0 [catch {execsql [subst {
      DROP TABLE t1;
      CREATE TABLE t1(a,b,c NOT NULL $conf1 DEFAULT 5);
      DELETE FROM t2;
      BEGIN;
      INSERT INTO t2 VALUES(1); 
      $cmd INTO t1 VALUES(1,2,NULL);
    }]} r1]
    catch {execsql {COMMIT}}
    if {!$r0} {set r1 [execsql {SELECT c FROM t1}]}
    set r2 [execsql {SELECT x FROM t2}]
    list $r0 $r1 $r2
280
281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312


313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
  }
} {1 2 1 4}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test
#   conf1  The conflict resolution algorithm on the UNIQUE constraint
#   conf2  The conflict resolution algorithm on the BEGIN statement
#   cmd    An UPDATE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "b" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t3

#
foreach {i conf1 conf2 cmd t0 t1 t2} {
  1 {}       {}       UPDATE                  1 {6 7 8 9}  1
  2 REPLACE  {}       UPDATE                  0 {7 6 9}    1
  3 IGNORE   {}       UPDATE                  0 {6 7 3 9}  1
  4 FAIL     {}       UPDATE                  1 {6 7 3 4}  1
  5 ABORT    {}       UPDATE                  1 {1 2 3 4}  1
  6 ROLLBACK {}       UPDATE                  1 {1 2 3 4}  0
  7 REPLACE  {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
  8 IGNORE   {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
  9 FAIL     {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
 10 ABORT    {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
 11 ROLLBACK {}       {UPDATE OR IGNORE}      0 {6 7 3 9}   1
 12 {}       {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
 13 {}       {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
 14 {}       {}       {UPDATE OR FAIL}        1 {6 7 3 4}  1
 15 {}       {}       {UPDATE OR ABORT}       1 {1 2 3 4}  1
 16 {}       {}       {UPDATE OR ROLLBACK}    1 {1 2 3 4}  0
} {
  if {$t0} {set t1 {column a is not unique}}
  do_test conflict-6.$i {


    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
    if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
    set r0 [catch {execsql [subst {
      DROP TABLE t1;
      CREATE TABLE t1(a,b,c, UNIQUE(a) $conf1);
      INSERT INTO t1 SELECT * FROM t2;
      UPDATE t3 SET x=0;
      BEGIN $conf2;
      $cmd t3 SET x=1;
      $cmd t1 SET b=b*2;
      $cmd t1 SET a=c+5;
    }]} r1]
    catch {execsql {COMMIT}}
    if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
    set r2 [execsql {SELECT x FROM t3}]
    list $r0 $r1 $r2
  } [list $t0 $t1 $t2]
}

# Test to make sure a lot of IGNOREs don't cause a stack overflow
#
do_test conflict-7.1 {
  execsql {
    DROP TABLE t1;







<




>

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|



>
>

|





|







|
|







269
270
271
272
273
274
275

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
  }
} {1 2 1 4}

# Six columns of configuration data as follows:
#
#   i      The reference number of the test
#   conf1  The conflict resolution algorithm on the UNIQUE constraint

#   cmd    An UPDATE command to execute against table t1
#   t0     True if there is an error from $cmd
#   t1     Content of "b" column of t1 assuming no error in $cmd
#   t2     Content of "x" column of t3
#   t3     Number of temporary files created
#
foreach {i conf1 cmd t0 t1 t2 t3} {
  1 {}       UPDATE                  1 {6 7 8 9}  1 1
  2 REPLACE  UPDATE                  0 {7 6 9}    1 0
  3 IGNORE   UPDATE                  0 {6 7 3 9}  1 0
  4 FAIL     UPDATE                  1 {6 7 3 4}  1 0
  5 ABORT    UPDATE                  1 {1 2 3 4}  1 1
  6 ROLLBACK UPDATE                  1 {1 2 3 4}  0 0
  7 REPLACE  {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0
  8 IGNORE   {UPDATE OR REPLACE}     0 {7 6 9}    1 0
  9 FAIL     {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0
 10 ABORT    {UPDATE OR REPLACE}     0 {7 6 9}    1 0
 11 ROLLBACK {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0
 12 {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0
 13 {}       {UPDATE OR REPLACE}     0 {7 6 9}    1 0
 14 {}       {UPDATE OR FAIL}        1 {6 7 3 4}  1 0
 15 {}       {UPDATE OR ABORT}       1 {1 2 3 4}  1 1
 16 {}       {UPDATE OR ROLLBACK}    1 {1 2 3 4}  0 0
} {
  if {$t0} {set t1 {column a is not unique}}
  do_test conflict-6.$i {
    db close
    sqlite3 db test.db 
    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
    set ::sqlite_opentemp_count 0
    set r0 [catch {execsql [subst {
      DROP TABLE t1;
      CREATE TABLE t1(a,b,c, UNIQUE(a) $conf1);
      INSERT INTO t1 SELECT * FROM t2;
      UPDATE t3 SET x=0;
      BEGIN;
      $cmd t3 SET x=1;
      $cmd t1 SET b=b*2;
      $cmd t1 SET a=c+5;
    }]} r1]
    catch {execsql {COMMIT}}
    if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
    set r2 [execsql {SELECT x FROM t3}]
    list $r0 $r1 $r2 $::sqlite_opentemp_count
  } [list $t0 $t1 $t2 $t3]
}

# Test to make sure a lot of IGNOREs don't cause a stack overflow
#
do_test conflict-7.1 {
  execsql {
    DROP TABLE t1;