SQLite

Check-in [a3e77c7776]
Login

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

Overview
Comment:Fix a problem in [b5ca442a] causing an assert() to fail in REINDEX commands.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: a3e77c7776ab01dadb9d30d6067ac97e9d4b09ec54834558a5fa1ffed7b52c72
User & Date: dan 2019-05-21 16:32:41.592
Context
2019-05-21
17:04
Combine the implementations of the key and hexkey pragmas into a single case. Have both pragmas return "ok" if they are implemented. (check-in: b3692c406f user: drh tags: trunk)
16:32
Fix a problem in [b5ca442a] causing an assert() to fail in REINDEX commands. (check-in: a3e77c7776 user: dan tags: trunk)
14:42
Use a statement journal for all CREATE INDEX statements in case an indexed exprsesion throws an exception when it is evaluated. Fix for [b5ca442a]. (check-in: b8071d10cb user: dan tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
    addr2 = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeVerifyAbortable(v, OE_Abort);
    sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
                         pIndex->nKeyCol); VdbeCoverage(v);
    sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
    sqlite3VdbeJumpHere(v, j2);
  }else{
    /* Most CREATE INDEX statements that are not UNIQUE can not abort. The
    ** exception is if one of the indexed expressions contains a user
    ** function that throws an exception when it is evaluated. But the
    ** overhead of adding a statement journal to a CREATE INDEX statement
    ** is very small (since most of the pages written do not contain
    ** content that needs to be restored if the statement aborts), so
    ** we call sqlite3MayAbort() for all CREATE INDEX statements.  */
    sqlite3MayAbort(pParse);
    addr2 = sqlite3VdbeCurrentAddr(v);
  }
  sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
  if( !pIndex->bAscKeyBug ){
    /* This OP_SeekEnd opcode makes index insert for a REINDEX go much
    ** faster by avoiding unnecessary seeks.  But the optimization does







|
|
|
|
|
|
|







3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
    addr2 = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeVerifyAbortable(v, OE_Abort);
    sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord,
                         pIndex->nKeyCol); VdbeCoverage(v);
    sqlite3UniqueConstraint(pParse, OE_Abort, pIndex);
    sqlite3VdbeJumpHere(v, j2);
  }else{
    /* Most CREATE INDEX and REINDEX statements that are not UNIQUE can not
    ** abort. The exception is if one of the indexed expressions contains a
    ** user function that throws an exception when it is evaluated. But the
    ** overhead of adding a statement journal to a CREATE INDEX statement is
    ** very small (since most of the pages written do not contain content that
    ** needs to be restored if the statement aborts), so we call 
    ** sqlite3MayAbort() for all CREATE INDEX statements.  */
    sqlite3MayAbort(pParse);
    addr2 = sqlite3VdbeCurrentAddr(v);
  }
  sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
  if( !pIndex->bAscKeyBug ){
    /* This OP_SeekEnd opcode makes index insert for a REINDEX go much
    ** faster by avoiding unnecessary seeks.  But the optimization does
Changes to src/vdbeaux.c.
644
645
646
647
648
649
650





651


652
653
654
655
656
657
658
     || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
      && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
    ){
      hasAbort = 1;
      break;
    }
    if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;





    if( opcode==OP_CreateBtree && pOp->p3==BTREE_BLOBKEY ) hasCreateIndex = 1;


    if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
#ifndef SQLITE_OMIT_FOREIGN_KEY
    if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
      hasFkCounter = 1;
    }
#endif
  }







>
>
>
>
>
|
>
>







644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
     || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
      && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort))
    ){
      hasAbort = 1;
      break;
    }
    if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
    if( mayAbort ){
      /* hasCreateIndex may also be set for some DELETE statements that use
      ** OP_Clear. So this routine may end up returning true in the case 
      ** where a "DELETE FROM tbl" has a statement-journal but does not
      ** require one. This is not so bad - it is an inefficiency, not a bug. */
      if( opcode==OP_CreateBtree && pOp->p3==BTREE_BLOBKEY ) hasCreateIndex = 1;
      if( opcode==OP_Clear ) hasCreateIndex = 1;
    }
    if( opcode==OP_InitCoroutine ) hasInitCoroutine = 1;
#ifndef SQLITE_OMIT_FOREIGN_KEY
    if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
      hasFkCounter = 1;
    }
#endif
  }
Changes to test/indexexpr2.test.
287
288
289
290
291
292
293



294
295
296
297
  CREATE INDEX i0 ON t0(ABS(c0));
} {1 {integer overflow}}
do_execsql_test 7.2 {
  COMMIT;
  SELECT sql FROM sqlite_master WHERE tbl_name = 't0';
  CREATE INDEX i0 ON t0(c0);
} {{CREATE TABLE t0(c0)}}






finish_test







>
>
>




287
288
289
290
291
292
293
294
295
296
297
298
299
300
  CREATE INDEX i0 ON t0(ABS(c0));
} {1 {integer overflow}}
do_execsql_test 7.2 {
  COMMIT;
  SELECT sql FROM sqlite_master WHERE tbl_name = 't0';
  CREATE INDEX i0 ON t0(c0);
} {{CREATE TABLE t0(c0)}}
do_execsql_test 7.3 {
  REINDEX;
} {}



finish_test