Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Additional changes toward fixing ticket #3292. (CVS 5562) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
0b92cbf5255020d4fde382f81590ff04 |
User & Date: | drh 2008-08-13 19:11:48.000 |
Context
2008-08-13
| ||
20:04 | Fix token destructors in lemon generated parsers. Does not effect SQLite. Ticket #3299. (CVS 5563) (check-in: 4887e8fc4a user: drh tags: trunk) | |
19:11 | Additional changes toward fixing ticket #3292. (CVS 5562) (check-in: 0b92cbf525 user: drh tags: trunk) | |
14:07 | A partial fix for ticket #3292. This fixes the original problem but there are other similar problems lurking in the code still. (CVS 5561) (check-in: 055f173ab1 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.497 2008/08/13 19:11:48 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. ** Including a description of file format and an overview of operation. */ #include "btreeInt.h" |
︙ | ︙ | |||
371 372 373 374 375 376 377 | int rc; assert( cursorHoldsMutex(pCur) ); assert( pCur->eState>=CURSOR_REQUIRESEEK ); if( pCur->eState==CURSOR_FAULT ){ return pCur->skip; } pCur->eState = CURSOR_INVALID; | | | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | int rc; assert( cursorHoldsMutex(pCur) ); assert( pCur->eState>=CURSOR_REQUIRESEEK ); if( pCur->eState==CURSOR_FAULT ){ return pCur->skip; } pCur->eState = CURSOR_INVALID; rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip); if( rc==SQLITE_OK ){ sqlite3_free(pCur->pKey); pCur->pKey = 0; assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); } return rc; } |
︙ | ︙ | |||
3644 3645 3646 3647 3648 3649 3650 | pCur->atLast = rc==SQLITE_OK; } } return rc; } /* Move the cursor so that it points to an entry near the key | | | | < | | 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 | pCur->atLast = rc==SQLITE_OK; } } return rc; } /* Move the cursor so that it points to an entry near the key ** specified by pIdxKey or intKey. Return a success code. ** ** For INTKEY tables, the intKey parameter is used. pIdxKey ** must be NULL. For index tables, pIdxKey is used and intKey ** is ignored. ** ** If an exact match is not found, then the cursor is always ** left pointing at a leaf page which would hold the entry if it ** were present. The cursor might point to an entry that comes ** before or after the key. ** ** The result of comparing the key with the entry to which the |
︙ | ︙ | |||
3671 3672 3673 3674 3675 3676 3677 | ** *pRes==0 The cursor is left pointing at an entry that ** exactly matches pKey. ** ** *pRes>0 The cursor is left pointing at an entry that ** is larger than pKey. ** */ | | | < | | | | < | | | < < < < < < < < < < < < < < < < < | | 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 | ** *pRes==0 The cursor is left pointing at an entry that ** exactly matches pKey. ** ** *pRes>0 The cursor is left pointing at an entry that ** is larger than pKey. ** */ int sqlite3BtreeMovetoUnpacked( BtCursor *pCur, /* The cursor to be moved */ UnpackedRecord *pIdxKey, /* Unpacked index key */ i64 intKey, /* The table key */ int biasRight, /* If true, bias the search to the high end */ int *pRes /* Write search results here */ ){ int rc; assert( cursorHoldsMutex(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); /* If the cursor is already positioned at the point we are trying ** to move to, then just return without doing any work */ if( pCur->eState==CURSOR_VALID && pCur->validNKey && pCur->pPage->intKey ){ if( pCur->info.nKey==intKey ){ *pRes = 0; return SQLITE_OK; } if( pCur->atLast && pCur->info.nKey<intKey ){ *pRes = -1; return SQLITE_OK; } } rc = moveToRoot(pCur); if( rc ){ return rc; } assert( pCur->pPage ); assert( pCur->pPage->isInit ); if( pCur->eState==CURSOR_INVALID ){ *pRes = -1; assert( pCur->pPage->nCell==0 ); return SQLITE_OK; } assert( pCur->pPage->intKey || pIdxKey ); for(;;){ int lwr, upr; Pgno chldPg; MemPage *pPage = pCur->pPage; int c = -1; /* pRes return if table is empty must be -1 */ lwr = 0; upr = pPage->nCell-1; if( !pPage->intKey && pIdxKey==0 ){ rc = SQLITE_CORRUPT_BKPT; goto moveto_finish; } if( biasRight ){ pCur->idx = upr; }else{ pCur->idx = (upr+lwr)/2; |
︙ | ︙ | |||
3757 3758 3759 3760 3761 3762 3763 | u8 *pCell; pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize; if( pPage->hasData ){ u32 dummy; pCell += getVarint32(pCell, dummy); } getVarint(pCell, (u64*)&nCellKey); | | | | | | | 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 | u8 *pCell; pCell = findCell(pPage, pCur->idx) + pPage->childPtrSize; if( pPage->hasData ){ u32 dummy; pCell += getVarint32(pCell, dummy); } getVarint(pCell, (u64*)&nCellKey); if( nCellKey==intKey ){ c = 0; }else if( nCellKey<intKey ){ c = -1; }else{ assert( nCellKey>intKey ); c = +1; } }else{ int available; pCellKey = (void *)fetchPayload(pCur, &available, 0); nCellKey = pCur->info.nKey; if( available>=nCellKey ){ c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pIdxKey); }else{ pCellKey = sqlite3Malloc( nCellKey ); if( pCellKey==0 ){ rc = SQLITE_NOMEM; goto moveto_finish; } rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey); c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pIdxKey); sqlite3_free(pCellKey); if( rc ) goto moveto_finish; } } if( c==0 ){ pCur->info.nKey = nCellKey; if( pPage->intKey && !pPage->leaf ){ |
︙ | ︙ | |||
3828 3829 3830 3831 3832 3833 3834 3835 | pCur->idx = lwr; pCur->info.nSize = 0; pCur->validNKey = 0; rc = moveToChild(pCur, chldPg); if( rc ) goto moveto_finish; } moveto_finish: if( pKey ){ | > > > > > > > > > > > > > > > > > > > < > > | > > > > > | | 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 | pCur->idx = lwr; pCur->info.nSize = 0; pCur->validNKey = 0; rc = moveToChild(pCur, chldPg); if( rc ) goto moveto_finish; } moveto_finish: return rc; } /* ** In this version of BtreeMoveto, pKey is a packed index record ** such as is generated by the OP_MakeRecord opcode. Unpack the ** record and then call BtreeMovetoUnpacked() to do the work. */ int sqlite3BtreeMoveto( BtCursor *pCur, /* Cursor open on the btree to be searched */ const void *pKey, /* Packed key if the btree is an index */ i64 nKey, /* Integer key for tables. Size of pKey for indices */ int bias, /* Bias search to the high end */ int *pRes /* Write search results here */ ){ int rc; /* Status code */ UnpackedRecord *pIdxKey; /* Unpacked index key */ char aSpace[200]; /* Temp space for pIdxKey - to avoid a malloc */ if( pKey ){ pIdxKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, nKey, pKey, aSpace, sizeof(aSpace)); if( pIdxKey==0 ) return SQLITE_NOMEM; }else{ pIdxKey = 0; } rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); if( pKey ){ sqlite3VdbeDeleteUnpackedRecord(pIdxKey); } return rc; } /* ** Return TRUE if the cursor is not pointing at an entry of the table. |
︙ | ︙ | |||
5832 5833 5834 5835 5836 5837 5838 | return pCur->skip; } /* Save the positions of any other cursors open on this table */ clearCursorPosition(pCur); if( SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) || | | | 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 | return pCur->skip; } /* Save the positions of any other cursors open on this table */ clearCursorPosition(pCur); if( SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) || SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc)) ){ return rc; } pPage = pCur->pPage; assert( pPage->intKey || nKey>=0 ); assert( pPage->leaf || !pPage->intKey ); |
︙ | ︙ |
Changes to src/btree.h.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** This header file defines the interface that the sqlite B-Tree file ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** ** @(#) $Id: btree.h,v 1.103 2008/08/13 19:11:48 drh Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ /* TODO: This definition is just included so other modules compile. It ** needs to be revisited. */ |
︙ | ︙ | |||
118 119 120 121 122 123 124 | int sqlite3BtreeDropTable(Btree*, int, int*); int sqlite3BtreeClearTable(Btree*, int); int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue); int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); void sqlite3BtreeTripAllCursors(Btree*, int); | < < < > > > > > > > | 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 146 147 148 149 150 151 152 153 154 | int sqlite3BtreeDropTable(Btree*, int, int*); int sqlite3BtreeClearTable(Btree*, int); int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue); int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); void sqlite3BtreeTripAllCursors(Btree*, int); int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ int iTable, /* Index of root page */ int wrFlag, /* 1 for writing. 0 for read-only */ struct KeyInfo*, /* First argument to compare function */ BtCursor *pCursor /* Space to write cursor structure */ ); int sqlite3BtreeCursorSize(void); int sqlite3BtreeCloseCursor(BtCursor*); int sqlite3BtreeMoveto( BtCursor*, const void *pKey, i64 nKey, int bias, int *pRes ); int sqlite3BtreeMovetoUnpacked( BtCursor*, UnpackedRecord *pUnKey, i64 intKey, int bias, int *pRes ); int sqlite3BtreeCursorHasMoved(BtCursor*, int*); int sqlite3BtreeDelete(BtCursor*); int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey, const void *pData, int nData, int nZero, int bias); int sqlite3BtreeFirst(BtCursor*, int *pRes); |
︙ | ︙ |
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.755 2008/08/13 19:11:48 drh Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build |
︙ | ︙ | |||
466 467 468 469 470 471 472 473 474 475 476 477 478 479 | typedef struct StrAccum StrAccum; typedef struct Table Table; typedef struct TableLock TableLock; typedef struct Token Token; typedef struct TriggerStack TriggerStack; typedef struct TriggerStep TriggerStep; typedef struct Trigger Trigger; typedef struct WhereInfo WhereInfo; typedef struct WhereLevel WhereLevel; /* ** Defer sourcing vdbe.h and btree.h until after the "u8" and ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque ** pointer types (i.e. FuncDef) defined above. | > | 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 | typedef struct StrAccum StrAccum; typedef struct Table Table; typedef struct TableLock TableLock; typedef struct Token Token; typedef struct TriggerStack TriggerStack; typedef struct TriggerStep TriggerStep; typedef struct Trigger Trigger; typedef struct UnpackedRecord UnpackedRecord; typedef struct WhereInfo WhereInfo; typedef struct WhereLevel WhereLevel; /* ** Defer sourcing vdbe.h and btree.h until after the "u8" and ** "BusyHandler" typedefs. vdbe.h also requires a few of the opaque ** pointer types (i.e. FuncDef) defined above. |
︙ | ︙ | |||
1033 1034 1035 1036 1037 1038 1039 | #define OE_Default 99 /* Do whatever the default action is */ /* ** An instance of the following structure is passed as the first ** argument to sqlite3VdbeKeyCompare and is used to control the ** comparison of the two index keys. | < < < < < < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 | #define OE_Default 99 /* Do whatever the default action is */ /* ** An instance of the following structure is passed as the first ** argument to sqlite3VdbeKeyCompare and is used to control the ** comparison of the two index keys. */ struct KeyInfo { sqlite3 *db; /* The database connection */ u8 enc; /* Text encoding - one of the TEXT_Utf* values */ u16 nField; /* Number of entries in aColl[] */ u8 *aSortOrder; /* If defined an aSortOrder[i] is true, sort DESC */ CollSeq *aColl[1]; /* Collating sequence for each term of the key */ }; /* ** An instance of the following structure holds information about a ** single index record that has already been parsed out into individual ** values. ** ** A record is an object that contains one or more fields of data. ** Records are used to store the content of a table row and to store ** the key of an index. A blob encoding of a record is created by ** the OP_MakeRecord opcode of the VDBE and is disassemblied by the ** OP_Column opcode. ** ** This structure holds a record that has already been disassembled ** into its constitutent fields. */ struct UnpackedRecord { KeyInfo *pKeyInfo; /* Collation and sort-order information */ u16 nField; /* Number of entries in apMem[] */ u16 flags; /* Boolean settings. UNPACKED_... below */ Mem *aMem; /* Values */ }; /* ** Allowed values of UnpackedRecord.flags */ #define UNPACKED_NEED_FREE 0x0001 /* Memory is from sqlite3Malloc() */ #define UNPACKED_NEED_DESTROY 0x0002 /* apMem[]s should all be destroyed */ #define UNPACKED_IGNORE_ROWID 0x0004 /* Ignore trailing rowid on key1 */ #define UNPACKED_INCRKEY 0x0008 /* Make this key an epsilon larger */ #define UNPACKED_PREFIX_MATCH 0x0010 /* A prefix match is considered OK */ /* ** Each SQL index is represented in memory by an ** instance of the following structure. ** ** The columns of the table that are to be indexed are described ** by the aiColumn[] field of this structure. For example, suppose ** we have the following table and index: |
︙ | ︙ |
Changes to src/test3.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the btree.c module in SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test3.c,v 1.101 2008/08/13 19:11:48 drh Exp $ */ #include "sqliteInt.h" #include "btreeInt.h" #include "tcl.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
693 694 695 696 697 698 699 | sqlite3BtreeEnter(pCur->pBtree); if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){ int iKey; if( Tcl_GetInt(interp, argv[2], &iKey) ){ sqlite3BtreeLeave(pCur->pBtree); return TCL_ERROR; } | | | | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | sqlite3BtreeEnter(pCur->pBtree); if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){ int iKey; if( Tcl_GetInt(interp, argv[2], &iKey) ){ sqlite3BtreeLeave(pCur->pBtree); return TCL_ERROR; } rc = sqlite3BtreeMovetoUnpacked(pCur, 0, iKey, 0, &res); }else{ rc = sqlite3BtreeMoveto(pCur, argv[2], strlen(argv[2]), 0, &res); } sqlite3BtreeLeave(pCur->pBtree); if( rc ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } if( res<0 ) res = -1; |
︙ | ︙ |
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.775 2008/08/13 19:11:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
551 552 553 554 555 556 557 558 559 560 561 562 563 564 | #ifdef VDBE_PROFILE u64 start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ #endif #ifndef SQLITE_OMIT_PROGRESS_CALLBACK int nProgressOps = 0; /* Opcodes executed since progress callback. */ #endif assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ assert( db->magic==SQLITE_MAGIC_BUSY ); sqlite3BtreeMutexArrayEnter(&p->aMutex); if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or ** sqlite3_column_text16() failed. */ | > > | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 | #ifdef VDBE_PROFILE u64 start; /* CPU clock count at start of opcode */ int origPc; /* Program counter at start of opcode */ #endif #ifndef SQLITE_OMIT_PROGRESS_CALLBACK int nProgressOps = 0; /* Opcodes executed since progress callback. */ #endif char zTempSpace[200]; /* Space to hold a transient UnpackedRecord */ assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ assert( db->magic==SQLITE_MAGIC_BUSY ); sqlite3BtreeMutexArrayEnter(&p->aMutex); if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or ** sqlite3_column_text16() failed. */ |
︙ | ︙ | |||
2701 2702 2703 2704 2705 2706 2707 | assert( i>=0 ); pCur = allocateCursor(p, i, &pOp[-1], iDb, 1); if( pCur==0 ) goto no_mem; pCur->nullRow = 1; rc = sqlite3BtreeCursor(pX, p2, wrFlag, pOp->p4.p, pCur->pCursor); if( pOp->p4type==P4_KEYINFO ){ pCur->pKeyInfo = pOp->p4.pKeyInfo; | < < | 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 | assert( i>=0 ); pCur = allocateCursor(p, i, &pOp[-1], iDb, 1); if( pCur==0 ) goto no_mem; pCur->nullRow = 1; rc = sqlite3BtreeCursor(pX, p2, wrFlag, pOp->p4.p, pCur->pCursor); if( pOp->p4type==P4_KEYINFO ){ pCur->pKeyInfo = pOp->p4.pKeyInfo; pCur->pKeyInfo->enc = ENC(p->db); }else{ pCur->pKeyInfo = 0; } switch( rc ){ case SQLITE_BUSY: { p->pc = pc; p->rc = rc = SQLITE_BUSY; goto vdbe_return; } |
︙ | ︙ | |||
2805 2806 2807 2808 2809 2810 2811 | rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); if( rc==SQLITE_OK ){ assert( pgno==MASTER_ROOT+1 ); rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, (KeyInfo*)pOp->p4.z, pCx->pCursor); pCx->pKeyInfo = pOp->p4.pKeyInfo; pCx->pKeyInfo->enc = ENC(p->db); | < < | 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 | rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); if( rc==SQLITE_OK ){ assert( pgno==MASTER_ROOT+1 ); rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, (KeyInfo*)pOp->p4.z, pCx->pCursor); pCx->pKeyInfo = pOp->p4.pKeyInfo; pCx->pKeyInfo->enc = ENC(p->db); } pCx->isTable = 0; }else{ rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, pCx->pCursor); pCx->isTable = 1; } } pCx->isIndex = !pCx->isTable; break; } /* Opcode: OpenPseudo P1 P2 * * * |
︙ | ︙ | |||
2847 2848 2849 2850 2851 2852 2853 | Cursor *pCx; assert( i>=0 ); pCx = allocateCursor(p, i, &pOp[-1], -1, 0); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; pCx->pseudoTable = 1; pCx->ephemPseudoTable = pOp->p2; | < | 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 | Cursor *pCx; assert( i>=0 ); pCx = allocateCursor(p, i, &pOp[-1], -1, 0); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; pCx->pseudoTable = 1; pCx->ephemPseudoTable = pOp->p2; pCx->isTable = 1; pCx->isIndex = 0; break; } /* Opcode: Close P1 * * * * ** |
︙ | ︙ | |||
2939 2940 2941 2942 2943 2944 2945 | assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); if( pC->pCursor!=0 ){ int res, oc; oc = pOp->opcode; pC->nullRow = 0; | < | > | > | > | < | 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 | assert( i>=0 && i<p->nCursor ); pC = p->apCsr[i]; assert( pC!=0 ); if( pC->pCursor!=0 ){ int res, oc; oc = pOp->opcode; pC->nullRow = 0; if( pC->isTable ){ i64 iKey = sqlite3VdbeIntValue(pIn3); if( pOp->p2==0 ){ assert( pOp->opcode==OP_MoveGe ); pC->movetoTarget = iKey; pC->rowidIsValid = 0; pC->deferredMoveto = 1; break; } rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pC->lastRowid = iKey; pC->rowidIsValid = res==0; }else{ UnpackedRecord r; int nField = pOp->p4.i; assert( pOp->p4type==P4_INT32 ); assert( nField>0 ); r.pKeyInfo = pC->pKeyInfo; r.nField = nField; if( oc==OP_MoveGt || oc==OP_MoveLe ){ r.flags = UNPACKED_INCRKEY; }else{ r.flags = 0; } r.aMem = &p->aMem[pOp->p3]; rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, &r, 0, 0, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } pC->rowidIsValid = 0; } pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; #ifdef SQLITE_TEST sqlite3_search_count++; #endif if( oc==OP_MoveGe || oc==OP_MoveGt ){ if( res<0 ){ rc = sqlite3BtreeNext(pC->pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; |
︙ | ︙ | |||
3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 | int i = pOp->p1; int alreadyExists = 0; Cursor *pC; assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pC = p->apCsr[i])->pCursor!=0 ){ int res; assert( pC->isTable==0 ); assert( pIn3->flags & MEM_Blob ); if( pOp->opcode==OP_Found ){ | > > > > > > > < > | < > | | 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 | int i = pOp->p1; int alreadyExists = 0; Cursor *pC; assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pC = p->apCsr[i])->pCursor!=0 ){ int res; UnpackedRecord *pIdxKey; assert( pC->isTable==0 ); assert( pIn3->flags & MEM_Blob ); pIdxKey = sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, zTempSpace, sizeof(zTempSpace)); if( pIdxKey==0 ){ goto no_mem; } if( pOp->opcode==OP_Found ){ pIdxKey->flags |= UNPACKED_PREFIX_MATCH; } rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res); sqlite3VdbeDeleteUnpackedRecord(pIdxKey); if( rc!=SQLITE_OK ){ break; } alreadyExists = (res==0); pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; } if( pOp->opcode==OP_Found ){ if( alreadyExists ) pc = pOp->p2 - 1; }else{ if( !alreadyExists ) pc = pOp->p2 - 1; } break; } /* Opcode: IsUnique P1 P2 P3 P4 * ** ** The P3 register contains an integer record number. Call this ** record number R. The P4 register contains an index key created ** using MakeRecord. Call it K. ** ** P1 is an index. So it has no data and its key consists of a ** record generated by OP_MakeRecord where the last field is the ** rowid of the entry that the index refers to. ** ** This instruction asks if there is an entry in P1 where the ** fields matches K but the rowid is different from R. |
︙ | ︙ | |||
3113 3114 3115 3116 3117 3118 3119 | R = pIn3->u.i; assert( i>=0 && i<p->nCursor ); pCx = p->apCsr[i]; assert( pCx!=0 ); pCrsr = pCx->pCursor; if( pCrsr!=0 ){ int res; | | | < < < | > | > | < < < < < < < < | | | > > | > | 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 | R = pIn3->u.i; assert( i>=0 && i<p->nCursor ); pCx = p->apCsr[i]; assert( pCx!=0 ); pCrsr = pCx->pCursor; if( pCrsr!=0 ){ int res; i64 v; /* The record number that matches K */ UnpackedRecord *pIdxKey; /* Unpacked version of P4 */ /* Make sure K is a string and make zKey point to K */ assert( pK->flags & MEM_Blob ); pIdxKey = sqlite3VdbeRecordUnpack(pCx->pKeyInfo, pK->n, pK->z, zTempSpace, sizeof(zTempSpace)); if( pIdxKey==0 ){ goto no_mem; } pIdxKey->flags |= UNPACKED_IGNORE_ROWID; /* Search for an entry in P1 where all but the last rowid match K ** If there is no such entry, jump immediately to P2. */ assert( pCx->deferredMoveto==0 ); pCx->cacheStatus = CACHE_STALE; rc = sqlite3BtreeMovetoUnpacked(pCrsr, pIdxKey, 0, 0, &res); if( rc!=SQLITE_OK ){ sqlite3VdbeDeleteUnpackedRecord(pIdxKey); goto abort_due_to_error; } if( res<0 ){ rc = sqlite3BtreeNext(pCrsr, &res); if( res ){ pc = pOp->p2 - 1; sqlite3VdbeDeleteUnpackedRecord(pIdxKey); break; } } rc = sqlite3VdbeIdxKeyCompare(pCx, pIdxKey, &res); sqlite3VdbeDeleteUnpackedRecord(pIdxKey); if( rc!=SQLITE_OK ) goto abort_due_to_error; if( res>0 ){ pc = pOp->p2 - 1; break; } /* At this point, pCrsr is pointing to an entry in P1 where all but |
︙ | ︙ | |||
3208 3209 3210 3211 3212 3213 3214 | assert( p->apCsr[i]!=0 ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int res; u64 iKey; assert( pIn3->flags & MEM_Int ); assert( p->apCsr[i]->isTable ); iKey = intToKey(pIn3->u.i); | | | 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 | assert( p->apCsr[i]!=0 ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int res; u64 iKey; assert( pIn3->flags & MEM_Int ); assert( p->apCsr[i]->isTable ); iKey = intToKey(pIn3->u.i); rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0,&res); pC->lastRowid = pIn3->u.i; pC->rowidIsValid = res==0; pC->nullRow = 0; pC->cacheStatus = CACHE_STALE; /* res might be uninitialized if rc!=SQLITE_OK. But if rc!=SQLITE_OK ** processing is about to abort so we really do not care whether or not ** the following jump is taken. (In other words, do not stress over |
︙ | ︙ | |||
3385 3386 3387 3388 3389 3390 3391 | v++; }else{ sqlite3_randomness(sizeof(v), &v); if( cnt<5 ) v &= 0xffffff; } if( v==0 ) continue; x = intToKey(v); | | | 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 | v++; }else{ sqlite3_randomness(sizeof(v), &v); if( cnt<5 ) v &= 0xffffff; } if( v==0 ) continue; x = intToKey(v); rx = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)x, 0, &res); cnt++; }while( cnt<100 && rx==SQLITE_OK && res==0 ); db->priorNewRowid = v; if( rx==SQLITE_OK && res==0 ){ rc = SQLITE_FULL; goto abort_due_to_error; } |
︙ | ︙ | |||
3881 3882 3883 3884 3885 3886 3887 | assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int res; UnpackedRecord r; r.pKeyInfo = pC->pKeyInfo; r.nField = pOp->p3; | | < | | 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 | assert( i>=0 && i<p->nCursor ); assert( p->apCsr[i]!=0 ); if( (pCrsr = (pC = p->apCsr[i])->pCursor)!=0 ){ int res; UnpackedRecord r; r.pKeyInfo = pC->pKeyInfo; r.nField = pOp->p3; r.flags = 0; r.aMem = &p->aMem[pOp->p2]; rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); if( rc==SQLITE_OK && res==0 ){ rc = sqlite3BtreeDelete(pCrsr); } assert( pC->deferredMoveto==0 ); pC->cacheStatus = CACHE_STALE; } break; |
︙ | ︙ | |||
3967 3968 3969 3970 3971 3972 3973 | int res; UnpackedRecord r; assert( pC->deferredMoveto==0 ); assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); r.pKeyInfo = pC->pKeyInfo; r.nField = pOp->p4.i; | > > | | > < | < | 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 | int res; UnpackedRecord r; assert( pC->deferredMoveto==0 ); assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); r.pKeyInfo = pC->pKeyInfo; r.nField = pOp->p4.i; if( pOp->p5 ){ r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; }else{ r.flags = UNPACKED_IGNORE_ROWID; } r.aMem = &p->aMem[pOp->p3]; rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res); if( pOp->opcode==OP_IdxLT ){ res = -res; }else{ assert( pOp->opcode==OP_IdxGE ); res++; } if( res>0 ){ |
︙ | ︙ |
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | ************************************************************************* ** 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.137 2008/08/13 19:11:48 drh Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ #include <stdio.h> /* ** A single VDBE is an opaque structure named "Vdbe". Only routines ** in the source file sqliteVdbe.c are allowed to see the insides ** of this structure. */ typedef struct Vdbe Vdbe; /* ** The names of the following types declared in vdbeInt.h are required ** for the VdbeOp definition. */ typedef struct VdbeFunc VdbeFunc; typedef struct Mem Mem; /* ** A single instruction of the virtual machine has an opcode ** and as many as three operands. The instruction is recorded ** as an instance of the following structure: */ struct VdbeOp { |
︙ | ︙ | |||
186 187 188 189 190 191 192 | void sqlite3VdbeSwap(Vdbe*,Vdbe*); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT int sqlite3VdbeReleaseMemory(int); #endif UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,void*,int); void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*); | | | 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | void sqlite3VdbeSwap(Vdbe*,Vdbe*); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT int sqlite3VdbeReleaseMemory(int); #endif UnpackedRecord *sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,void*,int); void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord*); int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); #ifndef NDEBUG void sqlite3VdbeComment(Vdbe*, const char*, ...); # define VdbeComment(X) sqlite3VdbeComment X void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); # define VdbeNoopComment(X) sqlite3VdbeNoopComment X #else # define VdbeComment(X) # define VdbeNoopComment(X) #endif #endif |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** This is the header file for information that is private to the ** VDBE. This information used to all be at the top of the single ** source code file "vdbe.c". When that file became too big (over ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. ** | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ************************************************************************* ** This is the header file for information that is private to the ** VDBE. This information used to all be at the top of the single ** source code file "vdbe.c". When that file became too big (over ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. ** ** $Id: vdbeInt.h,v 1.154 2008/08/13 19:11:48 drh Exp $ */ #ifndef _VDBEINT_H_ #define _VDBEINT_H_ /* ** intToKey() and keyToInt() used to transform the rowid. But with ** the latest versions of the design they are no-ops. |
︙ | ︙ | |||
67 68 69 70 71 72 73 | Bool nullRow; /* True if pointing to a row with no data */ Bool nextRowidValid; /* True if the nextRowid field is valid */ Bool pseudoTable; /* This is a NEW or OLD pseudo-tables of a trigger */ Bool ephemPseudoTable; Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ Bool isTable; /* True if a table requiring integer keys */ Bool isIndex; /* True if an index containing keys only - no data */ | < < | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | Bool nullRow; /* True if pointing to a row with no data */ Bool nextRowidValid; /* True if the nextRowid field is valid */ Bool pseudoTable; /* This is a NEW or OLD pseudo-tables of a trigger */ Bool ephemPseudoTable; Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ Bool isTable; /* True if a table requiring integer keys */ Bool isIndex; /* True if an index containing keys only - no data */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ Btree *pBt; /* Separate file holding temporary table */ int nData; /* Number of bytes in pData */ char *pData; /* Data for a NEW or OLD pseudo-table */ i64 iKey; /* Key for the NEW or OLD pseudo-table row */ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ int nField; /* Number of fields in the header */ i64 seqCount; /* Sequence counter */ sqlite3_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ const sqlite3_module *pModule; /* Module for cursor pVtabCursor */ /* Cached information about the header for the data record that the |
︙ | ︙ | |||
337 338 339 340 341 342 343 | #endif #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT Vdbe *pLruPrev; Vdbe *pLruNext; #endif }; | < < < < < < < < < < < < < < < < < < < < < < | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | #endif #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT Vdbe *pLruPrev; Vdbe *pLruNext; #endif }; /* ** The following are allowed values for Vdbe.magic */ #define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */ #define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */ #define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */ #define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */ |
︙ | ︙ | |||
383 384 385 386 387 388 389 | int sqlite3VdbeSerialTypeLen(u32); u32 sqlite3VdbeSerialType(Mem*, int); int sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int); int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(VdbeFunc*, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); | | < | 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | int sqlite3VdbeSerialTypeLen(u32); u32 sqlite3VdbeSerialType(Mem*, int); int sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int); int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(VdbeFunc*, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); int sqlite3VdbeIdxKeyCompare(Cursor*,UnpackedRecord*,int*); int sqlite3VdbeIdxRowid(BtCursor *, i64 *); int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); int sqlite3VdbeExec(Vdbe*); int sqlite3VdbeList(Vdbe*); int sqlite3VdbeHalt(Vdbe*); int sqlite3VdbeChangeEncoding(Mem *, int); int sqlite3VdbeMemTooBig(Mem*); int sqlite3VdbeMemCopy(Mem*, const Mem*); void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** This file contains code used for creating, destroying, and populating ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** ** $Id: vdbeaux.c,v 1.407 2008/08/13 19:11:48 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" |
︙ | ︙ | |||
1846 1847 1848 1849 1850 1851 1852 | int sqlite3VdbeCursorMoveto(Cursor *p){ if( p->deferredMoveto ){ int res, rc; #ifdef SQLITE_TEST extern int sqlite3_search_count; #endif assert( p->isTable ); | | < | 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 | int sqlite3VdbeCursorMoveto(Cursor *p){ if( p->deferredMoveto ){ int res, rc; #ifdef SQLITE_TEST extern int sqlite3_search_count; #endif assert( p->isTable ); rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); if( rc ) return rc; p->lastRowid = keyToInt(p->movetoTarget); p->rowidIsValid = res==0; if( res<0 ){ rc = sqlite3BtreeNext(p->pCursor, &res); if( rc ) return rc; } #ifdef SQLITE_TEST |
︙ | ︙ | |||
2211 2212 2213 2214 2215 2216 2217 | Mem *pMem; assert( sizeof(Mem)>sizeof(*p) ); nByte = sizeof(Mem)*(pKeyInfo->nField+2); if( nByte>szSpace ){ p = sqlite3DbMallocRaw(pKeyInfo->db, nByte); if( p==0 ) return 0; | | | < | 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 | Mem *pMem; assert( sizeof(Mem)>sizeof(*p) ); nByte = sizeof(Mem)*(pKeyInfo->nField+2); if( nByte>szSpace ){ p = sqlite3DbMallocRaw(pKeyInfo->db, nByte); if( p==0 ) return 0; p->flags = UNPACKED_NEED_FREE | UNPACKED_NEED_DESTROY; }else{ p = pSpace; p->flags = UNPACKED_NEED_DESTROY; } p->pKeyInfo = pKeyInfo; p->nField = pKeyInfo->nField + 1; p->aMem = pMem = &((Mem*)p)[1]; idx = getVarint32(aKey, szHdr); d = szHdr; u = 0; while( idx<szHdr && u<p->nField ){ u32 serial_type; |
︙ | ︙ | |||
2245 2246 2247 2248 2249 2250 2251 | } /* ** This routine destroys a UnpackedRecord object */ void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ if( p ){ | | | | | | | | | | > | < | | | | | < < < | < < < < > | > | 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 | } /* ** This routine destroys a UnpackedRecord object */ void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ if( p ){ if( p->flags & UNPACKED_NEED_DESTROY ){ int i; Mem *pMem; for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){ if( pMem->zMalloc ){ sqlite3VdbeMemRelease(pMem); } } } if( p->flags & UNPACKED_NEED_FREE ){ sqlite3DbFree(p->pKeyInfo->db, p); } } } /* ** This function compares the two table rows or index records ** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero ** or positive integer if key1 is less than, equal to or ** greater than key2. The {nKey1, pKey1} key must be a blob ** created by th OP_MakeRecord opcode of the VDBE. The pPKey2 ** key must be a parsed key such as obtained from ** sqlite3VdbeParseRecord. ** ** Key1 and Key2 do not have to contain the same number of fields. ** The key with fewer fields is usually compares less than the ** longer key. However if the UNPACKED_INCRKEY flags in pPKey2 is set ** and the common prefixes are equal, then key1 is less than key2. ** Or if the UNPACKED_MATCH_PREFIX flag is set and the prefixes are ** equal, then the keys are considered to be equal and ** the parts beyond the common prefix are ignored. ** ** If the UNPACKED_IGNORE_ROWID flag is set, then the last byte of ** the header of pKey1 is ignored. It is assumed that pKey1 is ** an index key, and thus ends with a rowid value. The last byte ** of the header will therefore be the serial type of the rowid: ** one of 1, 2, 3, 4, 5, 6, 8, or 9 - the integer serial types. ** The serial type of the final rowid will always be a single byte. ** By ignoring this last byte of the header, we force the comparison ** to ignore the rowid at the end of key1. */ int sqlite3VdbeRecordCompare( int nKey1, const void *pKey1, /* Left key */ UnpackedRecord *pPKey2 /* Right key */ ){ u32 d1; /* Offset into aKey[] of next data element */ u32 idx1; /* Offset into aKey[] of next header element */ u32 szHdr1; /* Number of bytes in header */ int i = 0; int nField; int rc = 0; const unsigned char *aKey1 = (const unsigned char *)pKey1; KeyInfo *pKeyInfo; Mem mem1; pKeyInfo = pPKey2->pKeyInfo; mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; mem1.flags = 0; mem1.zMalloc = 0; idx1 = getVarint32(aKey1, szHdr1); d1 = szHdr1; if( pPKey2->flags & UNPACKED_IGNORE_ROWID ){ szHdr1--; } nField = pKeyInfo->nField; while( idx1<szHdr1 && i<pPKey2->nField ){ u32 serial_type1; /* Read the serial types for the next element in each key. */ idx1 += getVarint32( aKey1+idx1, serial_type1 ); if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break; |
︙ | ︙ | |||
2341 2342 2343 2344 2345 2346 2347 | } i++; } if( mem1.zMalloc ) sqlite3VdbeMemRelease(&mem1); if( rc==0 ){ /* rc==0 here means that one of the keys ran out of fields and | | | | | | < < < < < < < < < < < < < < < < < < < | 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 | } i++; } if( mem1.zMalloc ) sqlite3VdbeMemRelease(&mem1); if( rc==0 ){ /* rc==0 here means that one of the keys ran out of fields and ** all the fields up to that point were equal. If the UNPACKED_INCRKEY ** flag is set, then break the tie by treating key2 as larger. ** If the UPACKED_PREFIX_MATCH flag is set, then keys with common prefixes ** are considered to be equal. Otherwise, the longer key is the ** larger. As it happens, the pPKey2 will always be the longer ** if there is a difference. */ if( pPKey2->flags & UNPACKED_INCRKEY ){ rc = -1; }else if( pPKey2->flags & UNPACKED_PREFIX_MATCH ){ /* Leave rc==0 */ }else if( idx1<szHdr1 ){ rc = 1; } }else if( pKeyInfo->aSortOrder && i<pKeyInfo->nField && pKeyInfo->aSortOrder[i] ){ rc = -rc; } return rc; } /* ** pCur points at an index entry created using the OP_MakeRecord opcode. ** Read the rowid (the last field in the record) and store it in *rowid. ** Return SQLITE_OK if everything works, or an error code otherwise. */ |
︙ | ︙ | |||
2433 2434 2435 2436 2437 2438 2439 | ** ** pUnpacked may be an unpacked version of pKey,nKey. If pUnpacked is ** supplied it is used in place of pKey,nKey. */ int sqlite3VdbeIdxKeyCompare( Cursor *pC, /* The cursor to compare against */ UnpackedRecord *pUnpacked, /* Unpacked version of pKey and nKey */ | < < < < < < < | < < < < | < < < | 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 | ** ** pUnpacked may be an unpacked version of pKey,nKey. If pUnpacked is ** supplied it is used in place of pKey,nKey. */ int sqlite3VdbeIdxKeyCompare( Cursor *pC, /* The cursor to compare against */ UnpackedRecord *pUnpacked, /* Unpacked version of pKey and nKey */ int *res /* Write the comparison result here */ ){ i64 nCellKey = 0; int rc; BtCursor *pCur = pC->pCursor; Mem m; sqlite3BtreeKeySize(pCur, &nCellKey); if( nCellKey<=0 ){ *res = 0; return SQLITE_OK; } m.db = 0; m.flags = 0; m.zMalloc = 0; rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m); if( rc ){ return rc; } assert( pUnpacked->flags & UNPACKED_IGNORE_ROWID ); *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked); sqlite3VdbeMemRelease(&m); return SQLITE_OK; } /* ** This routine sets the value to be returned by subsequent calls to ** sqlite3_changes() on the database handle 'db'. |
︙ | ︙ |