/ Check-in [3f3acee4]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Fix for [b1d3a2e531].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3f3acee465a6e390301f9dc588dd1d8e0bd646bd
User & Date: dan 2011-08-22 09:54:26
References
2011-08-22
17:49 Ticket [b1d3a2e5] Erroneous FK constraint failure when dropping table. status still Closed with 1 other change artifact: 796ec978 user: drh
09:55 Ticket [b1d3a2e5]: 3 changes artifact: 1a01bb22 user: dan
Context
2011-08-22
20:33
Remove an unreachable branch in the FK code. check-in: 6c227cc8 user: drh tags: trunk
09:54
Fix for [b1d3a2e531]. check-in: 3f3acee4 user: dan tags: trunk
2011-08-19
14:54
When retrying a write() after an EINTR error on unix, be sure to also rerun the previous lseek(). Ticket [e59bdf6116036a] check-in: 21452f3a user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/fkey.c.

730
731
732
733
734
735
736

737
















738
739
740
741
742
743
744
    ** early.  */
    if( pParse->disableTriggers ){
      pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
    }else{
      pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
    }
    if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){

      if( !isIgnoreErrors || db->mallocFailed ) return;
















      continue;
    }
    assert( pFKey->nCol==1 || (aiFree && pIdx) );

    if( aiFree ){
      aiCol = aiFree;
    }else{







>

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







730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
    ** early.  */
    if( pParse->disableTriggers ){
      pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
    }else{
      pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
    }
    if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
      assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
      if( !isIgnoreErrors || db->mallocFailed ) return;
      if( isIgnoreErrors && pTo==0 ){
        /* If isIgnoreErrors is true, then a table is being dropped. In this
        ** case SQLite runs a "DELETE FROM xxx" on the table being dropped
        ** before actually dropping it in order to check FK constraints.
        ** If the parent table of an FK constraint on the current table is
        ** missing, behave as if it is empty. i.e. decrement the relevant
        ** FK counter for each row of the current table with non-NULL keys.
        */
        Vdbe *v = sqlite3GetVdbe(pParse);
        int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1;
        for(i=0; i<pFKey->nCol; i++){
          int iReg = pFKey->aCol[i].iFrom + regOld + 1;
          sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump);
        }
        sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1);
      }
      continue;
    }
    assert( pFKey->nCol==1 || (aiFree && pIdx) );

    if( aiFree ){
      aiCol = aiFree;
    }else{

Added test/tkt-b1d3a2e531.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
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
# 2011 August 22
#
# 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 foreign keys. Specifically, it tests
# that ticket b1d3a2e531 has been fixed.
#

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

ifcapable {!foreignkey||!trigger} {
  finish_test
  return
}
set testprefix tkt-b1d3a2e531

do_execsql_test 1.0 { PRAGMA foreign_keys = ON }

do_execsql_test 1.1 {
  CREATE TABLE pp(x PRIMARY KEY);
  CREATE TABLE cc(y REFERENCES pp DEFERRABLE INITIALLY DEFERRED);
  INSERT INTO pp VALUES('abc');
  INSERT INTO cc VALUES('abc');
}
do_execsql_test 1.2 {
  BEGIN;
    DROP TABLE pp;
    DROP TABLE cc;
  COMMIT;
}
do_execsql_test 1.3 {
  CREATE TABLE pp(x PRIMARY KEY);
  CREATE TABLE cc(y REFERENCES pp DEFERRABLE INITIALLY DEFERRED);
  INSERT INTO pp VALUES('abc');
  INSERT INTO cc VALUES('abc');
}
do_execsql_test 1.4 {
  BEGIN;
    DROP TABLE cc;
    DROP TABLE pp;
  COMMIT;
}

do_execsql_test 2.1 {
  CREATE TABLE pp(x PRIMARY KEY);
  CREATE TABLE cc(
    y INTEGER PRIMARY KEY REFERENCES pp DEFERRABLE INITIALLY DEFERRED
  );
  INSERT INTO pp VALUES(5);
  INSERT INTO cc VALUES(5);
}
do_execsql_test 2.2 {
  BEGIN;
    DROP TABLE pp;
    DROP TABLE cc;
  COMMIT;
}
do_execsql_test 2.3 {
  CREATE TABLE pp(x PRIMARY KEY);
  CREATE TABLE cc(
    y INTEGER PRIMARY KEY REFERENCES pp DEFERRABLE INITIALLY DEFERRED
  );
  INSERT INTO pp VALUES(5);
  INSERT INTO cc VALUES(5);
}
do_execsql_test 2.4 {
  BEGIN;
    DROP TABLE cc;
    DROP TABLE pp;
  COMMIT;
}

do_execsql_test 3.1 {
  CREATE TABLE pp1(x PRIMARY KEY);
  CREATE TABLE cc1(y REFERENCES pp1 DEFERRABLE INITIALLY DEFERRED);

  CREATE TABLE pp2(x PRIMARY KEY);
  CREATE TABLE cc2(y REFERENCES pp1 DEFERRABLE INITIALLY DEFERRED);

  INSERT INTO pp1 VALUES(2200);
  INSERT INTO cc1 VALUES(NULL);

  INSERT INTO pp2 VALUES(2200);
  INSERT INTO cc2 VALUES(2200);
}
do_catchsql_test 3.2 {
  BEGIN;
    DELETE FROM pp2;
    DROP TABLE pp1;
    DROP TABLE cc1;
  COMMIT;
} {1 {foreign key constraint failed}}
do_catchsql_test 3.3 {
    DROP TABLE cc2;
  COMMIT;
} {0 {}}



finish_test