SQLite

Check-in [b90d9de32d]
Login

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

Overview
Comment:Fix a memory leak in triggers and update tests to show the latest error message text. (CVS 886)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: b90d9de32d10a71fe81f5bfd0cf57faae8c5c3b4
User & Date: drh 2003-03-30 00:19:50.000
Context
2003-03-30
18:41
Detect when a child node of a btree page has zero entries and report that as a case of database corruption. (CVS 887) (check-in: 66c80ae232 user: drh tags: trunk)
00:19
Fix a memory leak in triggers and update tests to show the latest error message text. (CVS 886) (check-in: b90d9de32d user: drh tags: trunk)
2003-03-27
13:50
Regression tests now work - except for some changes in error message text. The library is now safe to use for experimental work. (CVS 885) (check-in: 8a593e9c2d user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
**     COPY
**     VACUUM
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.135 2003/03/27 13:50:00 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







|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
**     COPY
**     VACUUM
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.136 2003/03/30 00:19:50 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
1448
1449
1450
1451
1452
1453
1454
1455






1456
1457
1458
1459
1460
1461
1462
    assert( pTable->nSrc==1 );
    pTab =  sqliteSrcListLookup(pParse, pTable);
  }else{
    assert( pName==0 );
    pTab =  pParse->pNewTable;
  }
  if( pTab==0 || pParse->nErr ) goto exit_create_index;
  if( !isTemp && (pTab->readOnly || pTab->iDb>=2) ){






    sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, 
      " may not have non-temporary indices added", 0);
    pParse->nErr++;
    goto exit_create_index;
  }
  if( pTab->pSelect ){
    sqliteSetString(&pParse->zErrMsg, "views may not be indexed", 0);







|
>
>
>
>
>
>







1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
    assert( pTable->nSrc==1 );
    pTab =  sqliteSrcListLookup(pParse, pTable);
  }else{
    assert( pName==0 );
    pTab =  pParse->pNewTable;
  }
  if( pTab==0 || pParse->nErr ) goto exit_create_index;
  if( pTab->readOnly ){
    sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
      " may not be indexed", 0);
    pParse->nErr++;
    goto exit_create_index;
  }
  if( !isTemp && pTab->iDb>=2 ){
    sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName, 
      " may not have non-temporary indices added", 0);
    pParse->nErr++;
    goto exit_create_index;
  }
  if( pTab->pSelect ){
    sqliteSetString(&pParse->zErrMsg, "views may not be indexed", 0);
Changes to src/trigger.c.
167
168
169
170
171
172
173

174
175
176
177
178
179
180
  if( !pParse->explain ){
    /* Stick it in the hash-table */
    sqliteHashInsert(&(db->aDb[nt->iDb].trigHash), nt->name, pName->n + 1, nt);

    /* Attach it to the table object */
    nt->pNext = tab->pTrigger;
    tab->pTrigger = nt;

    return;
  }else{
    sqliteFree(nt->name);
    sqliteFree(nt->table);
    sqliteFree(nt);
  }








>







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  if( !pParse->explain ){
    /* Stick it in the hash-table */
    sqliteHashInsert(&(db->aDb[nt->iDb].trigHash), nt->name, pName->n + 1, nt);

    /* Attach it to the table object */
    nt->pNext = tab->pTrigger;
    tab->pTrigger = nt;
    sqliteSrcListDelete(pTableName);
    return;
  }else{
    sqliteFree(nt->name);
    sqliteFree(nt->table);
    sqliteFree(nt);
  }

376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
  assert( pTable->iDb==pTrigger->iDb );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    if( pTable->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
    if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName) ||
      sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pTable->iDb),0) ){
      return;
    }
  }
#endif

  /*
   * If this is not an "explain", then delete the trigger structure.
   */







|







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
  assert( pTable->iDb==pTrigger->iDb );
#ifndef SQLITE_OMIT_AUTHORIZATION
  {
    int code = SQLITE_DROP_TRIGGER;
    if( pTable->iDb ) code = SQLITE_DROP_TEMP_TRIGGER;
    if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName) ||
      sqliteAuthCheck(pParse, SQLITE_DELETE, SCHEMA_TABLE(pTable->iDb),0) ){
      goto drop_trigger_cleanup;
    }
  }
#endif

  /*
   * If this is not an "explain", then delete the trigger structure.
   */
Changes to test/index.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the CREATE INDEX statement.
#
# $Id: index.test,v 1.20 2002/08/13 23:02:58 drh Exp $

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

# Create a basic index and verify it is added to sqlite_master
#
do_test index-1.1 {













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the CREATE INDEX statement.
#
# $Id: index.test,v 1.21 2003/03/30 00:19:50 drh Exp $

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

# Create a basic index and verify it is added to sqlite_master
#
do_test index-1.1 {
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
} {}

# Do not allow indices to be added to sqlite_master
#
do_test index-5.1 {
  set v [catch {execsql {CREATE INDEX index1 ON sqlite_master(name)}} msg]
  lappend v $msg
} {1 {table sqlite_master may not have new indices added}}
do_test index-5.2 {
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}

# Do not allow indices with duplicate names to be added
#
do_test index-6.1 {







|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
} {}

# Do not allow indices to be added to sqlite_master
#
do_test index-5.1 {
  set v [catch {execsql {CREATE INDEX index1 ON sqlite_master(name)}} msg]
  lappend v $msg
} {1 {table sqlite_master may not be indexed}}
do_test index-5.2 {
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}

# Do not allow indices with duplicate names to be added
#
do_test index-6.1 {
Changes to test/temptable.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for temporary tables and indices.
#
# $Id: temptable.test,v 1.8 2002/09/02 12:14:51 drh Exp $

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

# Create an alternative connection to the database
#
do_test temptable-1.0 {







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for temporary tables and indices.
#
# $Id: temptable.test,v 1.9 2003/03/30 00:19:50 drh Exp $

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

# Create an alternative connection to the database
#
do_test temptable-1.0 {
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
  }
} {9 8 7}
do_test temptable-4.3 {
  catchsql {
    SELECT * FROM t2;
  } db2
} {1 {database schema has changed}}
do_test temptable-4.4 {











  catchsql {
    SELECT * FROM t2;
  } db2
} {0 {10 20}}
do_test temptable-4.5 {
  catchsql {
    DROP TABLE t2;
    SELECT * FROM t2;
  } db2
} {1 {no such table: t2}}
do_test temptable-4.6 {
  db2 close
  sqlite db2 ./test.db
  catchsql {
    SELECT * FROM t2;
  } db2
} {0 {9 8 7}}







|
>
>
>
>
>
>
>
>
>
>
>






|
|

|







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
  }
} {9 8 7}
do_test temptable-4.3 {
  catchsql {
    SELECT * FROM t2;
  } db2
} {1 {database schema has changed}}
do_test temptable-4.4.1 {
  catchsql {
    SELECT * FROM temp.t2;
  } db2
} {0 {10 20}}
do_test temptable-4.4.2 {
  catchsql {
    SELECT * FROM main.t2;
  } db2
} {0 {9 8 7}}
do_test temptable-4.4.3 {
  # TEMP takes precedence over MAIN
  catchsql {
    SELECT * FROM t2;
  } db2
} {0 {10 20}}
do_test temptable-4.5 {
  catchsql {
    DROP TABLE t2;     -- should drop TEMP
    SELECT * FROM t2;  -- data should be from MAIN
  } db2
} {0 {9 8 7}}
do_test temptable-4.6 {
  db2 close
  sqlite db2 ./test.db
  catchsql {
    SELECT * FROM t2;
  } db2
} {0 {9 8 7}}
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
do_test temptable-4.12 {
  execsql {
    SELECT * FROM t2;
  }
} {3 4}
do_test temptable-4.13 {
  catchsql {
    DROP TABLE t2;
    SELECT * FROM t2;
  } db2
} {1 {no such table: t2}}
do_test temptable-4.14 {
  execsql {
    SELECT * FROM t2;
  }
} {3 4}
do_test temptable-4.15 {
  db2 close







|
|

|







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
do_test temptable-4.12 {
  execsql {
    SELECT * FROM t2;
  }
} {3 4}
do_test temptable-4.13 {
  catchsql {
    DROP TABLE t2;     -- drops TEMP.T2
    SELECT * FROM t2;  -- uses MAIN.T2
  } db2
} {0 {3 4}}
do_test temptable-4.14 {
  execsql {
    SELECT * FROM t2;
  }
} {3 4}
do_test temptable-4.15 {
  db2 close
Changes to test/trigger1.test.
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

do_test trigger1-1.9 {
  catchsql {
    CREATE TRIGGER tr1 AFTER UPDATE ON sqlite_master BEGIN
       SELECT * FROM sqlite_master;
    END;
  }
} {1 {cannot create trigger on system table: sqlite_master}}

# Check to make sure that a DELETE statement within the body of
# a trigger does not mess up the DELETE that caused the trigger to
# run in the first place.
#
do_test trigger1-1.10 {
  execsql {







|







110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

do_test trigger1-1.9 {
  catchsql {
    CREATE TRIGGER tr1 AFTER UPDATE ON sqlite_master BEGIN
       SELECT * FROM sqlite_master;
    END;
  }
} {1 {cannot create trigger on system table}}

# Check to make sure that a DELETE statement within the body of
# a trigger does not mess up the DELETE that caused the trigger to
# run in the first place.
#
do_test trigger1-1.10 {
  execsql {