/ Check-in [7029b340]
Login

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

Overview
Comment:Fix a faulty assert() statement. Add comments to clarify the behavior of the sqlite3OpenTableAndIndices() routine in insert.c. Add test cases to verify that the assert() statement is not firing inappropriately. Ticket [369d57fb8e5ccdff06f1].
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:7029b3404d3f5f698a496934f3a3f2972051b257
User & Date: drh 2014-08-21 14:10:23
Context
2014-08-21
20:26
Simplify the interface to the symbol table, saving 600 bytes of code space. check-in: 14b0f561 user: drh tags: trunk
19:11
For sqlite3_win32_is_nt(), assume WinRT is NT-based. check-in: 2f59e71f user: mistachkin tags: winrt
16:09
Merge all recent trunk changes, especially the fix for ticket [369d57fb8e5ccdff06f1], but also the skip-scan improvement and performance improvements in the b-tree code. check-in: 0b9e2c32 user: drh tags: sessions
14:10
Fix a faulty assert() statement. Add comments to clarify the behavior of the sqlite3OpenTableAndIndices() routine in insert.c. Add test cases to verify that the assert() statement is not firing inappropriately. Ticket [369d57fb8e5ccdff06f1]. check-in: 7029b340 user: drh tags: trunk
2014-08-20
23:42
Increase the version number to 3.8.7 check-in: 91594aae user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added ext/rtree/rtreeF.test.

            1  +# 2014-08-21
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file contains tests for the r-tree module.
           12  +#
           13  +# This file contains test cases for the ticket
           14  +# [369d57fb8e5ccdff06f197a37147a88f9de95cda] (2014-08-21)
           15  +#
           16  +#  The following SQL causes an assertion fault while running
           17  +#  sqlite3_prepare() on the DELETE statement:
           18  +#
           19  +#     CREATE TABLE t1(x);
           20  +#     CREATE TABLE t2(y);
           21  +#     CREATE VIRTUAL TABLE t3 USING rtree(a,b,c);
           22  +#     CREATE TRIGGER t2del AFTER DELETE ON t2 WHEN (SELECT 1 from t1) BEGIN 
           23  +#       DELETE FROM t3 WHERE a=old.y; 
           24  +#     END;
           25  +#     DELETE FROM t2 WHERE y=1;
           26  +# 
           27  +
           28  +if {![info exists testdir]} {
           29  +  set testdir [file join [file dirname [info script]] .. .. test]
           30  +} 
           31  +source $testdir/tester.tcl
           32  +ifcapable !rtree { finish_test ; return }
           33  +
           34  +do_execsql_test rtreeF-1.1 {
           35  +  CREATE TABLE t1(x);
           36  +  CREATE TABLE t2(y);
           37  +  CREATE VIRTUAL TABLE t3 USING rtree(a,b,c);
           38  +  CREATE TRIGGER t2dwl AFTER DELETE ON t2 WHEN (SELECT 1 from t1) BEGIN 
           39  +    DELETE FROM t3 WHERE a=old.y; 
           40  +  END;
           41  +
           42  +  INSERT INTO t1(x) VALUES(999);
           43  +  INSERT INTO t2(y) VALUES(1),(2),(3),(4),(5);
           44  +  INSERT INTO t3(a,b,c) VALUES(1,2,3),(2,3,4),(3,4,5),(4,5,6),(5,6,7);
           45  +
           46  +  SELECT a FROM t3 ORDER BY a;
           47  +  SELECT '|';
           48  +  SELECT y FROM t2 ORDER BY y;
           49  +} {1 2 3 4 5 | 1 2 3 4 5}
           50  +do_execsql_test rtreeF-1.2 {
           51  +  DELETE FROM t2 WHERE y=3;
           52  +
           53  +  SELECT a FROM t3 ORDER BY a;
           54  +  SELECT '|';
           55  +  SELECT y FROM t2 ORDER BY y;
           56  +} {1 2 4 5 | 1 2 4 5}
           57  +do_execsql_test rtreeF-1.3 {
           58  +  DELETE FROM t1;
           59  +  DELETE FROM t2 WHERE y=5;
           60  +
           61  +  SELECT a FROM t3 ORDER BY a;
           62  +  SELECT '|';
           63  +  SELECT y FROM t2 ORDER BY y;
           64  +} {1 2 4 5 | 1 2 4}
           65  +do_execsql_test rtreeF-1.4 {
           66  +  INSERT INTO t1 DEFAULT VALUES;
           67  +  DELETE FROM t2 WHERE y=5;
           68  +
           69  +  SELECT a FROM t3 ORDER BY a;
           70  +  SELECT '|';
           71  +  SELECT y FROM t2 ORDER BY y;
           72  +} {1 2 4 5 | 1 2 4}
           73  +do_execsql_test rtreeF-1.5 {
           74  +  DELETE FROM t2 WHERE y=2;
           75  +
           76  +  SELECT a FROM t3 ORDER BY a;
           77  +  SELECT '|';
           78  +  SELECT y FROM t2 ORDER BY y;
           79  +} {1 4 5 | 1 4}
           80  +
           81  +finish_test

Changes to src/delete.c.

   462    462     
   463    463       /* Unless this is a view, open cursors for the table we are 
   464    464       ** deleting from and all its indices. If this is a view, then the
   465    465       ** only effect this statement has is to fire the INSTEAD OF 
   466    466       ** triggers.
   467    467       */
   468    468       if( !isView ){
          469  +      testcase( IsVirtual(pTab) );
   469    470         sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen,
   470    471                                    &iDataCur, &iIdxCur);
   471         -      assert( pPk || iDataCur==iTabCur );
   472         -      assert( pPk || iIdxCur==iDataCur+1 );
          472  +      assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
          473  +      assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
   473    474       }
   474    475     
   475    476       /* Set up a loop over the rowids/primary-keys that were found in the
   476    477       ** where-clause loop above.
   477    478       */
   478    479       if( okOnePass ){
   479    480         /* Just one row.  Hence the top-of-loop is a no-op */
   480         -      assert( nKey==nPk ); /* OP_Found will use an unpacked key */
          481  +      assert( nKey==nPk );  /* OP_Found will use an unpacked key */
          482  +      assert( !IsVirtual(pTab) );
   481    483         if( aToOpen[iDataCur-iTabCur] ){
   482    484           assert( pPk!=0 );
   483    485           sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
   484    486           VdbeCoverage(v);
   485    487         }
   486    488       }else if( pPk ){
   487    489         addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);

Changes to src/insert.c.

  1608   1608   ** or the first index for WITHOUT ROWID tables) if it is non-negative.
  1609   1609   ** If iBase is negative, then allocate the next available cursor.
  1610   1610   **
  1611   1611   ** For a rowid table, *piDataCur will be exactly one less than *piIdxCur.
  1612   1612   ** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range
  1613   1613   ** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the
  1614   1614   ** pTab->pIndex list.
         1615  +**
         1616  +** If pTab is a virtual table, then this routine is a no-op and the
         1617  +** *piDataCur and *piIdxCur values are left uninitialized.
  1615   1618   */
  1616   1619   int sqlite3OpenTableAndIndices(
  1617   1620     Parse *pParse,   /* Parsing context */
  1618   1621     Table *pTab,     /* Table to be opened */
  1619   1622     int op,          /* OP_OpenRead or OP_OpenWrite */
  1620   1623     int iBase,       /* Use this for the table cursor, if there is one */
  1621   1624     u8 *aToOpen,     /* If not NULL: boolean for each table and index */
................................................................................
  1626   1629     int iDb;
  1627   1630     int iDataCur;
  1628   1631     Index *pIdx;
  1629   1632     Vdbe *v;
  1630   1633   
  1631   1634     assert( op==OP_OpenRead || op==OP_OpenWrite );
  1632   1635     if( IsVirtual(pTab) ){
  1633         -    assert( aToOpen==0 );
  1634         -    *piDataCur = 0;
  1635         -    *piIdxCur = 1;
         1636  +    /* This routine is a no-op for virtual tables. Leave the output
         1637  +    ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
         1638  +    ** can detect if they are used by mistake in the caller. */
  1636   1639       return 0;
  1637   1640     }
  1638   1641     iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
  1639   1642     v = sqlite3GetVdbe(pParse);
  1640   1643     assert( v!=0 );
  1641   1644     if( iBase<0 ) iBase = pParse->nTab;
  1642   1645     iDataCur = iBase++;