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 |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
46501f490a5f5577ea31c758df749e02 |
User & Date: | danielk1977 2008-01-03 09:51:55.000 |
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: 7e8330c804 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: 46501f490a user: danielk1977 tags: trunk) | |
08:18 | Change the output of vdbe_trace etc. to include operands p3 and p5. (CVS 4665) (check-in: 76f2040b05 user: danielk1977 tags: trunk) | |
Changes
Changes to src/analyze.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2005 July 8 ** ** 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. ** ************************************************************************* ** This file contains code associated with the ANALYZE command. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2005 July 8 ** ** 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. ** ************************************************************************* ** 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. |
︙ | ︙ | |||
208 209 210 211 212 213 214 | 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); | | | 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | 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 | ** CREATE INDEX ** DROP INDEX ** creating ID lists ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** | | | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ** 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. |
︙ | ︙ | |||
879 880 881 882 883 884 885 | { sqlite3VdbeAddOp1(v, OP_CreateTable, iDb); } sqlite3OpenMasterTable(pParse, iDb); sqlite3VdbeAddOp0(v, OP_NewRowid); sqlite3VdbeAddOp0(v, OP_Dup); sqlite3VdbeAddOp0(v, OP_Null); | | | 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 | { 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 | ** 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. ** | | | 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 ** 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. |
︙ | ︙ | |||
55 56 57 58 59 60 61 62 63 64 65 66 67 68 | 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 */ | > > > > > > > > > > > > > > | 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 | 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 */ |
︙ | ︙ | |||
321 322 323 324 325 326 327 | 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); } | | | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | 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 | ** 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. ** | | | 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.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: |
︙ | ︙ | |||
217 218 219 220 221 222 223 | 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); | | | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | 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 |
︙ | ︙ | |||
507 508 509 510 511 512 513 | */ 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); | | | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 | */ 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); |
︙ | ︙ | |||
697 698 699 700 701 702 703 | ** 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); } | | | 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 | ** 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; } } |
︙ | ︙ | |||
1227 1228 1229 1230 1231 1232 1233 | } 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); | | | | 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 | } 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); } |
︙ | ︙ | |||
1559 1560 1561 1562 1563 1564 1565 | }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); | < | | | 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 | }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 | ** 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. ** | | | 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 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. |
︙ | ︙ | |||
609 610 611 612 613 614 615 | 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); | | | 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 | 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 |
︙ | ︙ | |||
787 788 789 790 791 792 793 | } 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); | | | 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 | } 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); |
︙ | ︙ | |||
810 811 812 813 814 815 816 | /* The LIMIT clause will terminate the loop for us */ break; } #endif case SRT_Callback: case SRT_Subroutine: { int i; | | | 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 | /* 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** Internal interface definitions for SQLite. ** | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | /* ** 2001 September 15 ** ** 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. ** ************************************************************************* ** 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 |
︙ | ︙ | |||
1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 | 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*)); | > | 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 | 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 | ** 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. ** | | | 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 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 */ |
︙ | ︙ | |||
406 407 408 409 410 411 412 | */ sqlite3VdbeAddOp2(v, OP_Rowid, iCur, 0); if( !old_col_mask ){ sqlite3VdbeAddOp2(v, OP_Null, 0, 0); }else{ sqlite3VdbeAddOp2(v, OP_RowData, iCur, 0); } | | | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | */ 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); |
︙ | ︙ | |||
437 438 439 440 441 442 443 | } } sqlite3VdbeAddOp2(v, OP_MakeRecord, pTab->nCol, 0); if( !isView ){ sqlite3TableAffinityStr(v, pTab); } if( pParse->nErr ) goto update_cleanup; | | | 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 | } } 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 | ** ** 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. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** 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 |
︙ | ︙ | |||
2039 2040 2041 2042 2043 2044 2045 | ** 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. ** | | | < | < < | 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 | ** 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 */ |
︙ | ︙ | |||
3556 3557 3558 3559 3560 3561 3562 | } pTos++; pTos->u.i = v; pTos->flags = MEM_Int; break; } | | | | | | | > > | < | | | | | | | | | | | | | | | | | | | < | 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 | } 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 | ************************************************************************* ** 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. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** 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 |
︙ | ︙ | |||
129 130 131 132 133 134 135 | 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); | | > | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | 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 | assert( p==0 || p->magic==VDBE_MAGIC_INIT ); if( p && addr>=0 && p->nOp>addr && p->aOp ){ p->aOp[addr].p2 = val; } } /* | | < > > > > > > > > > > | 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); |
︙ | ︙ |