SQLite

Check-in [e5bb7db51c]
Login

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

Overview
Comment:Fix a problem causing "PRAGMA integrity_check" to disable the xfer optimization for subsequent VACUUM operations on tables with one or more CHECK constraints. This could result in VACUUM producing slightly larger database files.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: e5bb7db51cdfd8124c60329782798cea398733545594dab55cb892b2a08c4d29
User & Date: dan 2017-04-04 19:58:54.565
Context
2017-04-05
10:54
Attempt to remove bash-isms from configure.ac. Use -O0 with --enable-debug. (check-in: 71ed35ccf7 user: drh tags: trunk)
2017-04-04
19:58
Fix a problem causing "PRAGMA integrity_check" to disable the xfer optimization for subsequent VACUUM operations on tables with one or more CHECK constraints. This could result in VACUUM producing slightly larger database files. (check-in: e5bb7db51c user: dan tags: trunk)
2017-04-03
14:07
Avoid an unnecessary call to sqlite3WhereGetMask() inside of whereShortCut(). (check-in: 5c11f4303f user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/pragma.c.
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
1568
1569
                              pTab->aCol[j].zName);
          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
          integrityCheckResultRow(v, 3);
          sqlite3VdbeJumpHere(v, jmp2);
        }
        /* Verify CHECK constraints */
        if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){


          int addrCkFault = sqlite3VdbeMakeLabel(v);
          int addrCkOk = sqlite3VdbeMakeLabel(v);
          ExprList *pCheck = pTab->pCheck;
          char *zErr;
          int k;
          pParse->iSelfTab = iDataCur;
          sqlite3ExprCachePush(pParse);
          for(k=pCheck->nExpr-1; k>0; k--){
            sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
          }
          sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, 
                            SQLITE_JUMPIFNULL);
          sqlite3VdbeResolveLabel(v, addrCkFault);
          zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
                                pTab->zName);
          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
          integrityCheckResultRow(v, 3);
          sqlite3VdbeResolveLabel(v, addrCkOk);
          sqlite3ExprCachePop(pParse);


        }
        /* Validate index entries for the current row */
        for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
          int jmp2, jmp3, jmp4, jmp5;
          int ckUniq = sqlite3VdbeMakeLabel(v);
          if( pPk==pIdx ) continue;
          r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,







>
>
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>







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
1568
1569
1570
1571
1572
                              pTab->aCol[j].zName);
          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
          integrityCheckResultRow(v, 3);
          sqlite3VdbeJumpHere(v, jmp2);
        }
        /* Verify CHECK constraints */
        if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
          ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
          if( db->mallocFailed==0 ){
            int addrCkFault = sqlite3VdbeMakeLabel(v);
            int addrCkOk = sqlite3VdbeMakeLabel(v);

            char *zErr;
            int k;
            pParse->iSelfTab = iDataCur;
            sqlite3ExprCachePush(pParse);
            for(k=pCheck->nExpr-1; k>0; k--){
              sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
            }
            sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, 
                SQLITE_JUMPIFNULL);
            sqlite3VdbeResolveLabel(v, addrCkFault);
            zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s",
                pTab->zName);
            sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
            integrityCheckResultRow(v, 3);
            sqlite3VdbeResolveLabel(v, addrCkOk);
            sqlite3ExprCachePop(pParse);
          }
          sqlite3ExprListDelete(db, pCheck);
        }
        /* Validate index entries for the current row */
        for(j=0, pIdx=pTab->pIndex; pIdx && !isQuick; pIdx=pIdx->pNext, j++){
          int jmp2, jmp3, jmp4, jmp5;
          int ckUniq = sqlite3VdbeMakeLabel(v);
          if( pPk==pIdx ) continue;
          r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
Changes to test/insert4.test.
11
12
13
14
15
16
17

18
19
20
21
22
23
24
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the INSERT transfer optimization.
#
# $Id: insert4.test,v 1.10 2008/01/21 16:22:46 drh Exp $

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


ifcapable !view||!subquery {
  finish_test
  return
}

# The sqlite3_xferopt_count variable is incremented whenever the 







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the INSERT transfer optimization.
#
# $Id: insert4.test,v 1.10 2008/01/21 16:22:46 drh Exp $

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

ifcapable !view||!subquery {
  finish_test
  return
}

# The sqlite3_xferopt_count variable is incremented whenever the 
561
562
563
564
565
566
567
568
































569
} {1 3}

do_catchsql_test insert4-9.1 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x);
  INSERT INTO t1(x) VALUES(5 COLLATE xyzzy) UNION SELECT 0;
} {1 {no such collation sequence: xyzzy}}

































finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
} {1 3}

do_catchsql_test insert4-9.1 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x);
  INSERT INTO t1(x) VALUES(5 COLLATE xyzzy) UNION SELECT 0;
} {1 {no such collation sequence: xyzzy}}

#-------------------------------------------------------------------------
# Check that running an integrity-check does not disable the xfer 
# optimization for tables with CHECK constraints.
#
do_execsql_test 10.1 {
  CREATE TABLE t8(
    rid INTEGER,
    pid INTEGER,
    mid INTEGER,
    px INTEGER DEFAULT(0) CHECK(px IN(0, 1))
  );
  CREATE TEMP TABLE x(
    rid INTEGER,
    pid INTEGER,
    mid INTEGER,
    px INTEGER DEFAULT(0) CHECK(px IN(0, 1))
  );
}
do_test 10.2 {
  set sqlite3_xferopt_count 0
  execsql { INSERT INTO x SELECT * FROM t8 }
  set sqlite3_xferopt_count
} {1}

do_test 10.3 {
  execsql { PRAGMA integrity_check }
  set sqlite3_xferopt_count 0
  execsql { INSERT INTO x     SELECT * FROM t8 }
  set sqlite3_xferopt_count
} {1}


finish_test
Added test/pragmafault.test.














































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# 2010 June 15
#
# 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.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/lock_common.tcl
source $testdir/malloc_common.tcl
set testprefix pragmafault

db close
sqlite3 db test.db
sqlite3_db_config_lookaside db 0 0 0
do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, CHECK(a!=b));
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);
}
faultsim_save_and_close

do_faultsim_test 1 -prep {
  faultsim_restore_and_reopen
} -body {
  catchsql { PRAGMA integrity_check }
  set {} 0
} -test {
  faultsim_test_result {0 0} 
}


finish_test