/ Check-in [66158843]
Login

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

Overview
Comment:Fix a memory leak associated with PRIMARY KEY in a CREATE TABLE statement that fails. Ticket #249. (CVS 1730)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 66158843dfa073ffb8779a5170e091cebc018855
User & Date: drh 2003-02-26 13:52:51
Context
2003-02-26
13:52
Fix a memory leak associated with PRIMARY KEY in a CREATE TABLE statement that fails. Ticket #249. (CVS 874) check-in: 8e9dc567 user: drh tags: trunk
13:52
Fix a memory leak associated with PRIMARY KEY in a CREATE TABLE statement that fails. Ticket #249. (CVS 1730) check-in: 66158843 user: drh tags: trunk
2003-02-20
01:48
When the right table in a LEFT OUTER JOIN contains an INTEGER PRIMARY KEY make sure that key is NULL if there is no row in the right table that matches the current row in the left table. Tickets #246 and #247. (CVS 873) check-in: 6a45fe3b user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
...
626
627
628
629
630
631
632

633




634
635
636
637
638
639
640
**     COPY
**     VACUUM
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.129 2003/02/12 14:09:44 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
** If the key is not an INTEGER PRIMARY KEY, then create a unique
** index for the key.  No index is created for INTEGER PRIMARY KEYs.
*/
void sqliteAddPrimaryKey(Parse *pParse, IdList *pList, int onError){
  Table *pTab = pParse->pNewTable;
  char *zType = 0;
  int iCol = -1;
  if( pTab==0 ) return;
  if( pTab->hasPrimKey ){
    sqliteSetString(&pParse->zErrMsg, "table \"", pTab->zName, 
        "\" has more than one primary key", 0);
    pParse->nErr++;
    return;
  }
  pTab->hasPrimKey = 1;
  if( pList==0 ){
    iCol = pTab->nCol - 1;
  }else if( pList->nId==1 ){
    for(iCol=0; iCol<pTab->nCol; iCol++){
      if( sqliteStrICmp(pList->a[0].zName, pTab->aCol[iCol].zName)==0 ) break;
................................................................................
  }
  if( pParse->db->file_format>=1 && 
           zType && sqliteStrICmp(zType, "INTEGER")==0 ){
    pTab->iPKey = iCol;
    pTab->keyConf = onError;
  }else{
    sqliteCreateIndex(pParse, 0, 0, pList, onError, 0, 0);

  }




}

/*
** Return the appropriate collating type given a type name.
**
** The collation type is text (SQLITE_SO_TEXT) if the type
** name contains the character stream "text" or "blob" or







|







 







|




|







 







>

>
>
>
>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
...
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
**     COPY
**     VACUUM
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.130 2003/02/26 13:52:51 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
** If the key is not an INTEGER PRIMARY KEY, then create a unique
** index for the key.  No index is created for INTEGER PRIMARY KEYs.
*/
void sqliteAddPrimaryKey(Parse *pParse, IdList *pList, int onError){
  Table *pTab = pParse->pNewTable;
  char *zType = 0;
  int iCol = -1;
  if( pTab==0 ) goto primary_key_exit;
  if( pTab->hasPrimKey ){
    sqliteSetString(&pParse->zErrMsg, "table \"", pTab->zName, 
        "\" has more than one primary key", 0);
    pParse->nErr++;
    goto primary_key_exit;
  }
  pTab->hasPrimKey = 1;
  if( pList==0 ){
    iCol = pTab->nCol - 1;
  }else if( pList->nId==1 ){
    for(iCol=0; iCol<pTab->nCol; iCol++){
      if( sqliteStrICmp(pList->a[0].zName, pTab->aCol[iCol].zName)==0 ) break;
................................................................................
  }
  if( pParse->db->file_format>=1 && 
           zType && sqliteStrICmp(zType, "INTEGER")==0 ){
    pTab->iPKey = iCol;
    pTab->keyConf = onError;
  }else{
    sqliteCreateIndex(pParse, 0, 0, pList, onError, 0, 0);
    pList = 0;
  }

primary_key_exit:
  sqliteIdListDelete(pList);
  return;
}

/*
** Return the appropriate collating type given a type name.
**
** The collation type is text (SQLITE_SO_TEXT) if the type
** name contains the character stream "text" or "blob" or

Changes to test/conflict.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the conflict resolution extension
# to SQLite.
#
# $Id: conflict.test,v 1.15 2003/01/29 18:46:54 drh Exp $

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

# Create tables for the first group of tests.
#
do_test conflict-1.0 {
................................................................................

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

# Six columns of configuration data as follows:
#







|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the conflict resolution extension
# to SQLite.
#
# $Id: conflict.test,v 1.16 2003/02/26 13:52:52 drh Exp $

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

# Create tables for the first group of tests.
#
do_test conflict-1.0 {
................................................................................

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

# Six columns of configuration data as follows:
#

Changes to test/memleak.test.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
37
38
39
40
41
42
43





44

45
46
47
48
49
50
51
52
#    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 runs all tests.
#
# $Id: memleak.test,v 1.1 2002/08/31 16:52:45 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {
  catch {db close}
  memleak_check
................................................................................
  quick.test
  malloc.test
  misuse.test
  memleak.test
  btree2.test
  trans.test
}







foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
  set tail [file tail $testfile]
  if {[lsearch -exact $EXCLUDE $tail]>=0} continue
  set LeakList {}
  for {set COUNTER 0} {$COUNTER<$COUNT} {incr COUNTER} {
    source $testfile
    if {[info exists Leak]} {
      lappend LeakList $Leak







|







 







>
>
>
>
>
|
>
|







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#    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 runs all tests.
#
# $Id: memleak.test,v 1.2 2003/02/26 13:52:52 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {
  catch {db close}
  memleak_check
................................................................................
  quick.test
  malloc.test
  misuse.test
  memleak.test
  btree2.test
  trans.test
}
if {[llength $argv]>0} {
  set FILELIST $argv
  set argv {}
} else {
  set FILELIST [lsort -dictionary [glob $testdir/*.test]]
}

foreach testfile $FILELIST {
  set tail [file tail $testfile]
  if {[lsearch -exact $EXCLUDE $tail]>=0} continue
  set LeakList {}
  for {set COUNTER 0} {$COUNTER<$COUNT} {incr COUNTER} {
    source $testfile
    if {[info exists Leak]} {
      lappend LeakList $Leak

Changes to test/misc1.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
475
476
477
478
479
480
481
482








































483
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc1.test,v 1.20 2003/02/01 13:53:28 drh Exp $

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

# Test the creation and use of tables that have a large number
# of columns.
#
................................................................................
do_test misc1-15.2 {
  catchsql {
    CREATE TABLE t10 AS SELECT 1;
  }
  # The bug in ticket #238 causes the statement above to fail with
  # the error "table t10 alread exists"
} {0 {}}









































finish_test







|







 








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

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc1.test,v 1.21 2003/02/26 13:52:52 drh Exp $

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

# Test the creation and use of tables that have a large number
# of columns.
#
................................................................................
do_test misc1-15.2 {
  catchsql {
    CREATE TABLE t10 AS SELECT 1;
  }
  # The bug in ticket #238 causes the statement above to fail with
  # the error "table t10 alread exists"
} {0 {}}

# Test for memory leaks when a CREATE TABLE containing a primary key
# fails.  Ticket #249.
#
do_test misc1-16.1 {
  catchsql {SELECT name FROM sqlite_master LIMIT 1}
  catchsql {
    CREATE TABLE test(a integer, primary key(a));
  }
} {0 {}}
do_test misc1-16.2 {
  catchsql {
    CREATE TABLE test(a integer, primary key(a));
  }
} {1 {table test already exists}}
do_test misc1-16.3 {
  catchsql {
    CREATE TABLE test2(a text primary key, b text, primary key(a,b));
  }
} {1 {table "test2" has more than one primary key}}
do_test misc1-16.4 {
  execsql {
    INSERT INTO test VALUES(1);
    SELECT rowid, a FROM test;
  }
} {1 1}
do_test misc1-16.5 {
  execsql {
    INSERT INTO test VALUES(5);
    SELECT rowid, a FROM test;
  }
} {1 1 5 5}
do_test misc1-16.6 {
  execsql {
    INSERT INTO test VALUES(NULL);
    SELECT rowid, a FROM test;
  }
} {1 1 5 5 6 6}



finish_test