Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch one-writable-btree Excluding Merge-Ins
This is equivalent to a diff from e7d2ec048c to 58cc257aeb
2015-01-29
| ||
15:53 | Improvements to the DELETE code generator for the one-pass case. Avoid some OP_Goto instructions. Read content from the index cursor if the index cursor is valid and was used to locate the row that is to be deleted. (Closed-Leaf check-in: 58cc257aeb user: drh tags: one-writable-btree) | |
14:48 | Avoid overlength command lines in Makefile.msc when using TOP= with a large directory name. (check-in: 0cdd59bf36 user: drh tags: one-writable-btree) | |
11:52 | Optimize range constraints on the rowid column of fts3/4 tables even if there is no MATCH clause in the query. (check-in: 85dc12625d user: dan tags: trunk) | |
02:26 | Experimental sqlite_db_config() setting to disable writing to all btrees except for one btree with a particular root page. (check-in: 2305411097 user: drh tags: one-writable-btree) | |
2015-01-28
| ||
12:00 | Merge in all changes from trunk. (check-in: 17c69be805 user: drh tags: ota-update) | |
2015-01-27
| ||
21:24 | Fix harmless compiler warnings. (check-in: e7d2ec048c user: mistachkin tags: trunk) | |
19:01 | Fix a bug in the fts3 snippet() function causing it to omit leading separator characters from snippets that begin with the first token in a column. (check-in: adc9283dd9 user: dan tags: trunk) | |
Changes to Makefile.msc.
︙ | ︙ | |||
710 711 712 713 714 715 716 | LIBRESOBJS = sqlite3res.lo !ELSE LIBRESOBJS = !ENDIF # All of the source code files. # | | | 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 | LIBRESOBJS = sqlite3res.lo !ELSE LIBRESOBJS = !ENDIF # All of the source code files. # SRC1 = \ $(TOP)\src\alter.c \ $(TOP)\src\analyze.c \ $(TOP)\src\attach.c \ $(TOP)\src\auth.c \ $(TOP)\src\backup.c \ $(TOP)\src\bitvec.c \ $(TOP)\src\btmutex.c \ |
︙ | ︙ | |||
760 761 762 763 764 765 766 | $(TOP)\src\notify.c \ $(TOP)\src\os.c \ $(TOP)\src\os.h \ $(TOP)\src\os_common.h \ $(TOP)\src\os_setup.h \ $(TOP)\src\os_unix.c \ $(TOP)\src\os_win.c \ | | > | 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 | $(TOP)\src\notify.c \ $(TOP)\src\os.c \ $(TOP)\src\os.h \ $(TOP)\src\os_common.h \ $(TOP)\src\os_setup.h \ $(TOP)\src\os_unix.c \ $(TOP)\src\os_win.c \ $(TOP)\src\os_win.h SRC2 = \ $(TOP)\src\pager.c \ $(TOP)\src\pager.h \ $(TOP)\src\parse.y \ $(TOP)\src\pcache.c \ $(TOP)\src\pcache.h \ $(TOP)\src\pcache1.c \ $(TOP)\src\pragma.c \ |
︙ | ︙ | |||
807 808 809 810 811 812 813 | $(TOP)\src\wal.h \ $(TOP)\src\walker.c \ $(TOP)\src\where.c \ $(TOP)\src\whereInt.h # Source code for extensions # | | | < | | < | < | > > > > | 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 | $(TOP)\src\wal.h \ $(TOP)\src\walker.c \ $(TOP)\src\where.c \ $(TOP)\src\whereInt.h # Source code for extensions # SRC3 = \ $(TOP)\ext\fts1\fts1.c \ $(TOP)\ext\fts1\fts1.h \ $(TOP)\ext\fts1\fts1_hash.c \ $(TOP)\ext\fts1\fts1_hash.h \ $(TOP)\ext\fts1\fts1_porter.c \ $(TOP)\ext\fts1\fts1_tokenizer.h \ $(TOP)\ext\fts1\fts1_tokenizer1.c \ $(TOP)\ext\fts2\fts2.c \ $(TOP)\ext\fts2\fts2.h \ $(TOP)\ext\fts2\fts2_hash.c \ $(TOP)\ext\fts2\fts2_hash.h \ $(TOP)\ext\fts2\fts2_icu.c \ $(TOP)\ext\fts2\fts2_porter.c \ $(TOP)\ext\fts2\fts2_tokenizer.h \ $(TOP)\ext\fts2\fts2_tokenizer.c \ $(TOP)\ext\fts2\fts2_tokenizer1.c SRC4 = \ $(TOP)\ext\fts3\fts3.c \ $(TOP)\ext\fts3\fts3.h \ $(TOP)\ext\fts3\fts3Int.h \ $(TOP)\ext\fts3\fts3_aux.c \ $(TOP)\ext\fts3\fts3_expr.c \ $(TOP)\ext\fts3\fts3_hash.c \ $(TOP)\ext\fts3\fts3_hash.h \ $(TOP)\ext\fts3\fts3_icu.c \ $(TOP)\ext\fts3\fts3_porter.c \ $(TOP)\ext\fts3\fts3_snippet.c \ $(TOP)\ext\fts3\fts3_tokenizer.h \ $(TOP)\ext\fts3\fts3_tokenizer.c \ $(TOP)\ext\fts3\fts3_tokenizer1.c \ $(TOP)\ext\fts3\fts3_tokenize_vtab.c \ $(TOP)\ext\fts3\fts3_unicode.c \ $(TOP)\ext\fts3\fts3_unicode2.c \ $(TOP)\ext\fts3\fts3_write.c \ $(TOP)\ext\icu\sqliteicu.h \ $(TOP)\ext\icu\icu.c \ $(TOP)\ext\rtree\rtree.h \ $(TOP)\ext\rtree\rtree.c # Generated source code files # SRC5 = \ keywordhash.h \ opcodes.c \ opcodes.h \ parse.c \ parse.h \ sqlite3.h # All source code files. # SRC = $(SRC1) $(SRC2) $(SRC3) $(SRC4) $(SRC5) # Source code to the test files. # TESTSRC = \ $(TOP)\src\test1.c \ $(TOP)\src\test2.c \ $(TOP)\src\test3.c \ $(TOP)\src\test4.c \ |
︙ | ︙ | |||
1048 1049 1050 1051 1052 1053 1054 | # build on the target system. Some of the C source code and header # files are automatically generated. This target takes care of # all that automatic generation. # .target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl -rmdir /S/Q tsrc -mkdir tsrc | | > > > > | 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 | # build on the target system. Some of the C source code and header # files are automatically generated. This target takes care of # all that automatic generation. # .target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl -rmdir /S/Q tsrc -mkdir tsrc for %i in ($(SRC1)) do copy /Y %i tsrc for %i in ($(SRC2)) do copy /Y %i tsrc for %i in ($(SRC3)) do copy /Y %i tsrc for %i in ($(SRC4)) do copy /Y %i tsrc for %i in ($(SRC5)) do copy /Y %i tsrc del /Q tsrc\sqlite.h.in tsrc\parse.y $(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new move vdbe.new tsrc\vdbe.c echo > .target_source sqlite3.c: .target_source $(TOP)\tool\mksqlite3c.tcl $(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl $(MKSQLITE3C_ARGS) |
︙ | ︙ |
Changes to src/delete.c.
︙ | ︙ | |||
243 244 245 246 247 248 249 | i16 nPk = 1; /* Number of columns in the PRIMARY KEY */ int iKey; /* Memory cell holding key of row to be deleted */ i16 nKey; /* Number of memory cells in the row key */ int iEphCur = 0; /* Ephemeral table holding all primary key values */ int iRowSet = 0; /* Register for rowset of rows to delete */ int addrBypass = 0; /* Address of jump over the delete logic */ int addrLoop = 0; /* Top of the delete loop */ | < | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | i16 nPk = 1; /* Number of columns in the PRIMARY KEY */ int iKey; /* Memory cell holding key of row to be deleted */ i16 nKey; /* Number of memory cells in the row key */ int iEphCur = 0; /* Ephemeral table holding all primary key values */ int iRowSet = 0; /* Register for rowset of rows to delete */ int addrBypass = 0; /* Address of jump over the delete logic */ int addrLoop = 0; /* Top of the delete loop */ int addrEphOpen = 0; /* Instruction to open the Ephemeral table */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ Trigger *pTrigger; /* List of table triggers, if required */ #endif |
︙ | ︙ | |||
433 434 435 436 437 438 439 | goto delete_from_cleanup; } memset(aToOpen, 1, nIdx+1); aToOpen[nIdx+1] = 0; if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); | < | < < < > | | 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 | goto delete_from_cleanup; } memset(aToOpen, 1, nIdx+1); aToOpen[nIdx+1] = 0; if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); }else if( pPk ){ /* Construct a composite key for the row to be deleted and remember it */ iKey = ++pParse->nMem; nKey = 0; /* Zero tells OP_Found to use a composite key */ sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, sqlite3IndexAffinityStr(v, pPk), nPk); sqlite3VdbeAddOp2(v, OP_IdxInsert, iEphCur, iKey); }else{ /* Get the rowid of the row to be deleted and remember it in the RowSet */ nKey = 1; /* OP_Seek always uses a single rowid */ sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); } /* End of the WHERE loop. */ if( okOnePass ){ addrBypass = sqlite3VdbeMakeLabel(v); }else{ sqlite3WhereEnd(pWInfo); } /* Unless this is a view, open cursors for the table we are ** deleting from and all its indices. If this is a view, then the ** only effect this statement has is to fire the INSTEAD OF ** triggers. */ |
︙ | ︙ | |||
509 510 511 512 513 514 515 516 517 518 519 520 521 522 | int count = (pParse->nested==0); /* True to count changes */ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, iKey, nKey, count, OE_Default, okOnePass); } /* End of the loop over all rowids/primary-keys. */ if( okOnePass ){ sqlite3VdbeResolveLabel(v, addrBypass); }else if( pPk ){ sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addrLoop); }else{ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop); sqlite3VdbeJumpHere(v, addrLoop); | > | 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 | int count = (pParse->nested==0); /* True to count changes */ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, iKey, nKey, count, OE_Default, okOnePass); } /* End of the loop over all rowids/primary-keys. */ if( okOnePass ){ sqlite3WhereEnd(pWInfo); sqlite3VdbeResolveLabel(v, addrBypass); }else if( pPk ){ sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addrLoop); }else{ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrLoop); sqlite3VdbeJumpHere(v, addrLoop); |
︙ | ︙ | |||
670 671 672 673 674 675 676 | } /* Delete the index and table entries. Skip this step if pTab is really ** a view (in which case the only effect of the DELETE statement is to ** fire the INSTEAD OF triggers). */ if( pTab->pSelect==0 ){ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0); | > | | | > | 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 | } /* Delete the index and table entries. Skip this step if pTab is really ** a view (in which case the only effect of the DELETE statement is to ** fire the INSTEAD OF triggers). */ if( pTab->pSelect==0 ){ sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, 0); if( !WRITE_RESTRICT(pParse->db, pTab->tnum) ){ sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); if( count ){ sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT); } } } /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to ** handle rows (possibly in other tables) that refer via a foreign key ** to the row just deleted. */ sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); |
︙ | ︙ | |||
732 733 734 735 736 737 738 739 740 741 742 743 744 745 | v = pParse->pVdbe; pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ assert( iIdxCur+i!=iDataCur || pPk==pIdx ); if( aRegIdx!=0 && aRegIdx[i]==0 ) continue; if( pIdx==pPk ) continue; VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel, pPrior, r1); sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); pPrior = pIdx; | > | 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 | v = pParse->pVdbe; pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ assert( iIdxCur+i!=iDataCur || pPk==pIdx ); if( aRegIdx!=0 && aRegIdx[i]==0 ) continue; if( pIdx==pPk ) continue; if( WRITE_RESTRICT(pParse->db, pIdx->tnum) ) continue; VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel, pPrior, r1); sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); pPrior = pIdx; |
︙ | ︙ |
Changes to src/insert.c.
︙ | ︙ | |||
1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 | for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){ int regIdx; /* Range of registers hold conent for pIdx */ int regR; /* Range of registers holding conflicting PK */ int iThisCur; /* Cursor for this UNIQUE index */ int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ if( bAffinityDone==0 ){ sqlite3TableAffinity(v, pTab, regNewData+1); bAffinityDone = 1; } iThisCur = iIdxCur+ix; addrUniqueOk = sqlite3VdbeMakeLabel(v); | > | 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 | for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){ int regIdx; /* Range of registers hold conent for pIdx */ int regR; /* Range of registers holding conflicting PK */ int iThisCur; /* Cursor for this UNIQUE index */ int addrUniqueOk; /* Jump here if the UNIQUE constraint is satisfied */ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ if( WRITE_RESTRICT(db, pIdx->tnum) ) continue; if( bAffinityDone==0 ){ sqlite3TableAffinity(v, pTab, regNewData+1); bAffinityDone = 1; } iThisCur = iIdxCur+ix; addrUniqueOk = sqlite3VdbeMakeLabel(v); |
︙ | ︙ | |||
1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 | int *aRegIdx, /* Register used by each index. 0 for unused indices */ int isUpdate, /* True for UPDATE, False for INSERT */ int appendBias, /* True if this is likely to be an append */ int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */ ){ Vdbe *v; /* Prepared statements under construction */ Index *pIdx; /* An index being inserted or updated */ u8 pik_flags; /* flag values passed to the btree insert */ int regData; /* Content registers (after the rowid) */ int regRec; /* Register holding assembled record for the table */ int i; /* Loop counter */ u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */ v = sqlite3GetVdbe(pParse); assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ if( aRegIdx[i]==0 ) continue; bAffinityDone = 1; if( pIdx->pPartIdxWhere ){ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); } sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]); pik_flags = 0; if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ assert( pParse->nested==0 ); pik_flags |= OPFLAG_NCHANGE; } if( pik_flags ) sqlite3VdbeChangeP5(v, pik_flags); } if( !HasRowid(pTab) ) return; regData = regNewData + 1; regRec = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec); if( !bAffinityDone ) sqlite3TableAffinity(v, pTab, 0); sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); if( pParse->nested ){ pik_flags = 0; | > > > > | 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 | int *aRegIdx, /* Register used by each index. 0 for unused indices */ int isUpdate, /* True for UPDATE, False for INSERT */ int appendBias, /* True if this is likely to be an append */ int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */ ){ Vdbe *v; /* Prepared statements under construction */ Index *pIdx; /* An index being inserted or updated */ sqlite3 *db; u8 pik_flags; /* flag values passed to the btree insert */ int regData; /* Content registers (after the rowid) */ int regRec; /* Register holding assembled record for the table */ int i; /* Loop counter */ u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */ v = sqlite3GetVdbe(pParse); assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ db = pParse->db; for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ if( aRegIdx[i]==0 ) continue; if( WRITE_RESTRICT(db, pIdx->tnum) ) continue; bAffinityDone = 1; if( pIdx->pPartIdxWhere ){ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); } sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i]); pik_flags = 0; if( useSeekResult ) pik_flags = OPFLAG_USESEEKRESULT; if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ assert( pParse->nested==0 ); pik_flags |= OPFLAG_NCHANGE; } if( pik_flags ) sqlite3VdbeChangeP5(v, pik_flags); } if( !HasRowid(pTab) ) return; if( WRITE_RESTRICT(db, pTab->tnum) ) return; regData = regNewData + 1; regRec = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec); if( !bAffinityDone ) sqlite3TableAffinity(v, pTab, 0); sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); if( pParse->nested ){ pik_flags = 0; |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
720 721 722 723 724 725 726 727 728 729 730 731 732 733 | switch( op ){ case SQLITE_DBCONFIG_LOOKASIDE: { void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */ int sz = va_arg(ap, int); /* IMP: R-47871-25994 */ int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */ rc = setupLookaside(db, pBuf, sz, cnt); break; } default: { static const struct { int op; /* The opcode */ u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */ } aFlagOp[] = { { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, | > > > > > | 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 | switch( op ){ case SQLITE_DBCONFIG_LOOKASIDE: { void *pBuf = va_arg(ap, void*); /* IMP: R-26835-10964 */ int sz = va_arg(ap, int); /* IMP: R-47871-25994 */ int cnt = va_arg(ap, int); /* IMP: R-04460-53386 */ rc = setupLookaside(db, pBuf, sz, cnt); break; } case SQLITE_DBCONFIG_WRITABLE_BTREE: { db->onlyWritableBtree = va_arg(ap,int); rc = SQLITE_OK; break; } default: { static const struct { int op; /* The opcode */ u32 mask; /* Mask of the bit in sqlite3.flags to set/clear */ } aFlagOp[] = { { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, |
︙ | ︙ |
Changes to src/shell.c.
︙ | ︙ | |||
2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 | sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); rc = 1; } }else if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ open_db(p, 0); /* When playing back a "dump", the content might appear in an order ** which causes immediate foreign key constraints to be violated. ** So disable foreign-key constraint enforcement to prevent problems. */ if( nArg!=1 && nArg!=2 ){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 | sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg); if( zErrMsg ){ fprintf(stderr,"Error: %s\n", zErrMsg); sqlite3_free(zErrMsg); rc = 1; } }else if( c=='d' && n>1 && strncmp(azArg[0], "dbconfig", n)==0 ){ int nHit = 0, x; open_db(p, 0); if( nArg>=2 ){ n = (int)strlen(azArg[1]); if( strncmp(azArg[1], "writable_btree",n)==0 ){ if( nArg!=3 ){ fprintf(stderr, "Usage: .dbconfig writable_btree N\n"); rc = 1; }else{ sqlite3_db_config(p->db, SQLITE_DBCONFIG_WRITABLE_BTREE, integerValue(azArg[2])); } nHit = 1; }else if( strncmp(azArg[1], "enable_fkey",n)==0 ){ if( nArg!=3 ){ fprintf(stderr, "Usage: .dbconfig enable_fkey (1|0|-1)\n"); rc = 1; }else{ sqlite3_db_config(p->db, SQLITE_DBCONFIG_ENABLE_FKEY, integerValue(azArg[2]), &x); printf("result: %d\n", x); } nHit = 1; }else if( strncmp(azArg[1], "enable_trigger",n)==0 ){ if( nArg!=3 ){ fprintf(stderr, "Usage: .dbconfig enable_trigger (1|0|-1)\n"); rc = 1; }else{ sqlite3_db_config(p->db, SQLITE_DBCONFIG_ENABLE_TRIGGER, integerValue(azArg[2]), &x); printf("result: %d\n", x); } nHit = 1; } } if( nHit==0 ){ fprintf(stderr, "Usage: .dbconfig COMMAND ARGS...\n"); fprintf(stderr, "COMMAND is one of: writable_btree enable_fkey enable_trigger\n"); rc = 1; } }else if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){ open_db(p, 0); /* When playing back a "dump", the content might appear in an order ** which causes immediate foreign key constraints to be violated. ** So disable foreign-key constraint enforcement to prevent problems. */ if( nArg!=1 && nArg!=2 ){ |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 | ** The first argument is an integer which is 0 to disable triggers, ** positive to enable triggers or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. </dd> ** ** </dl> */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes ** ** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result | > > > > > > > > > | 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 | ** The first argument is an integer which is 0 to disable triggers, ** positive to enable triggers or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. </dd> ** ** <dt>SQLITE_DBCONFIG_WRITABLE_BTREE</dt> ** <dd> ^This option is used to disable INSERT and DELETE operations ** against all attached b-trees, except for b-trees that have a ** particular root page. ** There must be one additional integer argument which is the root page ** that is allowed to be written. If the argument is zero, then ** writing is allowed to all b-trees, as is normally the case. ** ** </dl> */ #define SQLITE_DBCONFIG_LOOKASIDE 1001 /* void* int int */ #define SQLITE_DBCONFIG_ENABLE_FKEY 1002 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_TRIGGER 1003 /* int int* */ #define SQLITE_DBCONFIG_WRITABLE_BTREE 1004 /* int */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes ** ** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 | u8 mallocFailed; /* True if we have seen a malloc failure */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ u8 suppressErr; /* Do not issue error messages if true */ u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ int nextPagesize; /* Pagesize after VACUUM if >0 */ u32 magic; /* Magic number for detect library misuse */ int nChange; /* Value returned by sqlite3_changes() */ int nTotalChange; /* Value returned by sqlite3_total_changes() */ int aLimit[SQLITE_N_LIMIT]; /* Limits */ int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */ struct sqlite3InitInfo { /* Information used during initialization */ int newTnum; /* Rootpage of table being initialized */ | > | 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 | u8 mallocFailed; /* True if we have seen a malloc failure */ u8 dfltLockMode; /* Default locking-mode for attached dbs */ signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ u8 suppressErr; /* Do not issue error messages if true */ u8 vtabOnConflict; /* Value to return for s3_vtab_on_conflict() */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ int nextPagesize; /* Pagesize after VACUUM if >0 */ int onlyWritableBtree; /* Do not write to any other b-tree */ u32 magic; /* Magic number for detect library misuse */ int nChange; /* Value returned by sqlite3_changes() */ int nTotalChange; /* Value returned by sqlite3_total_changes() */ int aLimit[SQLITE_N_LIMIT]; /* Limits */ int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */ struct sqlite3InitInfo { /* Information used during initialization */ int newTnum; /* Rootpage of table being initialized */ |
︙ | ︙ | |||
1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 | sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ #endif #ifdef SQLITE_USER_AUTHENTICATION sqlite3_userauth auth; /* User authentication information */ #endif }; /* ** A macro to discover the encoding of a database. */ #define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc) #define ENC(db) ((db)->enc) /* | > > > > > > > | 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 | sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ #endif #ifdef SQLITE_USER_AUTHENTICATION sqlite3_userauth auth; /* User authentication information */ #endif }; /* ** This macro returns true if the only_writable_btree pragma is turned ** on and is set to a btree root node other than N. */ #define WRITE_RESTRICT(db,N) ((db)->onlyWritableBtree>0 && \ (db)->onlyWritableBtree!=(N)) /* ** A macro to discover the encoding of a database. */ #define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc) #define ENC(db) ((db)->enc) /* |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
4187 4188 4189 4190 4191 4192 4193 | case OP_Delete: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ | | > | 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 | case OP_Delete: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ rc = sqlite3VdbeCursorMoveto(pC); if( rc ) goto abort_due_to_error; #ifdef SQLITE_DEBUG /* The seek operation that positioned the cursor prior to OP_Delete will ** have also set the pC->movetoTarget field to the rowid of the row that ** is being deleted */ if( pOp->p4.z && pC->isTable ){ i64 iKey = 0; |
︙ | ︙ |