/ Check-in [a9b90aa1]
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 a memory-leak/segfault caused by using OP_OpenDup and OP_OpenEphemeral on the same VM cursor.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a9b90aa12eecdd9f2a8b2d23da8b7cac43d8b1789f5cefa3f4e939d9f2b59269
User & Date: dan 2019-05-03 18:50:24
Context
2019-05-03
19:34
Ensure that UTF16 strings are properly zero-terminated before returning them in an sqlite3_value_text16() request, even if the string is invalid UTF16 because it was formed from an arbitrary and/or odd-length BLOB. check-in: 3a16ddf9 user: drh tags: trunk
18:50
Fix a memory-leak/segfault caused by using OP_OpenDup and OP_OpenEphemeral on the same VM cursor. check-in: a9b90aa1 user: dan tags: trunk
17:19
Fix a problem where self-joins on views that are aggregate queries may return the wrong result. check-in: 74ef97bf user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

   252    252   
   253    253     assert( iCur>=0 && iCur<p->nCursor );
   254    254     if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
   255    255       /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag
   256    256       ** is clear. Otherwise, if this is an ephemeral cursor created by 
   257    257       ** OP_OpenDup, the cursor will not be closed and will still be part
   258    258       ** of a BtShared.pCursor list.  */
   259         -    p->apCsr[iCur]->isEphemeral = 0;
          259  +    if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0;
   260    260       sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
   261    261       p->apCsr[iCur] = 0;
   262    262     }
   263    263     if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
   264    264       p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
   265    265       memset(pCx, 0, offsetof(VdbeCursor,pAltCursor));
   266    266       pCx->eCurType = eCurType;
................................................................................
  3706   3706         SQLITE_OPEN_TRANSIENT_DB;
  3707   3707     assert( pOp->p1>=0 );
  3708   3708     assert( pOp->p2>=0 );
  3709   3709     pCx = p->apCsr[pOp->p1];
  3710   3710     if( pCx ){
  3711   3711       /* If the ephermeral table is already open, erase all existing content
  3712   3712       ** so that the table is empty again, rather than creating a new table. */
  3713         -    rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
         3713  +    assert( pCx->isEphemeral );
         3714  +    if( pCx->pBtx ){
         3715  +      rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
         3716  +    }
  3714   3717     }else{
  3715   3718       pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
  3716   3719       if( pCx==0 ) goto no_mem;
  3717   3720       pCx->nullRow = 1;
  3718   3721       pCx->isEphemeral = 1;
  3719   3722       rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, 
  3720   3723                             BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5,

Changes to test/with3.test.

   125    125     |  `--RECURSIVE STEP
   126    126     |     |--SCAN TABLE w1
   127    127     |     `--SCAN TABLE c
   128    128     |--SCAN SUBQUERY xxxxxx
   129    129     |--SEARCH TABLE w2 USING INTEGER PRIMARY KEY (rowid=?)
   130    130     `--SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?)
   131    131   }
          132  +
          133  +do_execsql_test 4.0 {
          134  +  WITH t5(t5col1) AS (
          135  +    SELECT (
          136  +      WITH t3(t3col1) AS (
          137  +        WITH t2 AS (
          138  +          WITH t1 AS (SELECT 1 AS c1 GROUP BY 1) 
          139  +          SELECT a.c1 FROM t1 AS a, t1 AS b
          140  +          WHERE anoncol1 = 1
          141  +        )
          142  +        SELECT (SELECT 1 FROM t2) FROM t2
          143  +      ) 
          144  +      SELECT t3col1 FROM t3 WHERE t3col1
          145  +    ) FROM (SELECT 1 AS anoncol1)
          146  +  )
          147  +  SELECT t5col1, t5col1 FROM t5
          148  +} {1 1}
          149  +do_execsql_test 4.1 {
          150  +  SELECT EXISTS (
          151  +    WITH RECURSIVE Table0 AS (
          152  +      WITH RECURSIVE Table0(Col0) AS (SELECT ALL 1  ) 
          153  +      SELECT ALL (
          154  +        WITH RECURSIVE Table0 AS (
          155  +          WITH RECURSIVE Table0 AS (
          156  +            WITH RECURSIVE Table0 AS (SELECT DISTINCT 1  GROUP BY 1  ) 
          157  +            SELECT DISTINCT * FROM Table0 NATURAL INNER JOIN Table0
          158  +            WHERE Col0 = 1  
          159  +          )
          160  +          SELECT ALL (SELECT DISTINCT * FROM Table0) FROM Table0 WHERE Col0 = 1
          161  +        ) 
          162  +        SELECT ALL * FROM Table0  NATURAL INNER JOIN  Table0      
          163  +      ) FROM Table0 ) 
          164  +      SELECT DISTINCT * FROM Table0  NATURAL INNER JOIN  Table0      
          165  +    ); 
          166  +} {1}
          167  +
   132    168   
   133    169   finish_test