Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fixes for new triggers scheme. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
9eb91efda5241609ff18ff15ef5eaa0e |
User & Date: | dan 2009-08-30 11:42:52.000 |
Context
2009-08-31
| ||
05:23 | Fix another test problem and some instances where an OOM may cause a segfault. (check-in: 31199db0f7 user: dan tags: trunk) | |
2009-08-30
| ||
11:42 | Fixes for new triggers scheme. (check-in: 9eb91efda5 user: dan tags: trunk) | |
2009-08-28
| ||
18:53 | Changes to support recursive triggers. (check-in: 9b9c192115 user: dan tags: trunk) | |
Changes
Changes to src/delete.c.
︙ | |||
404 405 406 407 408 409 410 411 412 413 414 | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 | + + + - + - + | sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid); /* Populate the OLD.* pseudo-table */ assert( regOld==iRowid+1 ); for(i=0; i<pTab->nCol; i++){ if( mask==0xffffffff || mask&(1<<i) ){ sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regOld+i); sqlite3ColumnDefault(v, pTab, i, regOld+i); } } sqlite3VdbeAddOp2(v, OP_Affinity, regOld, pTab->nCol); sqlite3TableAffinityStr(v, pTab); sqlite3CodeRowTrigger(pParse, pTrigger, |
︙ |
Changes to src/expr.c.
︙ | |||
86 87 88 89 90 91 92 | 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | + - + + | CollSeq *pColl = 0; Expr *p = pExpr; while( ALWAYS(p) ){ int op; pColl = p->pColl; if( pColl ) break; op = p->op; if( p->pTab!=0 && ( |
︙ | |||
2553 2554 2555 2556 2557 2558 2559 | 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 | + - + - - + - + + | } case TK_UPLUS: { inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); break; } case TK_TRIGGER: { int iVal = pExpr->iTable * (pExpr->pTab->nCol+1) + 1 + pExpr->iColumn; |
︙ |
Changes to src/insert.c.
︙ | |||
193 194 195 196 197 198 199 200 201 | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | + - + - - + + - - - + + + + + + | static int autoIncBegin( Parse *pParse, /* Parsing context */ int iDb, /* Index of the database holding pTab */ Table *pTab /* The table we are writing to */ ){ int memId = 0; /* Register holding maximum rowid */ if( pTab->tabFlags & TF_Autoincrement ){ Parse *pRoot = (pParse->pRoot ? pParse->pRoot : pParse); AutoincInfo *pInfo; |
︙ | |||
801 802 803 804 805 806 807 | 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 | - - + - - + - + - + - - + + - + - - + - + - + - + - + - - + | } regData = regRowid+1; /* Run the BEFORE and INSTEAD OF triggers, if there are any */ endOfLoop = sqlite3VdbeMakeLabel(v); if( tmask & TRIGGER_BEFORE ){ |
︙ | |||
990 991 992 993 994 995 996 | 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 | - + | if( (db->flags & SQLITE_CountRows)!=0 ){ sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); } if( pTrigger ){ /* Code AFTER triggers */ sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, |
︙ | |||
1149 1150 1151 1152 1153 1154 1155 | 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 | - | v = sqlite3GetVdbe(pParse); assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ nCol = pTab->nCol; regData = regRowid + 1; |
︙ | |||
1225 1226 1227 1228 1229 1230 1231 | 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 | - + | onError = overrideError; }else if( onError==OE_Default ){ onError = OE_Abort; } if( onError!=OE_Replace || pTab->pIndex ){ if( isUpdate ){ |
︙ |
Changes to src/main.c.
︙ | |||
1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 | 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 | + + + | db->nextPagesize = 0; db->flags |= SQLITE_ShortColNames #if SQLITE_DEFAULT_FILE_FORMAT<4 | SQLITE_LegacyFileFmt #endif #ifdef SQLITE_ENABLE_LOAD_EXTENSION | SQLITE_LoadExtension #endif #ifdef SQLITE_DISABLE_RECURSIVE_TRIGGERS | SQLITE_NoRecTriggers #endif ; sqlite3HashInit(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3HashInit(&db->aModule); #endif |
︙ |
Changes to src/pragma.c.
︙ | |||
186 187 188 189 190 191 192 193 194 195 196 197 198 199 | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | + | /* The following is VERY experimental */ { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode }, { "omit_readlock", SQLITE_NoReadlock }, /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted ** flag if there are any active statements. */ { "read_uncommitted", SQLITE_ReadUncommitted }, { "disable_recursive_triggers", SQLITE_NoRecTriggers }, }; int i; const struct sPragmaType *p; for(i=0, p=aPragma; i<ArraySize(aPragma); i++, p++){ if( sqlite3StrICmp(zLeft, p->zName)==0 ){ sqlite3 *db = pParse->db; Vdbe *v; |
︙ |
Changes to src/sqliteInt.h.
︙ | |||
907 908 909 910 911 912 913 914 915 916 917 918 919 920 | 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 | + | #define SQLITE_ReadUncommitted 0x00004000 /* For shared-cache mode */ #define SQLITE_LegacyFileFmt 0x00008000 /* Create new databases in format 1 */ #define SQLITE_FullFSync 0x00010000 /* Use full fsync on the backend */ #define SQLITE_LoadExtension 0x00020000 /* Enable load_extension */ #define SQLITE_RecoveryMode 0x00040000 /* Ignore schema errors */ #define SQLITE_ReverseOrder 0x00100000 /* Reverse unordered SELECTs */ #define SQLITE_NoRecTriggers 0x00200000 /* Disable recursive triggers */ /* ** Possible values for the sqlite.magic field. ** The numbers are obtained at random and have no special meaning, other ** than being distinct from one another. */ #define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */ |
︙ |
Changes to src/trigger.c.
︙ | |||
693 694 695 696 697 698 699 700 701 702 703 704 705 706 | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 | + + + + | ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b); ** END; ** ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy */ pParse->orconf = (orconfin==OE_Default)?pStep->orconf:orconfin; if( pStep->op!=TK_SELECT ){ sqlite3VdbeAddOp1(v, OP_ResetCount, 0); } switch( pStep->op ){ case TK_UPDATE: { sqlite3Update(pParse, targetSrcList(pParse, pStep), sqlite3ExprListDup(db, pStep->pExprList, 0), sqlite3ExprDup(db, pStep->pWhere, 0), |
︙ | |||
730 731 732 733 734 735 736 737 738 739 740 741 742 743 | 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 | + + + | Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0); sqlite3SelectDestInit(&sDest, SRT_Discard, 0); sqlite3Select(pParse, pSelect, &sDest); sqlite3SelectDelete(db, pSelect); break; } } if( pStep->op!=TK_SELECT ){ sqlite3VdbeAddOp1(v, OP_ResetCount, 1); } pStep = pStep->pNext; } /* sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0); */ return 0; } |
︙ | |||
814 815 816 817 818 819 820 | 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 | + - + - + + + + + + - + + + | pSubParse->pRoot = pRoot; /* Push an entry on to the auth context stack */ sqlite3AuthContextPush(pParse, &sContext, pTrigger->name); v = sqlite3GetVdbe(pSubParse); if( v ){ VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", |
︙ | |||
957 958 959 960 961 962 963 | 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 | - + - + | CodedTrigger *pC; pC = getRowTrigger(pParse, p, op, pTab, orconf); assert( pC || pParse->nErr || pParse->db->mallocFailed ); /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program ** is a pointer to the sub-vdbe containing the trigger program. */ if( pC ){ |
︙ |
Changes to src/update.c.
︙ | |||
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | + - + | /* Register Allocations */ int regRowCount = 0; /* A count of rows changed */ int regOldRowid; /* The old rowid */ int regNewRowid; /* The new rowid */ int regNew; int regOld; int regRowSet = 0; /* Rowset of rows to be updated */ int regRec; /* Register used for new table record to insert */ memset(&sContext, 0, sizeof(sContext)); db = pParse->db; if( pParse->nErr || db->mallocFailed ){ goto update_cleanup; } assert( pTabList->nSrc==1 ); /* Locate the table which we want to update. */ pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ) goto update_cleanup; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); /* Figure out if we have any triggers and if the table being |
︙ | |||
278 279 280 281 282 283 284 285 286 287 288 289 290 291 | 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | + | pParse->nMem += pTab->nCol; } if( chngRowid || pTrigger ){ regNewRowid = ++pParse->nMem; } regNew = pParse->nMem + 1; pParse->nMem += pTab->nCol; regRec = ++pParse->nMem; /* Start the view context. */ if( isView ){ sqlite3AuthContextPush(pParse, &sContext, pTab->zName); } /* If there are any triggers, set old_col_mask and new_col_mask. */ |
︙ | |||
416 417 418 419 420 421 422 423 424 425 426 | 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 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 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | + + + + + + + + + + + + + - + - + - - + + + + + + + + + + + + + + + - + | sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i); sqlite3ColumnDefault(v, pTab, i, regNew+i); }else{ sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i); } } } /* If this is not a view, create the record that will be inserted into ** the table (assuming no constraint checks fail). A side effect of ** creating the record is applying affinity transformations to the ** array of registers populated by the block above. This needs to be ** done before the BEFORE triggers are fired. */ #if 0 if( !isView ){ sqlite3VdbeAddOp3(v, OP_MakeRecord, regNew, pTab->nCol, regRec); sqlite3TableAffinityStr(v, pTab); sqlite3ExprCacheAffinityChange(pParse, regNew, pTab->nCol); } #endif /* Fire any BEFORE UPDATE triggers. This happens before constraints are ** verified. One could argue that this is wrong. */ sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, |
︙ |
Changes to src/vdbe.c.
︙ | |||
848 849 850 851 852 853 854 855 856 857 858 859 860 861 | 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 | + | case OP_Halt: { if( pOp->p1==SQLITE_OK && p->pFrame ){ VdbeFrame *pFrame = p->pFrame; p->pFrame = pFrame->pParent; p->nFrame--; pc = sqlite3VdbeFrameRestore(pFrame); if( pOp->p2==OE_Ignore ){ pc = p->aOp[pc].p2-1; } break; } p->rc = pOp->p1; p->errorAction = (u8)pOp->p2; p->pc = pc; if( pOp->p4.z ){ |
︙ | |||
3542 3543 3544 3545 3546 3547 3548 | 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 | - - - - - + + + + + + | /* Opcode: NewRowid P1 P2 P3 * * ** ** Get a new integer record number (a.k.a "rowid") used as the key to a table. ** The record number is not previously used as a key in the database ** table that cursor P1 points to. The new record number is written ** written to register P2. ** |
︙ | |||
3613 3614 3615 3616 3617 3618 3619 | 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 | + + - - - + + + + + + + + | v++; } } } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 ){ if( p->pFrame ){ for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); |
︙ | |||
4736 4737 4738 4739 4740 4741 4742 | 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 | - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - - + + + + - - - - - + + - - + - - + + + - + | sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); } break; } #ifndef SQLITE_OMIT_TRIGGER |
︙ | |||
4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 | 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 | + + - + + - - - + + + + - - - + - - - - + + - - - + + + - - - + + - - + + - + + + + + + + + + | assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem ); assert( pProgram->nCsr==pFrame->nChildCsr ); assert( pc==pFrame->pc ); } p->nFrame++; pFrame->pParent = p->pFrame; pFrame->lastRowid = db->lastRowid; pFrame->nChange = p->nChange; p->pFrame = pFrame; p->aMem = &VdbeFrameMem(pFrame)[-1]; p->nMem = pFrame->nChildMem; p->nCursor = pFrame->nChildCsr; p->apCsr = (VdbeCursor **)&p->aMem[p->nMem+1]; p->aOp = pProgram->aOp; p->nOp = pProgram->nOp; pc = -1; break; } |
︙ |
Changes to src/vdbeInt.h.
︙ | |||
99 100 101 102 103 104 105 106 107 108 109 110 111 112 | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | + + | int nMem; /* Number of entries in aMem */ VdbeCursor **apCsr; /* Element of Vdbe cursors */ u16 nCursor; /* Number of entries in apCsr */ VdbeFrame *pParent; /* Parent of this frame */ void *token; /* Copy of SubProgram.token */ int nChildMem; /* Number of memory cells for child frame */ int nChildCsr; /* Number of cursors for child frame */ i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ int nChange; /* Statement changes (Vdbe.nChanges) */ }; #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) /* ** A value for VdbeCursor.cacheValid that means the cache is always invalid. */ |
︙ | |||
239 240 241 242 243 244 245 | 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | - - - - - - - - - - - - - - - | */ typedef struct Set Set; struct Set { Hash hash; /* A set is just a hash table */ HashElem *prev; /* Previously accessed hash elemen */ }; |
︙ | |||
293 294 295 296 297 298 299 | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | - - - | u16 nVar; /* Number of entries in aVar[] */ Mem *aVar; /* Values for the OP_Variable opcode. */ char **azVar; /* Name of variables */ u32 magic; /* Magic number for sanity checking */ int nMem; /* Number of memory locations currently allocated */ Mem *aMem; /* The memory locations */ int cacheCtr; /* VdbeCursor row cache generation counter */ |
︙ |
Changes to src/vdbeaux.c.
︙ | |||
291 292 293 294 295 296 297 | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | - + | hasStatementBegin = 1; p->usesStmtJournal = 1; }else if( opcode==OP_Destroy ){ doesStatementRollback = 1; }else if( opcode==OP_Transaction && pOp->p2!=0 ){ p->readOnly = 0; #ifndef SQLITE_OMIT_VIRTUALTABLE |
︙ | |||
1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 | 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 | + + | Vdbe *v = pFrame->v; v->aOp = pFrame->aOp; v->nOp = pFrame->nOp; v->aMem = pFrame->aMem; v->nMem = pFrame->nMem; v->apCsr = pFrame->apCsr; v->nCursor = pFrame->nCursor; v->db->lastRowid = pFrame->lastRowid; v->nChange = pFrame->nChange; return pFrame->pc; } /* ** Close all cursors. ** ** Also release any dynamic memory held by the VM in the Vdbe.aMem memory |
︙ | |||
1383 1384 1385 1386 1387 1388 1389 | 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 | - - - - - - | /* Execute assert() statements to ensure that the Vdbe.apCsr[] and ** Vdbe.aMem[] arrays have already been cleaned up. */ int i; for(i=0; i<p->nCursor; i++){ assert( p->apCsr[i]==0 ); } for(i=1; i<=p->nMem; i++){ assert( p->aMem[i].flags==MEM_Null ); } #endif |
︙ |
Changes to test/autoinc.test.
︙ | |||
553 554 555 556 557 558 559 560 561 562 563 564 565 566 | 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 | + + | INSERT INTO t2 VALUES(NULL, 1); CREATE TABLE t3(a INTEGER PRIMARY KEY AUTOINCREMENT, b); INSERT INTO t3 SELECT * FROM t2 WHERE y>1; SELECT * FROM sqlite_sequence WHERE name='t3'; } } {t3 0} catchsql { pragma disable_recursive_triggers = 1 } # Ticket #3928. Make sure that triggers to not make extra slots in # the SQLITE_SEQUENCE table. # do_test autoinc-3928.1 { db eval { CREATE TABLE t3928(a INTEGER PRIMARY KEY AUTOINCREMENT, b); |
︙ |
Changes to test/misc2.test.
︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | + + + + + | # left out of other test files. # # $Id: misc2.test,v 1.28 2007/09/12 17:01:45 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # The tests in this file were written before SQLite supported recursive # trigger invocation, and some tests depend on that to pass. So disable # recursive triggers for this file. catchsql { pragma disable_recursive_triggers = 1 } ifcapable {trigger} { # Test for ticket #360 # do_test misc2-1.1 { catchsql { CREATE TABLE FOO(bar integer); CREATE TRIGGER foo_insert BEFORE INSERT ON foo BEGIN |
︙ | |||
354 355 356 357 358 359 360 361 362 363 364 365 366 367 | 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 | + | execsql {SELECT * FROM t1} } {1 2 3 4 5 6 7 8 9 10} } db close file delete -force test.db sqlite3 db test.db catchsql { pragma disable_recursive_triggers = 1 } # Ticket #453. If the SQL ended with "-", the tokenizer was calling that # an incomplete token, which caused problem. The solution was to just call # it a minus sign. # do_test misc2-8.1 { catchsql {-} |
︙ |
Changes to test/tkt3731.test.
︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | + + + + + | set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!trigger} { finish_test return } # The tests in this file were written before SQLite supported recursive # trigger invocation, and some tests depend on that to pass. So disable # recursive triggers for this file. catchsql { pragma disable_recursive_triggers = 1 } do_test tkt3731-1.1 { execsql { CREATE TABLE t1(a PRIMARY KEY, b); CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN INSERT INTO t1 VALUES(new.a || '+', new.b || '+'); END; |
︙ |
Changes to test/tkt3992.test.
︙ | |||
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | + + + + + | CREATE TABLE parameters2( mountcnt INT NOT NULL CHECK (typeof(mountcnt) == 'integer'), version REAL CHECK (typeof(version) == 'real') ); INSERT INTO parameters2(mountcnt, version) VALUES(1, 1.0); } } {} puts [execsql { SELECT *,typeof(mountcnt),typeof(version) FROM parameters1 }] do_test tkt3992-1.2 { execsql { UPDATE parameters1 SET mountcnt = mountcnt + 1; SELECT * FROM parameters1; } } {2 1.0} do_test tkt3992-1.3 { explain { UPDATE parameters2 SET mountcnt = mountcnt + 1 } breakpoint execsql { pragma vdbe_trace = 1; UPDATE parameters2 SET mountcnt = mountcnt + 1; pragma vdbe_trace = 0; SELECT * FROM parameters2; } } {2 1.0} do_test tkt3992-2.1 { execsql { CREATE TABLE t1(a, b); |
︙ | |||
68 69 70 71 72 73 74 | 73 74 75 76 77 78 79 80 81 82 | - - - | SELECT tcl('set res', typeof(new.c)); END; UPDATE t2 SET a = 'I'; } set res } {real} |
Changes to test/trigger2.test.
︙ | |||
49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | + + + + + | set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!trigger} { finish_test return } # The tests in this file were written before SQLite supported recursive # trigger invocation, and some tests depend on that to pass. So disable # recursive triggers for this file. catchsql { pragma disable_recursive_triggers = 1 } # 1. ifcapable subquery { set ii 0 set tbl_definitions [list \ {CREATE TABLE tbl (a, b);} \ {CREATE TABLE tbl (a INTEGER PRIMARY KEY, b);} \ |
︙ |
Changes to test/trigger3.test.
︙ | |||
13 14 15 16 17 18 19 20 21 | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | + + + + + - - - + + | set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable {!trigger} { finish_test return } # The tests in this file were written before SQLite supported recursive } # trigger invocation, and some tests depend on that to pass. So disable # recursive triggers for this file. catchsql { pragma disable_recursive_triggers = 1 } # Test that we can cause ROLLBACK, FAIL and ABORT correctly |
︙ | |||
50 51 52 53 54 55 56 | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | - + | do_test trigger3-1.3 { execsql {SELECT * FROM tbl} } {} # FAIL do_test trigger3-2.1 { catchsql { |
︙ |
Changes to test/trigger9.test.
︙ | |||
71 72 73 74 75 76 77 | 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 100 | - + - + | END; DELETE FROM t1; SELECT * FROM t2; } } {1 2 3} do_test trigger9-1.3.2 { has_rowdata {DELETE FROM t1} |
︙ | |||
116 117 118 119 120 121 122 | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | - + - + | END; UPDATE t1 SET y = ''; SELECT * FROM t2; } } {1 2 3} do_test trigger9-1.6.2 { has_rowdata {UPDATE t1 SET y = ''} |
︙ |