1# 2007 April 26 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 file is testing the incremental vacuum feature. 13# 14# Note: There are also some tests for incremental vacuum and IO 15# errors in incrvacuum_ioerr.test. 16# 17# $Id: incrvacuum.test,v 1.23 2009/02/18 20:31:18 drh Exp $ 18 19set testdir [file dirname $argv0] 20source $testdir/tester.tcl 21 22# If this build of the library does not support auto-vacuum, omit this 23# whole file. 24ifcapable {!autovacuum || !pragma} { 25 finish_test 26 return 27} 28 29#--------------------------------------------------------------------- 30# Test the pragma on an empty database. 31# 32do_test incrvacuum-1.1 { 33 execsql { 34 pragma auto_vacuum; 35 } 36} $sqlite_options(default_autovacuum) 37do_test incrvacuum-1.2.0 { 38 # File size is sometimes 1 instead of 0 due to the hack we put in 39 # to work around ticket #3260. Search for comments on #3260 in 40 # os_unix.c. 41 expr {[file size test.db] > 1} 42} {0} 43do_test incrvacuum-1.2 { 44 # This command will create the database. 45 execsql { 46 pragma auto_vacuum = 'full'; 47 pragma auto_vacuum; 48 } 49} {1} 50do_test incrvacuum-1.2.1 { 51 expr {[file size test.db] > 0} 52} {1} 53do_test incrvacuum-1.3 { 54 execsql { 55 pragma auto_vacuum = 'incremental'; 56 pragma auto_vacuum; 57 } 58} {2} 59do_test incrvacuum-1.4 { 60 # In this case the invalid value is ignored and the auto_vacuum 61 # setting remains unchanged. 62 execsql { 63 pragma auto_vacuum = 'invalid'; 64 pragma auto_vacuum; 65 } 66} {2} 67do_test incrvacuum-1.5 { 68 execsql { 69 pragma auto_vacuum = 1; 70 pragma auto_vacuum; 71 } 72} {1} 73do_test incrvacuum-1.6 { 74 execsql { 75 pragma auto_vacuum = '2'; 76 pragma auto_vacuum; 77 } 78} {2} 79do_test incrvacuum-1.7 { 80 # Invalid value. auto_vacuum setting remains unchanged. 81 execsql { 82 pragma auto_vacuum = 5; 83 pragma auto_vacuum; 84 } 85} {2} 86 87#--------------------------------------------------------------------- 88# Test the pragma on a non-empty database. It is possible to toggle 89# the connection between "full" and "incremental" mode, but not to 90# change from either of these to "none", or from "none" to "full" or 91# "incremental". 92# 93do_test incrvacuum-2.1 { 94 execsql { 95 pragma auto_vacuum = 1; 96 CREATE TABLE abc(a, b, c); 97 } 98} {} 99do_test incrvacuum-2.2 { 100 execsql { 101 pragma auto_vacuum = 'none'; 102 pragma auto_vacuum; 103 } 104} {1} 105do_test incrvacuum-2.2.1 { 106 db close 107 sqlite3 db test.db 108 execsql { 109 pragma auto_vacuum; 110 } 111} {1} 112do_test incrvacuum-2.3 { 113 execsql { 114 pragma auto_vacuum = 'incremental'; 115 pragma auto_vacuum; 116 } 117} {2} 118do_test incrvacuum-2.4 { 119 execsql { 120 pragma auto_vacuum = 'full'; 121 pragma auto_vacuum; 122 } 123} {1} 124 125#--------------------------------------------------------------------- 126# Test that when the auto_vacuum mode is "incremental", the database 127# does not shrink when pages are removed from it. But it does if 128# the mode is set to "full". 129# 130do_test incrvacuum-3.1 { 131 execsql { 132 pragma auto_vacuum; 133 } 134} {1} 135do_test incrvacuum-3.2 { 136 set ::str [string repeat 1234567890 110] 137 execsql { 138 PRAGMA auto_vacuum = 2; 139 BEGIN; 140 CREATE TABLE tbl2(str); 141 INSERT INTO tbl2 VALUES($::str); 142 COMMIT; 143 } 144 # 5 pages: 145 # 146 # 1 -> database header 147 # 2 -> first back-pointer page 148 # 3 -> table abc 149 # 4 -> table tbl2 150 # 5 -> table tbl2 overflow page. 151 # 152 expr {[file size test.db] / 1024} 153} {5} 154do_test incrvacuum-3.3 { 155 execsql { 156 DROP TABLE abc; 157 DELETE FROM tbl2; 158 } 159 expr {[file size test.db] / 1024} 160} {5} 161do_test incrvacuum-3.4 { 162 execsql { 163 PRAGMA auto_vacuum = 1; 164 INSERT INTO tbl2 VALUES('hello world'); 165 } 166 expr {[file size test.db] / 1024} 167} {3} 168 169#--------------------------------------------------------------------- 170# Try to run a very simple incremental vacuum. Also verify that 171# PRAGMA incremental_vacuum is a harmless no-op against a database that 172# does not support auto-vacuum. 173# 174do_test incrvacuum-4.1 { 175 set ::str [string repeat 1234567890 110] 176 execsql { 177 PRAGMA auto_vacuum = 2; 178 INSERT INTO tbl2 VALUES($::str); 179 CREATE TABLE tbl1(a, b, c); 180 } 181 expr {[file size test.db] / 1024} 182} {5} 183do_test incrvacuum-4.2 { 184 execsql { 185 DELETE FROM tbl2; 186 DROP TABLE tbl1; 187 } 188 expr {[file size test.db] / 1024} 189} {5} 190do_test incrvacuum-4.3 { 191 set ::nStep 0 192 db eval {pragma incremental_vacuum(10)} { 193 incr ::nStep 194 } 195 list [expr {[file size test.db] / 1024}] $::nStep 196} {3 2} 197 198#--------------------------------------------------------------------- 199# The following tests - incrvacuum-5.* - test incremental vacuum 200# from within a transaction. 201# 202do_test incrvacuum-5.1.1 { 203 expr {[file size test.db] / 1024} 204} {3} 205do_test incrvacuum-5.1.2 { 206 execsql { 207 BEGIN; 208 DROP TABLE tbl2; 209 PRAGMA incremental_vacuum; 210 COMMIT; 211 } 212 expr {[file size test.db] / 1024} 213} {1} 214 215do_test incrvacuum-5.2.1 { 216 set ::str [string repeat abcdefghij 110] 217 execsql { 218 BEGIN; 219 CREATE TABLE tbl1(a); 220 INSERT INTO tbl1 VALUES($::str); 221 PRAGMA incremental_vacuum; -- this is a no-op. 222 COMMIT; 223 } 224 expr {[file size test.db] / 1024} 225} {4} 226do_test incrvacuum-5.2.2 { 227 set ::str [string repeat abcdefghij 110] 228 execsql { 229 BEGIN; 230 INSERT INTO tbl1 VALUES($::str); 231 INSERT INTO tbl1 SELECT * FROM tbl1; 232 DELETE FROM tbl1 WHERE oid%2; -- Put 2 overflow pages on free-list. 233 COMMIT; 234 } 235 expr {[file size test.db] / 1024} 236} {7} 237do_test incrvacuum-5.2.3 { 238 execsql { 239 BEGIN; 240 PRAGMA incremental_vacuum; -- Vacuum up the two pages. 241 CREATE TABLE tbl2(b); -- Use one free page as a table root. 242 INSERT INTO tbl2 VALUES('a nice string'); 243 COMMIT; 244 } 245 expr {[file size test.db] / 1024} 246} {6} 247do_test incrvacuum-5.2.4 { 248 execsql { 249 SELECT * FROM tbl2; 250 } 251} {{a nice string}} 252do_test incrvacuum-5.2.5 { 253 execsql { 254 DROP TABLE tbl1; 255 DROP TABLE tbl2; 256 PRAGMA incremental_vacuum; 257 } 258 expr {[file size test.db] / 1024} 259} {1} 260 261 262# Test cases incrvacuum-5.3.* use the following list as input data. 263# Two new databases are opened, one with incremental vacuum enabled, 264# the other with no auto-vacuum completely disabled. After executing 265# each element of the following list on both databases, test that 266# the integrity-check passes and the contents of each are identical. 267# 268set TestScriptList [list { 269 BEGIN; 270 CREATE TABLE t1(a, b); 271 CREATE TABLE t2(a, b); 272 CREATE INDEX t1_i ON t1(a); 273 CREATE INDEX t2_i ON t2(a); 274} { 275 INSERT INTO t1 VALUES($::str1, $::str2); 276 INSERT INTO t1 VALUES($::str1||$::str2, $::str2||$::str1); 277 INSERT INTO t2 SELECT b, a FROM t1; 278 INSERT INTO t2 SELECT a, b FROM t1; 279 INSERT INTO t1 SELECT b, a FROM t2; 280 UPDATE t2 SET b = ''; 281 PRAGMA incremental_vacuum; 282} { 283 UPDATE t2 SET b = (SELECT b FROM t1 WHERE t1.oid = t2.oid); 284 PRAGMA incremental_vacuum; 285} { 286 CREATE TABLE t3(a, b); 287 INSERT INTO t3 SELECT * FROM t2; 288 DROP TABLE t2; 289 PRAGMA incremental_vacuum; 290} { 291 CREATE INDEX t3_i ON t3(a); 292 COMMIT; 293} { 294 BEGIN; 295 DROP INDEX t3_i; 296 PRAGMA incremental_vacuum; 297 INSERT INTO t3 VALUES('hello', 'world'); 298 ROLLBACK; 299} { 300 INSERT INTO t3 VALUES('hello', 'world'); 301} 302] 303 304# If this build omits subqueries, step 2 in the above list will not 305# work. Replace it with "" in this case. 306# 307ifcapable !subquery { lset TestScriptList 2 "" } 308 309# Compare the contents of databases $A and $B. 310# 311proc compare_dbs {A B tname} { 312 set tbl_list [execsql { 313 SELECT tbl_name FROM sqlite_master WHERE type = 'table' 314 } $A] 315 316 do_test ${tname}.1 [subst { 317 execsql { 318 SELECT tbl_name FROM sqlite_master WHERE type = 'table' 319 } $B 320 }] $tbl_list 321 322 set tn 1 323 foreach tbl $tbl_list { 324 set control [execsql "SELECT * FROM $tbl" $A] 325 do_test ${tname}.[incr tn] [subst { 326 execsql "SELECT * FROM $tbl" $B 327 }] $control 328 } 329} 330 331set ::str1 [string repeat abcdefghij 130] 332set ::str2 [string repeat 1234567890 105] 333 334file delete -force test1.db test1.db-journal test2.db test2.db-journal 335sqlite3 db1 test1.db 336sqlite3 db2 test2.db 337execsql { PRAGMA auto_vacuum = 'none' } db1 338execsql { PRAGMA auto_vacuum = 'incremental' } db2 339 340set tn 1 341foreach sql $::TestScriptList { 342 execsql $sql db1 343 execsql $sql db2 344 345 compare_dbs db1 db2 incrvacuum-5.3.${tn} 346 do_test incrvacuum-5.3.${tn}.integrity1 { 347 execsql { PRAGMA integrity_check; } db1 348 } {ok} 349 do_test incrvacuum-5.3.${tn}.integrity2 { 350 execsql { PRAGMA integrity_check; } db2 351 } {ok} 352 incr tn 353} 354db1 close 355db2 close 356# 357# End of test cases 5.3.* 358 359#--------------------------------------------------------------------- 360# The following tests - incrvacuum-6.* - test running incremental 361# vacuum while another statement (a read) is being executed. 362# 363for {set jj 0} {$jj < 10} {incr jj} { 364 # Build some test data. Two tables are created in an empty 365 # database. tbl1 data is a contiguous block starting at page 5 (pages 366 # 3 and 4 are the table roots). tbl2 is a contiguous block starting 367 # right after tbl1. 368 # 369 # Then drop tbl1 so that when an incr vacuum is run the pages 370 # of tbl2 have to be moved to fill the gap. 371 # 372 do_test incrvacuum-6.${jj}.1 { 373 execsql { 374 DROP TABLE IF EXISTS tbl1; 375 DROP TABLE IF EXISTS tbl2; 376 PRAGMA incremental_vacuum; 377 CREATE TABLE tbl1(a, b); 378 CREATE TABLE tbl2(a, b); 379 BEGIN; 380 } 381 for {set ii 0} {$ii < 1000} {incr ii} { 382 db eval {INSERT INTO tbl1 VALUES($ii, $ii || $ii)} 383 } 384 execsql { 385 INSERT INTO tbl2 SELECT * FROM tbl1; 386 COMMIT; 387 DROP TABLE tbl1; 388 } 389 expr {[file size test.db] / 1024} 390 } {36} 391 392 # Run a linear scan query on tbl2. After reading ($jj*100) rows, 393 # run the incremental vacuum to shrink the database. 394 # 395 do_test incrvacuum-6.${jj}.2 { 396 set ::nRow 0 397 db eval {SELECT a FROM tbl2} {} { 398 if {$a == [expr $jj*100]} { 399 db eval {PRAGMA incremental_vacuum} 400 } 401 incr ::nRow 402 } 403 list [expr {[file size test.db] / 1024}] $nRow 404 } {19 1000} 405} 406 407#--------------------------------------------------------------------- 408# This test - incrvacuum-7.* - is to check that the database can be 409# written in the middle of an incremental vacuum. 410# 411set ::iWrite 1 412while 1 { 413 do_test incrvacuum-7.${::iWrite}.1 { 414 execsql { 415 DROP TABLE IF EXISTS tbl1; 416 DROP TABLE IF EXISTS tbl2; 417 PRAGMA incremental_vacuum; 418 CREATE TABLE tbl1(a, b); 419 CREATE TABLE tbl2(a, b); 420 BEGIN; 421 } 422 for {set ii 0} {$ii < 1000} {incr ii} { 423 db eval {INSERT INTO tbl1 VALUES($ii, $ii || $ii)} 424 } 425 execsql { 426 INSERT INTO tbl2 SELECT * FROM tbl1; 427 COMMIT; 428 DROP TABLE tbl1; 429 } 430 expr {[file size test.db] / 1024} 431 } {36} 432 433 do_test incrvacuum-7.${::iWrite}.2 { 434 set ::nRow 0 435 db eval {PRAGMA incremental_vacuum} { 436 incr ::nRow 437 if {$::nRow == $::iWrite} { 438 db eval { 439 CREATE TABLE tbl1(a, b); 440 INSERT INTO tbl1 VALUES('hello', 'world'); 441 } 442 } 443 } 444 list [expr {[file size test.db] / 1024}] 445 } {20} 446 447 do_test incrvacuum-7.${::iWrite}.3 { 448 execsql { 449 SELECT * FROM tbl1; 450 } 451 } {hello world} 452 453 if {$::nRow == $::iWrite} break 454 incr ::iWrite 455} 456 457#--------------------------------------------------------------------- 458# This test - incrvacuum-8.* - is to check that nothing goes wrong 459# with an incremental-vacuum if it is the first statement executed 460# after an existing database is opened. 461# 462# At one point, this would always return SQLITE_SCHEMA (which 463# causes an infinite loop in tclsqlite.c if using the Tcl interface). 464# 465do_test incrvacuum-8.1 { 466 db close 467 sqlite3 db test.db 468 execsql { 469 PRAGMA incremental_vacuum(50); 470 } 471} {} 472 473#--------------------------------------------------------------------- 474# At one point this test case was causing an assert() to fail. 475# 476do_test incrvacuum-9.1 { 477 db close 478 file delete -force test.db test.db-journal 479 sqlite3 db test.db 480 481 execsql { 482 PRAGMA auto_vacuum = 'incremental'; 483 CREATE TABLE t1(a, b, c); 484 CREATE TABLE t2(a, b, c); 485 INSERT INTO t2 VALUES(randstr(500,500),randstr(500,500),randstr(500,500)); 486 INSERT INTO t1 VALUES(1, 2, 3); 487 INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1; 488 INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1; 489 INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1; 490 INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1; 491 INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1; 492 INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1; 493 INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1; 494 INSERT INTO t1 SELECT a||a, b||b, c||c FROM t1; 495 } 496} {} 497 498do_test incrvacuum-9.2 { 499 execsql { 500 PRAGMA synchronous = 'OFF'; 501 BEGIN; 502 UPDATE t1 SET a = a, b = b, c = c; 503 DROP TABLE t2; 504 PRAGMA incremental_vacuum(10); 505 ROLLBACK; 506 } 507} {} 508 509do_test incrvacuum-9.3 { 510 execsql { 511 PRAGMA cache_size = 10; 512 BEGIN; 513 UPDATE t1 SET a = a, b = b, c = c; 514 DROP TABLE t2; 515 PRAGMA incremental_vacuum(10); 516 ROLLBACK; 517 } 518} {} 519 520#--------------------------------------------------------------------- 521# Test that the parameter to the incremental_vacuum pragma works. That 522# is, if the user executes "PRAGMA incremental_vacuum(N)", at most 523# N pages are vacuumed. 524# 525do_test incrvacuum-10.1 { 526 execsql { 527 DROP TABLE t1; 528 DROP TABLE t2; 529 } 530 expr [file size test.db] / 1024 531} {29} 532 533do_test incrvacuum-10.2 { 534 execsql { 535 PRAGMA incremental_vacuum(1); 536 } 537 expr [file size test.db] / 1024 538} {28} 539 540do_test incrvacuum-10.3 { 541 execsql { 542 PRAGMA incremental_vacuum(5); 543 } 544 expr [file size test.db] / 1024 545} {23} 546 547do_test incrvacuum-10.4 { 548 execsql { 549 PRAGMA incremental_vacuum('1'); 550 } 551 expr [file size test.db] / 1024 552} {22} 553 554do_test incrvacuum-10.5 { 555 execsql { 556 PRAGMA incremental_vacuum("+3"); 557 } 558 expr [file size test.db] / 1024 559} {19} 560 561do_test incrvacuum-10.6 { 562 execsql { 563 PRAGMA incremental_vacuum = 1; 564 } 565 expr [file size test.db] / 1024 566} {18} 567 568do_test incrvacuum-10.7 { 569 # Use a really big number as an argument to incremetal_vacuum. Should 570 # be interpreted as "free all possible space". 571 execsql { 572 PRAGMA incremental_vacuum(2147483649); 573 } 574 expr [file size test.db] / 1024 575} {1} 576 577do_test incrvacuum-10.8 { 578 execsql { 579 CREATE TABLE t1(x); 580 INSERT INTO t1 VALUES(hex(randomblob(1000))); 581 DROP TABLE t1; 582 } 583 # A negative number means free all possible space. 584 execsql { 585 PRAGMA incremental_vacuum=-1; 586 } 587 expr [file size test.db] / 1024 588} {1} 589 590#---------------------------------------------------------------- 591# Test that if we set the auto_vacuum mode to 'incremental', then 592# create a database, thereafter that database defaults to incremental 593# vacuum mode. 594# 595db close 596file delete -force test.db test.db-journal 597sqlite3 db test.db 598 599ifcapable default_autovacuum { 600 do_test incrvacuum-11.1-av-dflt-on { 601 execsql { 602 PRAGMA auto_vacuum; 603 } 604 } $AUTOVACUUM 605} else { 606 do_test incrvacuum-11.1-av-dflt-off { 607 execsql { 608 PRAGMA auto_vacuum; 609 } 610 } {0} 611} 612do_test incrvacuum-11.2 { 613 execsql { 614 PRAGMA auto_vacuum = incremental; 615 } 616} {} 617do_test incrvacuum-11.3 { 618 execsql { 619 PRAGMA auto_vacuum; 620 } 621} {2} 622do_test incrvacuum-11.4 { 623 # The database has now been created. 624 expr {[file size test.db]>0} 625} {1} 626do_test incrvacuum-11.5 { 627 # Close and reopen the connection. 628 db close 629 sqlite3 db test.db 630 631 # Test we are still in incremental vacuum mode. 632 execsql { PRAGMA auto_vacuum; } 633} {2} 634do_test incrvacuum-11.6 { 635 execsql { 636 PRAGMA auto_vacuum = 'full'; 637 PRAGMA auto_vacuum; 638 } 639} {1} 640do_test incrvacuum-11.7 { 641 # Close and reopen the connection. 642 db close 643 sqlite3 db test.db 644 645 # Test we are still in "full" auto-vacuum mode. 646 execsql { PRAGMA auto_vacuum; } 647} {1} 648 649#---------------------------------------------------------------------- 650# Special case: What happens if the database is locked when a "PRAGMA 651# auto_vacuum = XXX" statement is executed. 652# 653db close 654file delete -force test.db test.db-journal 655sqlite3 db test.db 656 657do_test incrvacuum-12.1 { 658 execsql { 659 PRAGMA auto_vacuum = 1; 660 } 661 expr {[file size test.db]>0} 662} {1} 663 664# Try to change the auto-vacuum from "full" to "incremental" while the 665# database is locked. Nothing should change. 666# 667do_test incrvacuum-12.2 { 668 sqlite3 db2 test.db 669 execsql { BEGIN EXCLUSIVE; } db2 670 catchsql { PRAGMA auto_vacuum = 2; } 671} {1 {database is locked}} 672 673do_test incrvacuum-12.3 { 674 execsql { ROLLBACK; } db2 675 execsql { PRAGMA auto_vacuum } 676} {2} ;# Still 2 because PRAGMA auto_vacuum setting held in case of vacuum 677do_test incrvacuum-12.4 { 678 db close 679 sqlite3 db test.db 680 execsql { PRAGMA auto_vacuum } 681} {1} ;# Revert to 1 because the database file did not change 682 683do_test incrvacuum-12.5 { 684 execsql { SELECT * FROM sqlite_master } 685 execsql { PRAGMA auto_vacuum } 686} {1} 687 688#---------------------------------------------------------------------- 689# Special case #2: What if one process prepares a "PRAGMA auto_vacuum = XXX" 690# statement when the database is empty, but doesn't execute it until 691# after some other process has created the database. 692# 693db2 close 694db close 695file delete -force test.db test.db-journal 696sqlite3 db test.db ; set ::DB [sqlite3_connection_pointer db] 697sqlite3 db2 test.db 698 699do_test incrvacuum-13.1 { 700 # File size is sometimes 1 instead of 0 due to the hack we put in 701 # to work around ticket #3260. Search for comments on #3260 in 702 # os_unix.c. 703 expr {[file size test.db]>1} 704} {0} 705do_test incrvacuum-13.2 { 706 set ::STMT [sqlite3_prepare $::DB {PRAGMA auto_vacuum = 2} -1 DUMMY] 707 execsql { 708 PRAGMA auto_vacuum = none; 709 PRAGMA default_cache_size = 1024; 710 PRAGMA auto_vacuum; 711 } db2 712} {0} 713do_test incrvacuum-13.3 { 714 expr {[file size test.db]>0} 715} {1} 716do_test incrvacuum-13.4 { 717 set rc [sqlite3_step $::STMT] 718 list $rc [sqlite3_finalize $::STMT] 719} {SQLITE_DONE SQLITE_OK} 720do_test incrvacuum-13.5 { 721 execsql { 722 PRAGMA auto_vacuum; 723 } 724} {0} 725 726 727# Verify that the incremental_vacuum pragma fails gracefully if it 728# is used against an invalid database file. 729# 730if {[permutation] == ""} { 731 do_test incrvacuum-14.1 { 732 set out [open invalid.db w] 733 puts $out "This is not an SQLite database file" 734 close $out 735 sqlite3 db3 invalid.db 736 catchsql { 737 PRAGMA incremental_vacuum(10); 738 } db3 739 } {1 {file is encrypted or is not a database}} 740 db3 close 741} 742 743do_test incrvacuum-15.1 { 744 db close 745 db2 close 746 file delete -force test.db 747 sqlite3 db test.db 748 749 set str [string repeat "abcdefghij" 500] 750 751 execsql { 752 PRAGMA cache_size = 10; 753 PRAGMA auto_vacuum = incremental; 754 CREATE TABLE t1(x, y); 755 INSERT INTO t1 VALUES('a', $str); 756 INSERT INTO t1 VALUES('b', $str); 757 INSERT INTO t1 VALUES('c', $str); 758 INSERT INTO t1 VALUES('d', $str); 759 INSERT INTO t1 VALUES('e', $str); 760 INSERT INTO t1 VALUES('f', $str); 761 INSERT INTO t1 VALUES('g', $str); 762 INSERT INTO t1 VALUES('h', $str); 763 INSERT INTO t1 VALUES('i', $str); 764 INSERT INTO t1 VALUES('j', $str); 765 INSERT INTO t1 VALUES('j', $str); 766 767 CREATE TABLE t2(x PRIMARY KEY, y); 768 INSERT INTO t2 VALUES('a', $str); 769 INSERT INTO t2 VALUES('b', $str); 770 INSERT INTO t2 VALUES('c', $str); 771 INSERT INTO t2 VALUES('d', $str); 772 773 BEGIN; 774 DELETE FROM t2; 775 PRAGMA incremental_vacuum; 776 } 777 778 catchsql {INSERT INTO t2 SELECT * FROM t1} 779 780 execsql { 781 COMMIT; 782 PRAGMA integrity_check; 783 } 784} {ok} 785 786finish_test 787