/ Check-in [46501f49]
Login

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

Overview
Comment:Change the OP_Insert opcode to read the key and data to insert from memory cells, not the stack. (CVS 4666)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 46501f490a5f5577ea31c758df749e02c7c65f39
User & Date: danielk1977 2008-01-03 09:51:55
Context
2008-01-03
11:50
Change the VdbeOp.p4 union to include specific pointer types for the various values of VdbeOp.p4type. (CVS 4667) check-in: 7e8330c8 user: danielk1977 tags: trunk
09:51
Change the OP_Insert opcode to read the key and data to insert from memory cells, not the stack. (CVS 4666) check-in: 46501f49 user: danielk1977 tags: trunk
08:18
Change the output of vdbe_trace etc. to include operands p3 and p5. (CVS 4665) check-in: 76f2040b user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/analyze.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
**    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.
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** @(#) $Id: analyze.c,v 1.28 2008/01/03 07:54:24 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"

/*
** This routine generates code that opens the sqlite_stat1 table on cursor
** iStatCur.
................................................................................
      if( i==nCol-1 ){
        sqlite3VdbeAddOp1(v, OP_Concat, nCol*2-1);
      }else{
        sqlite3VdbeAddOp1(v, OP_Dup, 1);
      }
    }
    sqlite3VdbeAddOp4(v, OP_MakeRecord, 3, 0, 0, "aaa", 0);
    sqlite3VdbeAddOp2(v, OP_Insert, iStatCur, OPFLAG_APPEND);
    sqlite3VdbeJumpHere(v, addr);
  }
}

/*
** Generate code that will cause the most recent index analysis to
** be laoded into internal hash tables where is can be used.







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
**    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.
**
*************************************************************************
** This file contains code associated with the ANALYZE command.
**
** @(#) $Id: analyze.c,v 1.29 2008/01/03 09:51:55 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_ANALYZE
#include "sqliteInt.h"

/*
** This routine generates code that opens the sqlite_stat1 table on cursor
** iStatCur.
................................................................................
      if( i==nCol-1 ){
        sqlite3VdbeAddOp1(v, OP_Concat, nCol*2-1);
      }else{
        sqlite3VdbeAddOp1(v, OP_Dup, 1);
      }
    }
    sqlite3VdbeAddOp4(v, OP_MakeRecord, 3, 0, 0, "aaa", 0);
    sqlite3CodeInsert(pParse, iStatCur, OPFLAG_APPEND);
    sqlite3VdbeJumpHere(v, addr);
  }
}

/*
** Generate code that will cause the most recent index analysis to
** be laoded into internal hash tables where is can be used.

Changes to src/build.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.454 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
    {
      sqlite3VdbeAddOp1(v, OP_CreateTable, iDb);
    }
    sqlite3OpenMasterTable(pParse, iDb);
    sqlite3VdbeAddOp0(v, OP_NewRowid);
    sqlite3VdbeAddOp0(v, OP_Dup);
    sqlite3VdbeAddOp0(v, OP_Null);
    sqlite3VdbeAddOp2(v, OP_Insert, 0, OPFLAG_APPEND);
    sqlite3VdbeAddOp0(v, OP_Close);
    sqlite3VdbeAddOp1(v, OP_Pull, 1);
  }

  /* Normal (non-error) return. */
  return;








|







 







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.455 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
    {
      sqlite3VdbeAddOp1(v, OP_CreateTable, iDb);
    }
    sqlite3OpenMasterTable(pParse, iDb);
    sqlite3VdbeAddOp0(v, OP_NewRowid);
    sqlite3VdbeAddOp0(v, OP_Dup);
    sqlite3VdbeAddOp0(v, OP_Null);
    sqlite3CodeInsert(pParse, 0, OPFLAG_APPEND);
    sqlite3VdbeAddOp0(v, OP_Close);
    sqlite3VdbeAddOp1(v, OP_Pull, 1);
  }

  /* Normal (non-error) return. */
  return;

Changes to src/delete.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
55
56
57
58
59
60
61














62
63
64
65
66
67
68
...
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
**    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
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.141 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
  if( !viewOk && pTab->pSelect ){
    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    return 1;
  }
#endif
  return 0;
}















/*
** Generate code that will open a table for reading.
*/
void sqlite3OpenTable(
  Parse *p,       /* Generate code into this VDBE */
  int iCur,       /* The cursor number of the table */
................................................................................
      sqlite3VdbeAddOp2(v, OP_NotExists, iCur, addr);
      sqlite3VdbeAddOp1(v, OP_Rowid, iCur);
      if( old_col_mask ){
        sqlite3VdbeAddOp1(v, OP_RowData, iCur);
      }else{
        sqlite3VdbeAddOp0(v, OP_Null);
      }
      sqlite3VdbeAddOp1(v, OP_Insert, oldIdx);

      /* Jump back and run the BEFORE triggers */
      sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
      sqlite3VdbeJumpHere(v, iEndBeforeTrigger);

      if( !isView ){
        sqlite3VdbeAddOp1(v, OP_MemLoad, mem1);







|







 







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







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
...
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
**    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
** in order to generate code for DELETE FROM statements.
**
** $Id: delete.c,v 1.142 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
  if( !viewOk && pTab->pSelect ){
    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    return 1;
  }
#endif
  return 0;
}

/*
** This function is a temporary measure required because OP_Insert now
** reads the key and data to insert from memory cells.
*/
void sqlite3CodeInsert(Parse *p, int iCur, u8 flags){
  int iData = p->nMem++;
  int iKey = p->nMem++;
  Vdbe *v = sqlite3GetVdbe(p);
  sqlite3VdbeAddOp2(v, OP_MemStore, iData, 1);
  sqlite3VdbeAddOp2(v, OP_MemStore, iKey, 1);
  sqlite3VdbeAddOp3(v, OP_Insert, iCur, iData, iKey);
  sqlite3VdbeChangeP5(v, sqlite3VdbeCurrentAddr(v)-1, flags);
}

/*
** Generate code that will open a table for reading.
*/
void sqlite3OpenTable(
  Parse *p,       /* Generate code into this VDBE */
  int iCur,       /* The cursor number of the table */
................................................................................
      sqlite3VdbeAddOp2(v, OP_NotExists, iCur, addr);
      sqlite3VdbeAddOp1(v, OP_Rowid, iCur);
      if( old_col_mask ){
        sqlite3VdbeAddOp1(v, OP_RowData, iCur);
      }else{
        sqlite3VdbeAddOp0(v, OP_Null);
      }
      sqlite3CodeInsert(pParse, oldIdx, 0);

      /* Jump back and run the BEFORE triggers */
      sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
      sqlite3VdbeJumpHere(v, iEndBeforeTrigger);

      if( !isView ){
        sqlite3VdbeAddOp1(v, OP_MemLoad, mem1);

Changes to src/insert.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
...
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
...
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
....
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
....
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
**    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.203 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
    sqlite3VdbeAddOp2(v, OP_MemLoad, memId-1, 0);
    sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+6);
    sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, 0);
    sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp2(v, OP_MemLoad, memId, 0);
    sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0);
    sqlite3VdbeAddOp2(v, OP_Insert, iCur, OPFLAG_APPEND);
    sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
  }
}
#else
/*
** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines
** above are all no-ops
................................................................................
      */
      srcTab = pParse->nTab++;
      sqlite3VdbeResolveLabel(v, iInsertBlock);
      sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0);
      sqlite3VdbeAddOp2(v, OP_MakeRecord, nColumn, 0);
      sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, 0);
      sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp2(v, OP_Insert, srcTab, OPFLAG_APPEND);
      sqlite3VdbeAddOp2(v, OP_Return, 0, 0);

      /* The following code runs first because the GOTO at the very top
      ** of the program jumps to it.  Create the temporary table, then jump
      ** back up and execute the SELECT code above.
      */
      sqlite3VdbeJumpHere(v, iInitCode);
................................................................................
    ** do not attempt any conversions before assembling the record.
    ** If this is a real table, attempt conversions as required by the
    ** table column affinities.
    */
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
    }
    sqlite3VdbeAddOp2(v, OP_Insert, newIdx, 0);

    /* Fire BEFORE or INSTEAD OF triggers */
    if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab, 
        newIdx, -1, onError, endOfLoop, 0, 0) ){
      goto insert_cleanup;
    }
  }
................................................................................
  }
  sqlite3VdbeAddOp2(v, OP_MakeRecord, pTab->nCol, 0);
  sqlite3TableAffinityStr(v, pTab);
#ifndef SQLITE_OMIT_TRIGGER
  if( newIdx>=0 ){
    sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
    sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
    sqlite3VdbeAddOp2(v, OP_Insert, newIdx, 0);
  }
#endif
  if( pParse->nested ){
    pik_flags = 0;
  }else{
    pik_flags = OPFLAG_NCHANGE;
    pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
  }
  if( appendBias ){
    pik_flags |= OPFLAG_APPEND;
  }
  sqlite3VdbeAddOp2(v, OP_Insert, base, pik_flags);
  if( !pParse->nested ){
    sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
  }
  
  if( isUpdate && rowidChng ){
    sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
  }
................................................................................
  }else if( pDest->pIndex==0 ){
    addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, 0);
  }else{
    addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0);
    assert( pDest->autoInc==0 );
  }
  sqlite3VdbeAddOp2(v, OP_RowData, iSrc, 0);
  sqlite3VdbeAddOp4(v, OP_Insert, iDest, 0,
                    OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND,
                    pDest->zName, 0);
  sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
  autoIncEnd(pParse, iDbDest, pDest, counterMem);
  for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
    for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
    }
    assert( pSrcIdx );







|







 







|







 







|







 







|







 







|











|







 







<
|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
...
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
...
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
....
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
....
1559
1560
1561
1562
1563
1564
1565

1566
1567
1568
1569
1570
1571
1572
1573
1574
**    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.204 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Set P4 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................
    sqlite3VdbeAddOp2(v, OP_MemLoad, memId-1, 0);
    sqlite3VdbeAddOp2(v, OP_NotNull, -1, addr+6);
    sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
    sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, 0);
    sqlite3VdbeAddOp4(v, OP_String8, 0, 0, 0, pTab->zName, 0);
    sqlite3VdbeAddOp2(v, OP_MemLoad, memId, 0);
    sqlite3VdbeAddOp2(v, OP_MakeRecord, 2, 0);
    sqlite3CodeInsert(pParse, iCur, OPFLAG_APPEND);
    sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
  }
}
#else
/*
** If SQLITE_OMIT_AUTOINCREMENT is defined, then the three routines
** above are all no-ops
................................................................................
      */
      srcTab = pParse->nTab++;
      sqlite3VdbeResolveLabel(v, iInsertBlock);
      sqlite3VdbeAddOp2(v, OP_StackDepth, -1, 0);
      sqlite3VdbeAddOp2(v, OP_MakeRecord, nColumn, 0);
      sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, 0);
      sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
      sqlite3CodeInsert(pParse, srcTab, OPFLAG_APPEND);
      sqlite3VdbeAddOp2(v, OP_Return, 0, 0);

      /* The following code runs first because the GOTO at the very top
      ** of the program jumps to it.  Create the temporary table, then jump
      ** back up and execute the SELECT code above.
      */
      sqlite3VdbeJumpHere(v, iInitCode);
................................................................................
    ** do not attempt any conversions before assembling the record.
    ** If this is a real table, attempt conversions as required by the
    ** table column affinities.
    */
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
    }
    sqlite3CodeInsert(pParse, newIdx, OPFLAG_APPEND);

    /* Fire BEFORE or INSTEAD OF triggers */
    if( sqlite3CodeRowTrigger(pParse, TK_INSERT, 0, TRIGGER_BEFORE, pTab, 
        newIdx, -1, onError, endOfLoop, 0, 0) ){
      goto insert_cleanup;
    }
  }
................................................................................
  }
  sqlite3VdbeAddOp2(v, OP_MakeRecord, pTab->nCol, 0);
  sqlite3TableAffinityStr(v, pTab);
#ifndef SQLITE_OMIT_TRIGGER
  if( newIdx>=0 ){
    sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
    sqlite3VdbeAddOp2(v, OP_Dup, 1, 0);
    sqlite3CodeInsert(pParse, newIdx, 0);
  }
#endif
  if( pParse->nested ){
    pik_flags = 0;
  }else{
    pik_flags = OPFLAG_NCHANGE;
    pik_flags |= (isUpdate?OPFLAG_ISUPDATE:OPFLAG_LASTROWID);
  }
  if( appendBias ){
    pik_flags |= OPFLAG_APPEND;
  }
  sqlite3CodeInsert(pParse, base, pik_flags);
  if( !pParse->nested ){
    sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
  }
  
  if( isUpdate && rowidChng ){
    sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
  }
................................................................................
  }else if( pDest->pIndex==0 ){
    addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, 0);
  }else{
    addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, 0);
    assert( pDest->autoInc==0 );
  }
  sqlite3VdbeAddOp2(v, OP_RowData, iSrc, 0);

  sqlite3CodeInsert(pParse,iDest,OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND);
  sqlite3VdbeChangeP4(v, -1, pDest->zName, 0);
  sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1);
  autoIncEnd(pParse, iDbDest, pDest, counterMem);
  for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
    for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
      if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
    }
    assert( pSrcIdx );

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
...
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
...
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
**    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 SELECT statements in SQLite.
**
** $Id: select.c,v 1.379 2008/01/03 07:54:24 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
    case SRT_EphemTab: {
      sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
      if( pOrderBy ){
        pushOntoSorter(pParse, pOrderBy, p);
      }else{
        sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, 0);
        sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
        sqlite3VdbeAddOp2(v, OP_Insert, iParm, OPFLAG_APPEND);
      }
      break;
    }

#ifndef SQLITE_OMIT_SUBQUERY
    /* If we are creating a set for an "expr IN (SELECT ...)" construct,
    ** then there should be a single item on the stack.  Write this
................................................................................
  }
  sqlite3VdbeAddOp2(v, OP_Column, iTab, pOrderBy->nExpr + 1);
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, 0);
      sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
      sqlite3VdbeAddOp2(v, OP_Insert, iParm, OPFLAG_APPEND);
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case SRT_Set: {
      assert( nColumn==1 );
      sqlite3VdbeAddOp2(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
................................................................................
      /* The LIMIT clause will terminate the loop for us */
      break;
    }
#endif
    case SRT_Callback:
    case SRT_Subroutine: {
      int i;
      sqlite3VdbeAddOp2(v, OP_Insert, pseudoTab, 0);
      for(i=0; i<nColumn; i++){
        sqlite3VdbeAddOp2(v, OP_Column, pseudoTab, i);
      }
      if( eDest==SRT_Callback ){
        sqlite3VdbeAddOp2(v, OP_Callback, nColumn, 0);
      }else{
        sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);







|







 







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
...
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
...
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
**    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 SELECT statements in SQLite.
**
** $Id: select.c,v 1.380 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Delete all the content of a Select structure but do not deallocate
** the select structure itself.
................................................................................
    case SRT_EphemTab: {
      sqlite3VdbeAddOp2(v, OP_RegMakeRec, iMem, 0);
      if( pOrderBy ){
        pushOntoSorter(pParse, pOrderBy, p);
      }else{
        sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, 0);
        sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
        sqlite3CodeInsert(pParse, iParm, OPFLAG_APPEND);
      }
      break;
    }

#ifndef SQLITE_OMIT_SUBQUERY
    /* If we are creating a set for an "expr IN (SELECT ...)" construct,
    ** then there should be a single item on the stack.  Write this
................................................................................
  }
  sqlite3VdbeAddOp2(v, OP_Column, iTab, pOrderBy->nExpr + 1);
  switch( eDest ){
    case SRT_Table:
    case SRT_EphemTab: {
      sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, 0);
      sqlite3VdbeAddOp2(v, OP_Pull, 1, 0);
      sqlite3CodeInsert(pParse, iParm, OPFLAG_APPEND);
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case SRT_Set: {
      assert( nColumn==1 );
      sqlite3VdbeAddOp2(v, OP_NotNull, -1, sqlite3VdbeCurrentAddr(v)+3);
      sqlite3VdbeAddOp2(v, OP_Pop, 1, 0);
................................................................................
      /* The LIMIT clause will terminate the loop for us */
      break;
    }
#endif
    case SRT_Callback:
    case SRT_Subroutine: {
      int i;
      sqlite3CodeInsert(pParse, pseudoTab, 0);
      for(i=0; i<nColumn; i++){
        sqlite3VdbeAddOp2(v, OP_Column, pseudoTab, i);
      }
      if( eDest==SRT_Callback ){
        sqlite3VdbeAddOp2(v, OP_Callback, nColumn, 0);
      }else{
        sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1914
1915
1916
1917
1918
1919
1920

1921
1922
1923
1924
1925
1926
1927
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.631 2008/01/03 00:01:25 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds
................................................................................
  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*));
int sqlite3ApiExit(sqlite3 *db, int);
int sqlite3OpenTempDatabase(Parse *);

void sqlite3StrAccumAppend(StrAccum*,const char*,int);
char *sqlite3StrAccumFinish(StrAccum*);
void sqlite3StrAccumReset(StrAccum*);



/*
** The interface to the LEMON-generated parser
*/
void *sqlite3ParserAlloc(void*(*)(size_t));
void sqlite3ParserFree(void*, void(*)(void*));







|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
....
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.632 2008/01/03 09:51:55 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_

/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds
................................................................................
  void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*));
int sqlite3ApiExit(sqlite3 *db, int);
int sqlite3OpenTempDatabase(Parse *);

void sqlite3StrAccumAppend(StrAccum*,const char*,int);
char *sqlite3StrAccumFinish(StrAccum*);
void sqlite3StrAccumReset(StrAccum*);
void sqlite3CodeInsert(Parse *, int, u8);


/*
** The interface to the LEMON-generated parser
*/
void *sqlite3ParserAlloc(void*(*)(size_t));
void sqlite3ParserFree(void*, void(*)(void*));

Changes to src/trigger.c.

233
234
235
236
237
238
239


240
241
242
243


244
245
246
247
248
249
250
251
252
253
254
255
256




257
258
259
260
261
262
263
      { OP_String8,    0, 0,  0          },  /* 2: trigger name */
      { OP_String8,    0, 0,  0          },  /* 3: table name */
      { OP_Integer,    0, 0,  0          },
      { OP_String8,    0, 0,  0          },  /* 5: "CREATE TRIGGER " */
      { OP_String8,    0, 0,  0          },  /* 6: SQL */
      { OP_Concat,     0, 0,  0          }, 
      { OP_MakeRecord, 5, 0,  0          },  /* 8: "aaada" */


      { OP_Insert,     0, 0,  0          },
    };
    int addr;
    Vdbe *v;



    /* Make an entry in the sqlite_master table */
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto triggerfinish_cleanup;
    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3OpenMasterTable(pParse, iDb);
    addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
    sqlite3VdbeChangeP4(v, addr+1, "trigger", P4_STATIC);
    sqlite3VdbeChangeP4(v, addr+2, pTrig->name, 0); 
    sqlite3VdbeChangeP4(v, addr+3, pTrig->table, 0);
    sqlite3VdbeChangeP4(v, addr+5, "CREATE TRIGGER ", P4_STATIC); 
    sqlite3VdbeChangeP4(v, addr+6, (char*)pAll->z, pAll->n);
    sqlite3VdbeChangeP4(v, addr+8, "aaada", P4_STATIC);




    sqlite3ChangeCookie(db, v, iDb);
    sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
    sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, sqlite3MPrintf(
        db, "type='trigger' AND name='%q'", pTrig->name), P4_DYNAMIC
    );
  }








>
>




>
>













>
>
>
>







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
      { OP_String8,    0, 0,  0          },  /* 2: trigger name */
      { OP_String8,    0, 0,  0          },  /* 3: table name */
      { OP_Integer,    0, 0,  0          },
      { OP_String8,    0, 0,  0          },  /* 5: "CREATE TRIGGER " */
      { OP_String8,    0, 0,  0          },  /* 6: SQL */
      { OP_Concat,     0, 0,  0          }, 
      { OP_MakeRecord, 5, 0,  0          },  /* 8: "aaada" */
      { OP_MemStore,   0, 1,  0          },  /* 9: Store data */
      { OP_MemStore,   0, 1,  0          },  /* 10: Store key */
      { OP_Insert,     0, 0,  0          },
    };
    int addr;
    Vdbe *v;
    int iKey = pParse->nMem++;
    int iData = pParse->nMem++;

    /* Make an entry in the sqlite_master table */
    v = sqlite3GetVdbe(pParse);
    if( v==0 ) goto triggerfinish_cleanup;
    sqlite3BeginWriteOperation(pParse, 0, iDb);
    sqlite3OpenMasterTable(pParse, iDb);
    addr = sqlite3VdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
    sqlite3VdbeChangeP4(v, addr+1, "trigger", P4_STATIC);
    sqlite3VdbeChangeP4(v, addr+2, pTrig->name, 0); 
    sqlite3VdbeChangeP4(v, addr+3, pTrig->table, 0);
    sqlite3VdbeChangeP4(v, addr+5, "CREATE TRIGGER ", P4_STATIC); 
    sqlite3VdbeChangeP4(v, addr+6, (char*)pAll->z, pAll->n);
    sqlite3VdbeChangeP4(v, addr+8, "aaada", P4_STATIC);
    sqlite3VdbeChangeP1(v, addr+9, iData);
    sqlite3VdbeChangeP2(v, addr+11, iData);
    sqlite3VdbeChangeP1(v, addr+10, iKey);
    sqlite3VdbeChangeP3(v, addr+11, iKey);
    sqlite3ChangeCookie(db, v, iDb);
    sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
    sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, sqlite3MPrintf(
        db, "type='trigger' AND name='%q'", pTrig->name), P4_DYNAMIC
    );
  }

Changes to src/update.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
...
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
**    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 UPDATE statements.
**
** $Id: update.c,v 1.151 2008/01/03 08:08:40 danielk1977 Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
................................................................................
    */
    sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
    if( !old_col_mask ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
    }else{
      sqlite3VdbeAddOp2(v, OP_RowData, iCur, 0);
    }
    sqlite3VdbeAddOp2(v, OP_Insert, oldIdx, 0);

    /* Generate the NEW table
    */
    if( chngRowid ){
      sqlite3ExprCodeAndCache(pParse, pRowidExpr);
    }else{
      sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
................................................................................
      }
    }
    sqlite3VdbeAddOp2(v, OP_MakeRecord, pTab->nCol, 0);
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
    }
    if( pParse->nErr ) goto update_cleanup;
    sqlite3VdbeAddOp2(v, OP_Insert, newIdx, 0);

    sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
    sqlite3VdbeJumpHere(v, iEndBeforeTrigger);

    if( !isView ){
      sqlite3VdbeAddOp2(v, OP_MemLoad, mem1, 0);
    }







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
...
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
**    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 UPDATE statements.
**
** $Id: update.c,v 1.152 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Forward declaration */
static void updateVirtualTable(
  Parse *pParse,       /* The parsing context */
................................................................................
    */
    sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
    if( !old_col_mask ){
      sqlite3VdbeAddOp2(v, OP_Null, 0, 0);
    }else{
      sqlite3VdbeAddOp2(v, OP_RowData, iCur, 0);
    }
    sqlite3CodeInsert(pParse, oldIdx, 0);

    /* Generate the NEW table
    */
    if( chngRowid ){
      sqlite3ExprCodeAndCache(pParse, pRowidExpr);
    }else{
      sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0);
................................................................................
      }
    }
    sqlite3VdbeAddOp2(v, OP_MakeRecord, pTab->nCol, 0);
    if( !isView ){
      sqlite3TableAffinityStr(v, pTab);
    }
    if( pParse->nErr ) goto update_cleanup;
    sqlite3CodeInsert(pParse, newIdx, 0);

    sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger);
    sqlite3VdbeJumpHere(v, iEndBeforeTrigger);

    if( !isView ){
      sqlite3VdbeAddOp2(v, OP_MemLoad, mem1, 0);
    }

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
....
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584


3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.667 2008/01/03 08:08:40 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
** The value extracted is pushed onto the stack.  Or if P3 is a positive
** non-zero integer register number, then the value is written into that
** register.
**
** If the KeyAsData opcode has previously executed on this cursor, then the
** field might be extracted from the key rather than the data.
**
** If the column contains fewer than P2 fields, then extract a NULL.  Or
** if the next instruction is OP_DfltValue then the P4 argument to the
** OP_DfltValue instruction will be a P4_MEM.  Use the P4 argument of
** the OP_DfltValue instruction as the extracted value instead of NULL.
** The OP_DfltValue P4 value will be a default value for a column 
** that has been added using the ALTER TABLE ADD COLUMN command.
*/
case OP_Column: {
  u32 payloadSize;   /* Number of bytes in the record */
  int p1 = pOp->p1;  /* P1 value of the opcode */
  int p2 = pOp->p2;  /* column number to retrieve */
  Cursor *pC = 0;    /* The VDBE cursor */
  char *zRec;        /* Pointer to complete record-data */
................................................................................
  }
  pTos++;
  pTos->u.i = v;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: Insert P1 P2 P4
**
** Write an entry into the table of cursor P1.  A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten.  The data is the value on the top of the
** stack.  The key is the next value down on the stack.  The key must
** be an integer.  The stack is popped twice by this instruction.
**
** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
** incremented (otherwise not).  If the OPFLAG_LASTROWID flag of P2 is set,
** then rowid is stored for subsequent return by the
** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
**
** Parameter P4 may point to a string containing the table-name, or
** may be NULL. If it is not NULL, then the update-hook 
** (sqlite3.xUpdateCallback) is invoked following a successful insert.
**
** This instruction only works on tables.  The equivalent instruction
** for indices is OP_IdxInsert.
*/
case OP_Insert: {         /* no-push */
  Mem *pNos = &pTos[-1];


  int i = pOp->p1;
  Cursor *pC;
  assert( pNos>=p->aStack );
  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
    i64 iKey;   /* The integer ROWID or key for the record to be inserted */

    assert( pNos->flags & MEM_Int );
    assert( pC->isTable );
    iKey = intToKey(pNos->u.i);

    if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
    if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->u.i;
    if( pC->nextRowidValid && pNos->u.i>=pC->nextRowid ){
      pC->nextRowidValid = 0;
    }
    if( pTos->flags & MEM_Null ){
      pTos->z = 0;
      pTos->n = 0;
    }else{
      assert( pTos->flags & (MEM_Blob|MEM_Str) );
    }
    if( pC->pseudoTable ){
      sqlite3_free(pC->pData);
      pC->iKey = iKey;
      pC->nData = pTos->n;
      if( pTos->flags & MEM_Dyn ){
        pC->pData = pTos->z;
        pTos->flags = MEM_Null;
      }else{
        pC->pData = sqlite3_malloc( pC->nData+2 );
        if( !pC->pData ) goto no_mem;
        memcpy(pC->pData, pTos->z, pC->nData);
        pC->pData[pC->nData] = 0;
        pC->pData[pC->nData+1] = 0;
      }
      pC->nullRow = 0;
    }else{
      int nZero;
      if( pTos->flags & MEM_Zero ){
        nZero = pTos->u.i;
      }else{
        nZero = 0;
      }
      rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
                              pTos->z, pTos->n, nZero,
                              pOp->p2 & OPFLAG_APPEND);
    }
    
    pC->rowidIsValid = 0;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;

    /* Invoke the update-hook if required. */
    if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.p ){
      const char *zDb = db->aDb[pC->iDb].zName;
      const char *zTbl = pOp->p4.p;
      int op = ((pOp->p2 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
      assert( pC->isTable );
      db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
      assert( pC->iDb>=0 );
    }
  }
  popStack(&pTos, 2);

  break;
}

/* Opcode: Delete P1 P2 P4
**
** Delete the record at which the P1 cursor is currently pointing.







|







 







|
|
|
<
<
<







 







|



|
|
|

|
|











|
>
>


<





|

|

|
|
|


|
|
|

|




|
|
|
|



|






|
|




|
|










|





<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048



2049
2050
2051
2052
2053
2054
2055
....
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585

3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646

3647
3648
3649
3650
3651
3652
3653
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.668 2008/01/03 09:51:55 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
................................................................................
** The value extracted is pushed onto the stack.  Or if P3 is a positive
** non-zero integer register number, then the value is written into that
** register.
**
** If the KeyAsData opcode has previously executed on this cursor, then the
** field might be extracted from the key rather than the data.
**
** If the column contains fewer than P2 fields, then extract a NULL.  Or,
** if the P4 argument is a P4_MEM use the value of the P4 argument as
** the result.



*/
case OP_Column: {
  u32 payloadSize;   /* Number of bytes in the record */
  int p1 = pOp->p1;  /* P1 value of the opcode */
  int p2 = pOp->p2;  /* column number to retrieve */
  Cursor *pC = 0;    /* The VDBE cursor */
  char *zRec;        /* Pointer to complete record-data */
................................................................................
  }
  pTos++;
  pTos->u.i = v;
  pTos->flags = MEM_Int;
  break;
}

/* Opcode: Insert P1 P2 P3 P4 P5
**
** Write an entry into the table of cursor P1.  A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten.  The data is the value stored register
** number P2. The key is stored in register P3. The key must
** be an integer.
**
** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is
** incremented (otherwise not).  If the OPFLAG_LASTROWID flag of P5 is set,
** then rowid is stored for subsequent return by the
** sqlite3_last_insert_rowid() function (otherwise it is unmodified).
**
** Parameter P4 may point to a string containing the table-name, or
** may be NULL. If it is not NULL, then the update-hook 
** (sqlite3.xUpdateCallback) is invoked following a successful insert.
**
** This instruction only works on tables.  The equivalent instruction
** for indices is OP_IdxInsert.
*/
case OP_Insert: {         /* no-push */
  Mem *pData = &p->aMem[pOp->p2];
  Mem *pKey = &p->aMem[pOp->p3];

  int i = pOp->p1;
  Cursor *pC;

  assert( i>=0 && i<p->nCursor );
  assert( p->apCsr[i]!=0 );
  if( ((pC = p->apCsr[i])->pCursor!=0 || pC->pseudoTable) ){
    i64 iKey;   /* The integer ROWID or key for the record to be inserted */

    assert( pKey->flags & MEM_Int );
    assert( pC->isTable );
    iKey = intToKey(pKey->u.i);

    if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
    if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = pKey->u.i;
    if( pC->nextRowidValid && pKey->u.i>=pC->nextRowid ){
      pC->nextRowidValid = 0;
    }
    if( pData->flags & MEM_Null ){
      pData->z = 0;
      pData->n = 0;
    }else{
      assert( pData->flags & (MEM_Blob|MEM_Str) );
    }
    if( pC->pseudoTable ){
      sqlite3_free(pC->pData);
      pC->iKey = iKey;
      pC->nData = pData->n;
      if( pData->flags & MEM_Dyn ){
        pC->pData = pData->z;
        pData->flags = MEM_Null;
      }else{
        pC->pData = sqlite3_malloc( pC->nData+2 );
        if( !pC->pData ) goto no_mem;
        memcpy(pC->pData, pData->z, pC->nData);
        pC->pData[pC->nData] = 0;
        pC->pData[pC->nData+1] = 0;
      }
      pC->nullRow = 0;
    }else{
      int nZero;
      if( pData->flags & MEM_Zero ){
        nZero = pData->u.i;
      }else{
        nZero = 0;
      }
      rc = sqlite3BtreeInsert(pC->pCursor, 0, iKey,
                              pData->z, pData->n, nZero,
                              pOp->p5 & OPFLAG_APPEND);
    }
    
    pC->rowidIsValid = 0;
    pC->deferredMoveto = 0;
    pC->cacheStatus = CACHE_STALE;

    /* Invoke the update-hook if required. */
    if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.p ){
      const char *zDb = db->aDb[pC->iDb].zName;
      const char *zTbl = pOp->p4.p;
      int op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
      assert( pC->isTable );
      db->xUpdateCallback(db->pUpdateArg, op, zDb, zTbl, iKey);
      assert( pC->iDb>=0 );
    }
  }


  break;
}

/* Opcode: Delete P1 P2 P4
**
** Delete the record at which the P1 cursor is currently pointing.

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
129
130
131
132
133
134
135
136

137
138
139
140
141
142
143
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.120 2008/01/03 07:54:24 danielk1977 Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
int sqlite3VdbeAddOp1(Vdbe*,int,int);
int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, int addr, int P2);

void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeUsesBtree(Vdbe*, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);







|







 







|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.121 2008/01/03 09:51:55 danielk1977 Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
int sqlite3VdbeAddOp1(Vdbe*,int,int);
int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int);
int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int);
int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, int addr, u8 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr, int N);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeUsesBtree(Vdbe*, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);

Changes to src/vdbeaux.c.

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449










450
451
452
453
454
455
456
  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p2 = val;
  }
}

/*
** Change the value of the P2 operand for a specific instruction.
** This routine is useful for setting a jump destination.
*/
void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p3 = val;
  }
}











/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
  sqlite3VdbeChangeP2(p, addr, p->nOp);







|
<







>
>
>
>
>
>
>
>
>
>







434
435
436
437
438
439
440
441

442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p2 = val;
  }
}

/*
** Change the value of the P3 operand for a specific instruction.

*/
void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){
  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p3 = val;
  }
}

/*
** Change the value of the P3 operand for a specific instruction.
*/
void sqlite3VdbeChangeP5(Vdbe *p, int addr, u8 val){
  assert( p==0 || p->magic==VDBE_MAGIC_INIT );
  if( p && addr>=0 && p->nOp>addr && p->aOp ){
    p->aOp[addr].p5 = val;
  }
}

/*
** Change the P2 operand of instruction addr so that it points to
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
  sqlite3VdbeChangeP2(p, addr, p->nOp);