summaryrefslogtreecommitdiffstats
path: root/test/pragma3.test
blob: c4794c743c65589c6d27bdae51b91b4cb703ebd3 (plain)
1
2
3
4
5
6
7
8
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
114
115
116
117
118
119
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
154
155
156
157
158
159
160
161
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
202
203
204
205
206
207
208
209
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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# 2014-12-19
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for PRAGMA data_version command.
#

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

if {[sqlite3 -has-codec]} {
  finish_test
  return
}

do_execsql_test pragma3-100 {
  PRAGMA data_version;
} {1}
do_execsql_test pragma3-101 {
  PRAGMA temp.data_version;
} {1}

# Writing to the pragma is a no-op 
do_execsql_test pragma3-102 {
  PRAGMA main.data_version=1234;
  PRAGMA main.data_version;
} {1 1}

# EVIDENCE-OF: R-27726-60934 The "PRAGMA data_version" command provides
# an indication that the database file has been modified.
#
# EVIDENCE-OF: R-47505-58569 The "PRAGMA data_version" value is
# unchanged for commits made on the same database connection.
#
do_execsql_test pragma3-110 {
  PRAGMA data_version;
  BEGIN IMMEDIATE;
  PRAGMA data_version;
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(100),(200),(300);
  PRAGMA data_version;
  COMMIT;
  SELECT * FROM t1;
  PRAGMA data_version;
} {1 1 1 100 200 300 1}

sqlite3 db2 test.db
do_test pragma3-120 {
  db2 eval {
    SELECT * FROM t1;
    PRAGMA data_version;
  }
} {100 200 300 1}

do_execsql_test pragma3-130 {
  PRAGMA data_version;
  BEGIN IMMEDIATE;
  PRAGMA data_version;
  INSERT INTO t1 VALUES(400),(500);
  PRAGMA data_version;
  COMMIT;
  SELECT * FROM t1;
  PRAGMA data_version;
  PRAGMA shrink_memory;
} {1 1 1 100 200 300 400 500 1}

# EVIDENCE-OF: R-63005-41812 The integer values returned by two
# invocations of "PRAGMA data_version" from the same connection will be
# different if changes were committed to the database by any other
# connection in the interim.
#
# Value went from 1 in pragma3-120 to 2 here.
#
do_test pragma3-140 {
  db2 eval {
    SELECT * FROM t1;
    PRAGMA data_version;
    BEGIN IMMEDIATE;
    PRAGMA data_version;
    UPDATE t1 SET a=a+1;
    COMMIT;
    SELECT * FROM t1;
    PRAGMA data_version;
  }
} {100 200 300 400 500 2 2 101 201 301 401 501 2}
do_execsql_test pragma3-150 {
  SELECT * FROM t1;
  PRAGMA data_version;
} {101 201 301 401 501 2}

#
do_test pragma3-160 {
  db eval {
    BEGIN;
    PRAGMA data_version;
    UPDATE t1 SET a=555 WHERE a=501;
    PRAGMA data_version;
    SELECT * FROM t1 ORDER BY a;
    PRAGMA data_version;
  }
} {2 2 101 201 301 401 555 2}
do_test pragma3-170 {
  db2 eval {
    PRAGMA data_version;
  }
} {2}
do_test pragma3-180 {
  db eval {
    COMMIT;
    PRAGMA data_version;
  }
} {2}
do_test pragma3-190 {
  db2 eval {
    PRAGMA data_version;
  }
} {3}

# EVIDENCE-OF: R-19326-44825 The "PRAGMA data_version" value is a local
# property of each database connection and so values returned by two
# concurrent invocations of "PRAGMA data_version" on separate database
# connections are often different even though the underlying database is
# identical.
#
do_test pragma3-195 {
  expr {[db eval {PRAGMA data_version}]!=[db2 eval {PRAGMA data_version}]}
} {1}

# EVIDENCE-OF: R-54562-06892 The behavior of "PRAGMA data_version" is
# the same for all database connections, including database connections
# in separate processes and shared cache database connections.
#
# The next block checks the behavior for separate processes.
#
do_test pragma3-200 {
  db eval {PRAGMA data_version; SELECT * FROM t1;}
} {2 101 201 301 401 555}
do_test pragma3-201 {
  set fd [open pragma3.txt wb]
  puts $fd {
     sqlite3 db test.db;
     db eval {DELETE FROM t1 WHERE a>300};
     db close;
     exit;
  }
  close $fd
  exec [info nameofexec] pragma3.txt
  forcedelete pragma3.txt
  db eval {
    PRAGMA data_version;
    SELECT * FROM t1;
  }
} {3 101 201}
db2 close
db close

# EVIDENCE-OF: R-54562-06892 The behavior of "PRAGMA data_version" is
# the same for all database connections, including database connections
# in separate processes and shared cache database connections.
#
# The next block checks that behavior is the same for shared-cache.
#
ifcapable shared_cache {
  set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
  sqlite3 db test.db
  sqlite3 db2 test.db
  do_test pragma3-300 {
    db eval {
      PRAGMA data_version;
      BEGIN;
      CREATE TABLE t3(a,b,c);
      CREATE TABLE t4(x,y,z);
      INSERT INTO t4 VALUES(123,456,789);
      PRAGMA data_version;
      COMMIT;
      PRAGMA data_version;
    }
  } {1 1 1}
  do_test pragma3-310 {
    db2 eval {
      PRAGMA data_version;
      BEGIN;
      INSERT INTO t3(a,b,c) VALUES('abc','def','ghi');
      SELECT * FROM t3;
      PRAGMA data_version;
    }
  } {2 abc def ghi 2}
  # The transaction in db2 has not yet committed, so the data_version in
  # db is unchanged.
  do_test pragma3-320 {
    db eval {
      PRAGMA data_version;
      SELECT * FROM t4;
    }
  } {1 123 456 789}
  do_test pragma3-330 {
    db2 eval {
      COMMIT;
      PRAGMA data_version;
      SELECT * FROM t4;
    }
  } {2 123 456 789}
  do_test pragma3-340 {
    db eval {
      PRAGMA data_version;
      SELECT * FROM t3;
      SELECT * FROM t4;
    }
  } {2 abc def ghi 123 456 789}
  db2 close
  db close
  sqlite3_enable_shared_cache $::enable_shared_cache
}

# Make sure this also works in WAL mode
#
# This will not work with the in-memory journal permutation, as opening
# [db2] switches the journal mode back to "memory"
#
if {[wal_is_capable]} {
if {[permutation]!="inmemory_journal"} {

  sqlite3 db test.db
  db eval {PRAGMA journal_mode=WAL}
  sqlite3 db2 test.db
  do_test pragma3-400 {
    db eval {
      PRAGMA data_version;
      PRAGMA journal_mode;
      SELECT * FROM t1;
    }
  } {2 wal 101 201}
  do_test pragma3-410 {
    db2 eval {
      PRAGMA data_version;
      PRAGMA journal_mode;
      SELECT * FROM t1;
    }
  } {2 wal 101 201}
  do_test pragma3-420 {
    db eval {UPDATE t1 SET a=111*(a/100); PRAGMA data_version; SELECT * FROM t1}
  } {2 111 222}
  do_test pragma3-430 {
    db2 eval {PRAGMA data_version; SELECT * FROM t1;}
  } {3 111 222}
  db2 close
}
}

#-------------------------------------------------------------------------
# Check that empty write transactions do not cause the return of "PRAGMA
# data_version" to be decremented with journal_mode=PERSIST and
# locking_mode=EXCLUSIVE
#
foreach {tn sql} {
  A {
  }
  B {
    PRAGMA journal_mode = PERSIST;
    PRAGMA locking_mode = EXCLUSIVE;
  }
} {
  reset_db
  execsql $sql

  do_execsql_test pragma3-510$tn {
    CREATE TABLE t1(x, y);
    INSERT INTO t1 VALUES(1, 2);
    PRAGMA data_version;
  } {1}

  do_execsql_test pragma3-520$tn {
    BEGIN EXCLUSIVE;
    COMMIT;
    PRAGMA data_version;
  } {1}
}

finish_test