SQLite

Check-in [4a1f6a3a9a]
Login

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

Overview
Comment:Fix processing of BEFORE triggers on INSERT statements with RHS SELECTs that insert a NULL into the INTEGER PRIMARY KEY. Ticket #3832. (CVS 6583)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4a1f6a3a9ac8b476c86edac83b555adeef0be4e6
User & Date: drh 2009-05-01 02:08:04.000
Context
2009-05-01
05:23
Fix for tempdb.test so that it passes when running the inmemory_journal permutation test. (CVS 6584) (check-in: 0256187b51 user: danielk1977 tags: trunk)
02:08
Fix processing of BEFORE triggers on INSERT statements with RHS SELECTs that insert a NULL into the INTEGER PRIMARY KEY. Ticket #3832. (CVS 6583) (check-in: 4a1f6a3a9a user: drh tags: trunk)
2009-04-30
17:45
More cleanup, etc. to support MSVC compiles. (CVS 6582) (check-in: 2cd9655e73 user: shane tags: trunk)
Changes
Unified Diff Show Whitespace Changes Patch
Changes to src/insert.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.261 2009/04/30 00:11:10 drh Exp $
*/
#include "sqliteInt.h"

/*
** Generate code that will open a table for reading.
*/
void sqlite3OpenTable(







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.262 2009/05/01 02:08:04 drh Exp $
*/
#include "sqliteInt.h"

/*
** Generate code that will open a table for reading.
*/
void sqlite3OpenTable(
777
778
779
780
781
782
783


784
785
786
787
788
789

790
791
792
793
794
795
796
    ** translated into a unique ID for the row.  But on a BEFORE trigger,
    ** we do not know what the unique ID will be (because the insert has
    ** not happened yet) so we substitute a rowid of -1
    */
    regTrigRowid = sqlite3GetTempReg(pParse);
    if( keyColumn<0 ){
      sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid);


    }else if( useTempTable ){
      sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regTrigRowid);
    }else{
      int j1;
      assert( pSelect==0 );  /* Otherwise useTempTable is true */
      sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regTrigRowid);

      j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regTrigRowid);
      sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid);
      sqlite3VdbeJumpHere(v, j1);
      sqlite3VdbeAddOp1(v, OP_MustBeInt, regTrigRowid);
    }

    /* Cannot have triggers on a virtual table. If it were possible,







>
>
|


<


>







777
778
779
780
781
782
783
784
785
786
787
788

789
790
791
792
793
794
795
796
797
798
    ** translated into a unique ID for the row.  But on a BEFORE trigger,
    ** we do not know what the unique ID will be (because the insert has
    ** not happened yet) so we substitute a rowid of -1
    */
    regTrigRowid = sqlite3GetTempReg(pParse);
    if( keyColumn<0 ){
      sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid);
    }else{
      int j1;
      if( useTempTable ){
      sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regTrigRowid);
    }else{

      assert( pSelect==0 );  /* Otherwise useTempTable is true */
      sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regTrigRowid);
      }
      j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regTrigRowid);
      sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid);
      sqlite3VdbeJumpHere(v, j1);
      sqlite3VdbeAddOp1(v, OP_MustBeInt, regTrigRowid);
    }

    /* Cannot have triggers on a virtual table. If it were possible,
Added test/tkt3832.test.










































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 2009 April 30                                                            
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Ticket #3832
#
# A segfault when using a BEFORE trigger on an INSERT and inserting
# a NULL into the INTEGER PRIMARY KEY.
#
# $Id: tkt3832.test,v 1.1 2009/05/01 02:08:04 drh Exp $

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


do_test tkt3832-1.1 {
  db eval {
    CREATE TABLE t1(a INT, b INTEGER PRIMARY KEY);
    CREATE TABLE log(x);
    CREATE TRIGGER t1r1 BEFORE INSERT ON t1 BEGIN
      INSERT INTO log VALUES(new.b);
    END;
    INSERT INTO t1 VALUES(NULL,5);
    INSERT INTO t1 SELECT b, a FROM t1 ORDER BY b;
    SELECT rowid, * FROM t1;
    SELECT rowid, * FROM log;
  }
} {5 {} 5 6 5 6 1 5 2 -1}

finish_test