SQLite

Check-in [6504aa47a8]
Login

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

Overview
Comment:Fix an obscure bug causing sqlite3_close() to fail if there are virtual tables on the disconnect list when it is called.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6504aa47a8ebb13827be017c4cb4b2dc3c4c55f4
User & Date: dan 2014-03-12 19:38:38.004
Context
2014-03-14
11:46
Fix a harmless compiler warning that crops up with SQLITE_MAX_MMAP_SIZE=0. (check-in: 1277932b7e user: drh tags: trunk)
2014-03-13
15:41
Merge latest trunk changes into this branch. (check-in: d17231b63d user: dan tags: threads)
2014-03-12
19:38
Fix an obscure bug causing sqlite3_close() to fail if there are virtual tables on the disconnect list when it is called. (check-in: 6504aa47a8 user: dan tags: trunk)
19:20
Changes to FTS to ensure that it does not access the database from within the xConnect method. (check-in: c67a52c356 user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/rtree/rtree.c.
3237
3238
3239
3240
3241
3242
3243


3244
3245
3246
3247
3248
3249
3250
      sqlite3_free(zSql);
    }
  }

  if( rc==SQLITE_OK ){
    *ppVtab = (sqlite3_vtab *)pRtree;
  }else{


    rtreeRelease(pRtree);
  }
  return rc;
}


/*







>
>







3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
      sqlite3_free(zSql);
    }
  }

  if( rc==SQLITE_OK ){
    *ppVtab = (sqlite3_vtab *)pRtree;
  }else{
    assert( *ppVtab==0 );
    assert( pRtree->nBusy==1 );
    rtreeRelease(pRtree);
  }
  return rc;
}


/*
Changes to ext/rtree/rtreeC.test.
238
239
240
241
242
243
244


























245
246
247
248
} {}
do_eqp_test 5.8 {
  SELECT * FROM t1, rt WHERE x==id;
} {
  0 0 0 {SCAN TABLE t1} 
  0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
}




























finish_test








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




238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
} {}
do_eqp_test 5.8 {
  SELECT * FROM t1, rt WHERE x==id;
} {
  0 0 0 {SCAN TABLE t1} 
  0 1 1 {SCAN TABLE rt VIRTUAL TABLE INDEX 1:}
}

#--------------------------------------------------------------------
# Test that having a second connection drop the sqlite_stat1 table
# before it is required by rtreeConnect() does not cause problems.
#
ifcapable rtree {
  reset_db
  do_execsql_test 6.1 {
    CREATE TABLE t1(x);
    CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
    INSERT INTO t1 VALUES(1);
    INSERT INTO rt VALUES(1,2,3);
    ANALYZE;
  }
  db close
  sqlite3 db test.db
  do_execsql_test 6.2 { SELECT * FROM t1 } {1}
  
  do_test 6.3 {
    sqlite3 db2 test.db
    db2 eval { DROP TABLE sqlite_stat1 }
    db2 close
    execsql { SELECT * FROM rt }
  } {1 2.0 3.0}
  db close
}


finish_test

Changes to src/main.c.
796
797
798
799
800
801
802

803
804
805
806
807
808
809
      HashElem *p;
      for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
        Table *pTab = (Table *)sqliteHashData(p);
        if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
      }
    }
  }

  sqlite3BtreeLeaveAll(db);
#else
  UNUSED_PARAMETER(db);
#endif
}

/*







>







796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
      HashElem *p;
      for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
        Table *pTab = (Table *)sqliteHashData(p);
        if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
      }
    }
  }
  sqlite3VtabUnlockList(db);
  sqlite3BtreeLeaveAll(db);
#else
  UNUSED_PARAMETER(db);
#endif
}

/*
Changes to test/fts3ao.test.
214
215
216
217
218
219
220




























221
222
  SELECT count(*) FROM sqlite_master WHERE name LIKE 't8%';
} {6 0}
do_execsql_test 5.2 {
  ALTER TABLE t7 RENAME TO t8;
  SELECT count(*) FROM sqlite_master WHERE name LIKE 't7%';
  SELECT count(*) FROM sqlite_master WHERE name LIKE 't8%';
} {0 6}





























finish_test







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


214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
  SELECT count(*) FROM sqlite_master WHERE name LIKE 't8%';
} {6 0}
do_execsql_test 5.2 {
  ALTER TABLE t7 RENAME TO t8;
  SELECT count(*) FROM sqlite_master WHERE name LIKE 't7%';
  SELECT count(*) FROM sqlite_master WHERE name LIKE 't8%';
} {0 6}

# At one point this was causing a memory leak.
#
foreach {tn sql} {
  1 {}
  2 { INSERT INTO ft(ft) VALUES('merge=2,2'); }
} {
  reset_db
  do_execsql_test 6.$tn.1 "
    CREATE TABLE t1(x);
    CREATE VIRTUAL TABLE ft USING fts3;
    INSERT INTO ft VALUES('hello world');
    $sql
  "

  db close
  sqlite3 db test.db
  do_execsql_test 6.$tn.2 { SELECT * FROM t1 } {}

  do_test 6.$tn.3 {
    sqlite3 db2 test.db
    db2 eval { DROP TABLE t1 }
    db2 close
    set stmt [sqlite3_prepare db { SELECT * FROM ft } -1 dummy]
    sqlite3_finalize $stmt
  } {SQLITE_OK}
  db close
}

finish_test
Changes to test/vtab_shared.test.
11
12
13
14
15
16
17

18
19
20
21
22
23
24
# This file tests interactions between the virtual table and
# shared-schema functionality.
#
# $Id: vtab_shared.test,v 1.3 2009/07/24 17:58:53 danielk1977 Exp $

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


ifcapable !vtab||!shared_cache {
  finish_test
  return
}

db close







>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# This file tests interactions between the virtual table and
# shared-schema functionality.
#
# $Id: vtab_shared.test,v 1.3 2009/07/24 17:58:53 danielk1977 Exp $

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

ifcapable !vtab||!shared_cache {
  finish_test
  return
}

db close
224
225
226
227
228
229
230













































231
232

    INSERT INTO t3 VALUES(4, 5, 6);
    SELECT * FROM t3;
  }
} {1 2 3 4 5 6}

db close
db2 close













































sqlite3_enable_shared_cache 0
finish_test








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


>
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
    INSERT INTO t3 VALUES(4, 5, 6);
    SELECT * FROM t3;
  }
} {1 2 3 4 5 6}

db close
db2 close

#---------------------------------------------------------------
# Test calling sqlite3_close() with vtabs on the disconnect list.
#
ifcapable rtree {
  reset_db
  do_test 2.1.1 {
    sqlite3 db  test.db
    sqlite3 db2 test.db
  
    # Create a virtual table using [db]. 
    execsql {
      CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
      INSERT INTO rt VALUES(1, 2 ,3);
      SELECT * FROM rt;
    }
  
    # Drop the virtual table using [db2]. The sqlite3_vtab object belonging
    # to [db] is moved to the sqlite3.pDisconnect list.
    execsql { DROP TABLE rt } db2
  
    # Immediately close [db]. At one point this would fail due to the 
    # unfinalized statements held by the un-xDisconnect()ed sqlite3_vtab.
    db close
  } {}
  db2 close
}

ifcapable fts3 {
  # Same test as above, except using fts3 instead of rtree.
  reset_db
  do_test 2.2.1 {
    sqlite3 db  test.db
    sqlite3 db2 test.db
    execsql {
      CREATE VIRTUAL TABLE ft USING fts3;
      INSERT INTO ft VALUES('hello world');
      SELECT * FROM ft;
    } 
    execsql { DROP TABLE ft } db2
    db close
  } {}
  db2 close
}

sqlite3_enable_shared_cache 0
finish_test