SQLite

Check-in [d536be698d]
Login

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

Overview
Comment:Roll back the transaction if a write statement fails with OE_Abort but there is no open statement transaction.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | rollback-abort
Files: files | file ages | folders
SHA3-256: d536be698d1c6479e09f99ac12620c900f7f57bad0842372cbfe0755e41355e9
User & Date: dan 2019-01-26 16:34:08.268
Context
2019-01-26
17:47
Fix "PRAGMA journal_mode" so that if it fails because there is a transaction open, it does not roll that transaction back. (check-in: 9f39cb5b81 user: dan tags: rollback-abort)
16:34
Roll back the transaction if a write statement fails with OE_Abort but there is no open statement transaction. (check-in: d536be698d user: dan tags: rollback-abort)
15:40
Add the ".eqp trace" command to the CLI when using SQLITE_DEBUG, as a convenient shorthand for "PRAGMA vdbe_debug=ON" but with automatic indentation feature for program listings provided by the CLI. (check-in: 626502faa1 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/vacuum.c.
126
127
128
129
130
131
132


133
134
135
136
137
138
139
    int iIntoReg = 0;
    if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){
      iIntoReg = ++pParse->nMem;
      sqlite3ExprCode(pParse, pInto, iIntoReg);
    }
    sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg);
    sqlite3VdbeUsesBtree(v, iDb);


  }
build_vacuum_end:
  sqlite3ExprDelete(pParse->db, pInto);
  return;
}

/*







>
>







126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
    int iIntoReg = 0;
    if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){
      iIntoReg = ++pParse->nMem;
      sqlite3ExprCode(pParse, pInto, iIntoReg);
    }
    sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg);
    sqlite3VdbeUsesBtree(v, iDb);
    assert( pParse==pParse->pToplevel || pParse->pToplevel==0 );
    pParse->mayAbort = pParse->isMultiWrite = 1;
  }
build_vacuum_end:
  sqlite3ExprDelete(pParse->db, pInto);
  return;
}

/*
Changes to src/vdbe.c.
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
*/
case OP_Halt: {
  VdbeFrame *pFrame;
  int pcx;

  pcx = (int)(pOp - aOp);
#ifdef SQLITE_DEBUG
  if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); }
#endif
  if( pOp->p1==SQLITE_OK && p->pFrame ){
    /* Halt the sub-program. Return control to the parent frame. */
    pFrame = p->pFrame;
    p->pFrame = pFrame->pParent;
    p->nFrame--;
    sqlite3VdbeSetChanges(db, p->nChange);







|







984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
*/
case OP_Halt: {
  VdbeFrame *pFrame;
  int pcx;

  pcx = (int)(pOp - aOp);
#ifdef SQLITE_DEBUG
  if( pOp->p2==OE_Abort && !pOp->p3 ){ sqlite3VdbeAssertAbortable(p); }
#endif
  if( pOp->p1==SQLITE_OK && p->pFrame ){
    /* Halt the sub-program. Return control to the parent frame. */
    pFrame = p->pFrame;
    p->pFrame = pFrame->pParent;
    p->nFrame--;
    sqlite3VdbeSetChanges(db, p->nChange);
Changes to src/vdbeaux.c.
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
  VdbeOpIter sIter;
  memset(&sIter, 0, sizeof(sIter));
  sIter.v = v;

  while( (pOp = opIterNext(&sIter))!=0 ){
    int opcode = pOp->opcode;
    if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename 
     || opcode==OP_VDestroy
     || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
      && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
    ){
      hasAbort = 1;
      break;
    }
    if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;







|







632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
  VdbeOpIter sIter;
  memset(&sIter, 0, sizeof(sIter));
  sIter.v = v;

  while( (pOp = opIterNext(&sIter))!=0 ){
    int opcode = pOp->opcode;
    if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename 
     || opcode==OP_VDestroy || opcode==OP_Vacuum
     || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
      && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
    ){
      hasAbort = 1;
      break;
    }
    if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
2939
2940
2941
2942
2943
2944
2945
2946


2947
2948
2949
2950
2951
2952
2953
        sqlite3RollbackAll(db, SQLITE_OK);
        p->nChange = 0;
      }
      db->nStatement = 0;
    }else if( eStatementOp==0 ){
      if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
        eStatementOp = SAVEPOINT_RELEASE;
      }else if( p->errorAction==OE_Abort ){


        eStatementOp = SAVEPOINT_ROLLBACK;
      }else{
        sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
        sqlite3CloseSavepoints(db);
        db->autoCommit = 1;
        p->nChange = 0;
      }







|
>
>







2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
        sqlite3RollbackAll(db, SQLITE_OK);
        p->nChange = 0;
      }
      db->nStatement = 0;
    }else if( eStatementOp==0 ){
      if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
        eStatementOp = SAVEPOINT_RELEASE;
      }else if( p->errorAction==OE_Abort 
           && (p->usesStmtJournal || p->readOnly || p->rc!=SQLITE_ERROR) 
      ){
        eStatementOp = SAVEPOINT_ROLLBACK;
      }else{
        sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
        sqlite3CloseSavepoints(db);
        db->autoCommit = 1;
        p->nChange = 0;
      }
Changes to src/window.c.
1072
1073
1074
1075
1076
1077
1078



1079
1080
1081
1082
1083
1084
1085
  VdbeCoverageIf(v, eCond==1);
  VdbeCoverageIf(v, eCond==2);
  sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
  VdbeCoverageNeverNullIf(v, eCond==0);
  VdbeCoverageNeverNullIf(v, eCond==1);
  VdbeCoverageNeverNullIf(v, eCond==2);
  sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);



  sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
  sqlite3ReleaseTempReg(pParse, regZero);
}

/*
** Return the number of arguments passed to the window-function associated
** with the object passed as the only argument to this function.







>
>
>







1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
  VdbeCoverageIf(v, eCond==1);
  VdbeCoverageIf(v, eCond==2);
  sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
  VdbeCoverageNeverNullIf(v, eCond==0);
  VdbeCoverageNeverNullIf(v, eCond==1);
  VdbeCoverageNeverNullIf(v, eCond==2);
  sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
#ifdef SQLITE_DEBUG
  sqlite3VdbeChangeP3(v, -1, 1);
#endif
  sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
  sqlite3ReleaseTempReg(pParse, regZero);
}

/*
** Return the number of arguments passed to the window-function associated
** with the object passed as the only argument to this function.
Changes to test/triggerG.test.
71
72
73
74
75
76
77




















78

  END;
}

do_catchsql_test 310 {
  INSERT INTO t4 VALUES(1);
} {1 {hex literal too big: 0x2147483648e0e0099}}





















finish_test








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

>
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
  END;
}

do_catchsql_test 310 {
  INSERT INTO t4 VALUES(1);
} {1 {hex literal too big: 0x2147483648e0e0099}}

#-------------------------------------------------------------------------

do_execsql_test 400 {
  CREATE TABLE x1(a, b);
  CREATE TRIGGER x1t AFTER INSERT ON x1 BEGIN
    SELECT abs(-9223372036854775808 + new.a);
  END;
  BEGIN;
}

do_catchsql_test 410 {
  INSERT INTO x1 VALUES(2, 2), (0, 0), (1, 1);
} {1 {integer overflow}}

do_execsql_test  420 {
  SELECT * FROM x1; 
} {}

do_test  430 { sqlite3_get_autocommit db } {1}

finish_test

Changes to test/window1.test.
696
697
698
699
700
701
702

































703
704
  WINDOW w1 AS (PARTITION BY b IN (SELECT rowid FROM t7));
} {
  2 10
  1 101
  3 101
}



































finish_test







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


696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
  WINDOW w1 AS (PARTITION BY b IN (SELECT rowid FROM t7));
} {
  2 10
  1 101
  3 101
}

#-------------------------------------------------------------------------
do_execsql_test 17.0 {
  CREATE TABLE tbl1(a,b,c,d);
  CREATE TRIGGER r1 AFTER INSERT ON tbl1 WHEN new.a NOT NULL BEGIN
    SELECT sum(d) OVER
    (PARTITION BY b ORDER BY d ROWS BETWEEN 2 PRECEDING AND -2 FOLLOWING)
    FROM tbl1;
  END;
}

do_catchsql_test 17.1.1 {
  INSERT INTO tbl1(a) VALUES(1);
} {1 {frame ending offset must be a non-negative integer}}
do_execsql_test 17.1.2 {
  SELECT count(*) FROM tbl1;
} 0

do_catchsql_test 17.2.1 {
  INSERT INTO tbl1(a) VALUES(NULL), (NULL), (1);
} {1 {frame ending offset must be a non-negative integer}}
do_execsql_test 17.2.2 {
  SELECT count(*) FROM tbl1;
} 0

do_catchsql_test 17.3.1 {
  BEGIN;
    INSERT INTO tbl1(a) VALUES(NULL);
    INSERT INTO tbl1(a) VALUES(NULL), (1);
} {1 {frame ending offset must be a non-negative integer}}
do_execsql_test 17.3.2 {
  SELECT count(*) FROM tbl1;
} 0
do_test 17.3.3 { sqlite3_get_autocommit db } 1

finish_test