Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | More simplifications to vdbe.c. Remove a NEVER() from vdbe.c that is possible after all. (CVS 6796) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
c8f009bd24cb4e4b5ce9fbfd8ab09921 |
User & Date: | drh 2009-06-22 11:10:48.000 |
Context
2009-06-22
| ||
12:05 | Make sure sqlite3BtreeCreateTable() returns an error code if the largest rootpage field is invalid in auto_vacuum mode. Update file-format comments to describe all of the "meta" values. (CVS 6797) (check-in: bda38f5e86 user: drh tags: trunk) | |
11:10 | More simplifications to vdbe.c. Remove a NEVER() from vdbe.c that is possible after all. (CVS 6796) (check-in: c8f009bd24 user: drh tags: trunk) | |
05:43 | If an OOM error occurs just after obtaining a shared lock on the database file, release the lock before returning. (CVS 6795) (check-in: 971a9650f6 user: danielk1977 tags: trunk) | |
Changes
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.859 2009/06/22 11:10:48 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor ** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes. The test |
︙ | ︙ | |||
2463 2464 2465 2466 2467 2468 2469 | ** will be allocated and initialized. ** ** The statement is begun on the database file with index P1. The main ** database file has an index of 0 and the file used for temporary tables ** has an index of 1. */ case OP_Statement: { | < < | | | | | 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 | ** will be allocated and initialized. ** ** The statement is begun on the database file with index P1. The main ** database file has an index of 0 and the file used for temporary tables ** has an index of 1. */ case OP_Statement: { Btree *pBt; if( db->autoCommit==0 || db->activeVdbeCnt>1 ){ assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( db->aDb[pOp->p1].pBt!=0 ); pBt = db->aDb[pOp->p1].pBt; assert( sqlite3BtreeIsInTrans(pBt) ); assert( (p->btreeMask & (1<<pOp->p1))!=0 ); if( p->iStatement==0 ){ assert( db->nStatement>=0 && db->nSavepoint>=0 ); db->nStatement++; p->iStatement = db->nSavepoint + db->nStatement; } rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); } |
︙ | ︙ | |||
2713 2714 2715 2716 2717 2718 2719 | ** write transaction must be started before any changes can be made to the ** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained ** on the file. ** ** If P2 is zero, then a read-lock is obtained on the database file. */ case OP_Transaction: { | < < | | | | 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 | ** write transaction must be started before any changes can be made to the ** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained ** on the file. ** ** If P2 is zero, then a read-lock is obtained on the database file. */ case OP_Transaction: { Btree *pBt; assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( (p->btreeMask & (1<<pOp->p1))!=0 ); pBt = db->aDb[pOp->p1].pBt; if( pBt ){ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2); if( rc==SQLITE_BUSY ){ p->pc = pc; p->rc = rc = SQLITE_BUSY; goto vdbe_return; |
︙ | ︙ | |||
2908 2909 2910 2911 2912 2913 2914 | ** ** See also OpenRead. */ case OP_OpenRead: case OP_OpenWrite: { int nField; KeyInfo *pKeyInfo; | < < | 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 | ** ** See also OpenRead. */ case OP_OpenRead: case OP_OpenWrite: { int nField; KeyInfo *pKeyInfo; int p2; int iDb; int wrFlag; Btree *pX; VdbeCursor *pCur; Db *pDb; int flags; nField = 0; pKeyInfo = 0; p2 = pOp->p2; iDb = pOp->p3; assert( iDb>=0 && iDb<db->nDb ); assert( (p->btreeMask & (1<<iDb))!=0 ); pDb = &db->aDb[iDb]; pX = pDb->pBt; assert( pX!=0 ); |
︙ | ︙ | |||
2941 2942 2943 2944 2945 2946 2947 | } if( pOp->p5 ){ assert( p2>0 ); assert( p2<=p->nMem ); pIn2 = &p->aMem[p2]; sqlite3VdbeMemIntegerify(pIn2); p2 = (int)pIn2->u.i; | | < > | | 2935 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 | } if( pOp->p5 ){ assert( p2>0 ); assert( p2<=p->nMem ); pIn2 = &p->aMem[p2]; sqlite3VdbeMemIntegerify(pIn2); p2 = (int)pIn2->u.i; if( p2<2 ) { rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } } if( pOp->p4type==P4_KEYINFO ){ pKeyInfo = pOp->p4.pKeyInfo; pKeyInfo->enc = ENC(p->db); nField = pKeyInfo->nField+1; }else if( pOp->p4type==P4_INT32 ){ nField = pOp->p4.i; } assert( pOp->p1>=0 ); pCur = allocateCursor(p, pOp->p1, nField, iDb, 1); if( pCur==0 ) goto no_mem; pCur->nullRow = 1; rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor); pCur->pKeyInfo = pKeyInfo; switch( rc ){ case SQLITE_OK: { |
︙ | ︙ | |||
3021 3022 3023 3024 3025 3026 3027 | ** This opcode was once called OpenTemp. But that created ** confusion because the term "temp table", might refer either ** to a TEMP table at the SQL level, or to a table opened by ** this opcode. Then this opcode was call OpenVirtual. But ** that created confusion with the whole virtual-table idea. */ case OP_OpenEphemeral: { | < < | | | 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 | ** This opcode was once called OpenTemp. But that created ** confusion because the term "temp table", might refer either ** to a TEMP table at the SQL level, or to a table opened by ** this opcode. Then this opcode was call OpenVirtual. But ** that created confusion with the whole virtual-table idea. */ case OP_OpenEphemeral: { VdbeCursor *pCx; static const int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TRANSIENT_DB; assert( pOp->p1>=0 ); pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags, &pCx->pBt); if( rc==SQLITE_OK ){ rc = sqlite3BtreeBeginTrans(pCx->pBt, 1); } |
︙ | ︙ | |||
3091 3092 3093 3094 3095 3096 3097 | ** memory cell containing the row data is not overwritten until the ** pseudo table is closed (or a new row is inserted into it). ** ** P3 is the number of fields in the records that will be stored by ** the pseudo-table. */ case OP_OpenPseudo: { | < < | | < < | | | | 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 | ** memory cell containing the row data is not overwritten until the ** pseudo table is closed (or a new row is inserted into it). ** ** P3 is the number of fields in the records that will be stored by ** the pseudo-table. */ case OP_OpenPseudo: { VdbeCursor *pCx; assert( pOp->p1>=0 ); pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; pCx->pseudoTable = 1; pCx->ephemPseudoTable = (u8)pOp->p2; pCx->isTable = 1; pCx->isIndex = 0; break; } /* Opcode: Close P1 * * * * ** ** Close a cursor previously opened as P1. If P1 is not ** currently open, this instruction is a no-op. */ case OP_Close: { assert( pOp->p1>=0 && pOp->p1<p->nCursor ); sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); p->apCsr[pOp->p1] = 0; break; } /* Opcode: SeekGe P1 P2 P3 P4 * ** ** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), ** use the value in register P3 as the key. If cursor P1 refers |
︙ | ︙ | |||
3176 3177 3178 3179 3180 3181 3182 | ** ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt */ case OP_SeekLt: /* jump, in3 */ case OP_SeekLe: /* jump, in3 */ case OP_SeekGe: /* jump, in3 */ case OP_SeekGt: { /* jump, in3 */ | < < | | | 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 | ** ** See also: Found, NotFound, Distinct, SeekGt, SeekGe, SeekLt */ case OP_SeekLt: /* jump, in3 */ case OP_SeekLe: /* jump, in3 */ case OP_SeekGe: /* jump, in3 */ case OP_SeekGt: { /* jump, in3 */ int res; int oc; VdbeCursor *pC; UnpackedRecord r; int nField; i64 iKey; /* The rowid we are to seek to */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p2!=0 ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); if( pC->pCursor!=0 ){ oc = pOp->opcode; pC->nullRow = 0; if( pC->isTable ){ /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do |
︙ | ︙ | |||
3318 3319 3320 3321 3322 3323 3324 | ** for P1 to move so that it points to the rowid given by P2. ** ** This is actually a deferred seek. Nothing actually happens until ** the cursor is used to read a record. That way, if no reads ** occur, no unnecessary I/O happens. */ case OP_Seek: { /* in2 */ | < < | | | 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 | ** for P1 to move so that it points to the rowid given by P2. ** ** This is actually a deferred seek. Nothing actually happens until ** the cursor is used to read a record. That way, if no reads ** occur, no unnecessary I/O happens. */ case OP_Seek: { /* in2 */ VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); if( ALWAYS(pC->pCursor!=0) ){ assert( pC->isTable ); pC->nullRow = 0; pC->movetoTarget = sqlite3VdbeIntValue(pIn2); pC->rowidIsValid = 0; pC->deferredMoveto = 1; |
︙ | ︙ | |||
3550 3551 3552 3553 3554 3555 3556 | ** ** Find the next available sequence number for cursor P1. ** Write the sequence number into register P2. ** The sequence number on the cursor is incremented after this ** instruction. */ case OP_Sequence: { /* out2-prerelease */ | < | | | | 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 | ** ** Find the next available sequence number for cursor P1. ** Write the sequence number into register P2. ** The sequence number on the cursor is incremented after this ** instruction. */ case OP_Sequence: { /* out2-prerelease */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( p->apCsr[pOp->p1]!=0 ); pOut->u.i = p->apCsr[pOp->p1]->seqCount++; MemSetTypeFlag(pOut, MEM_Int); break; } /* Opcode: NewRowid P1 P2 P3 * * ** |
︙ | ︙ | |||
3713 3714 3715 3716 3717 3718 3719 | ** This instruction only works on tables. The equivalent instruction ** for indices is OP_IdxInsert. */ case OP_Insert: { Mem *pData; Mem *pKey; i64 iKey; /* The integer ROWID or key for the record to be inserted */ | < < | | | 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 | ** This instruction only works on tables. The equivalent instruction ** for indices is OP_IdxInsert. */ case OP_Insert: { Mem *pData; Mem *pKey; i64 iKey; /* The integer ROWID or key for the record to be inserted */ VdbeCursor *pC; int nZero; int seekResult; const char *zDb; const char *zTbl; int op; pData = &p->aMem[pOp->p2]; pKey = &p->aMem[pOp->p3]; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->pCursor!=0 || pC->pseudoTable ); assert( pKey->flags & MEM_Int ); assert( pC->isTable ); REGISTER_TRACE(pOp->p2, pData); REGISTER_TRACE(pOp->p3, pKey); |
︙ | ︙ | |||
3814 3815 3816 3817 3818 3819 3820 | ** ** If P4 is not NULL, then it is the name of the table that P1 is ** pointing to. The update hook will be invoked, if it exists. ** If P4 is not NULL then the P1 cursor must have been positioned ** using OP_NotFound prior to invoking this opcode. */ case OP_Delete: { | < < | | | 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 | ** ** If P4 is not NULL, then it is the name of the table that P1 is ** pointing to. The update hook will be invoked, if it exists. ** If P4 is not NULL then the P1 cursor must have been positioned ** using OP_NotFound prior to invoking this opcode. */ case OP_Delete: { i64 iKey; VdbeCursor *pC; iKey = 0; 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 */ /* If the update-hook will be invoked, set iKey to the rowid of the ** row being deleted. */ if( db->xUpdateCallback && pOp->p4.z ){ |
︙ | ︙ | |||
3888 3889 3890 3891 3892 3893 3894 | ** it is found in the database file. ** ** If the P1 cursor must be pointing to a valid row (not a NULL row) ** of a real table, not a pseudo-table. */ case OP_RowKey: case OP_RowData: { | < < | | | 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 | ** it is found in the database file. ** ** If the P1 cursor must be pointing to a valid row (not a NULL row) ** of a real table, not a pseudo-table. */ case OP_RowKey: case OP_RowData: { VdbeCursor *pC; BtCursor *pCrsr; u32 n; i64 n64; pOut = &p->aMem[pOp->p2]; /* Note that RowKey and RowData are really exactly the same instruction */ assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC->isTable || pOp->opcode==OP_RowKey ); assert( pC->isIndex || pOp->opcode==OP_RowData ); assert( pC!=0 ); assert( pC->nullRow==0 ); assert( pC->pseudoTable==0 ); assert( pC->pCursor!=0 ); pCrsr = pC->pCursor; |
︙ | ︙ | |||
3947 3948 3949 3950 3951 3952 3953 | ** P1 is currently point to. ** ** P1 can be either an ordinary table or a virtual table. There used to ** be a separate OP_VRowid opcode for use with virtual tables, but this ** one opcode now works for both table types. */ case OP_Rowid: { /* out2-prerelease */ | < < | | | 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 | ** P1 is currently point to. ** ** P1 can be either an ordinary table or a virtual table. There used to ** be a separate OP_VRowid opcode for use with virtual tables, but this ** one opcode now works for both table types. */ case OP_Rowid: { /* out2-prerelease */ VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); if( pC->nullRow ){ /* Do nothing so that reg[P2] remains NULL */ break; }else if( pC->deferredMoveto ){ v = pC->movetoTarget; }else if( pC->pseudoTable ){ |
︙ | ︙ | |||
3998 3999 4000 4001 4002 4003 4004 | /* Opcode: NullRow P1 * * * * ** ** Move the cursor P1 to a null row. Any OP_Column operations ** that occur while the cursor is on the null row will always ** write a NULL. */ case OP_NullRow: { | < < | | < < | | | 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 | /* Opcode: NullRow P1 * * * * ** ** Move the cursor P1 to a null row. Any OP_Column operations ** that occur while the cursor is on the null row will always ** write a NULL. */ case OP_NullRow: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pC->nullRow = 1; pC->rowidIsValid = 0; if( pC->pCursor ){ sqlite3BtreeClearCursor(pC->pCursor); } break; } /* Opcode: Last P1 P2 * * * ** ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the last entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ case OP_Last: { /* jump */ VdbeCursor *pC; BtCursor *pCrsr; int res; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->pCursor; assert( pCrsr!=0 ); rc = sqlite3BtreeLast(pCrsr, &res); pC->nullRow = (u8)res; pC->deferredMoveto = 0; pC->rowidIsValid = 0; |
︙ | ︙ | |||
4074 4075 4076 4077 4078 4079 4080 | ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ case OP_Rewind: { /* jump */ | < < | | | 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 | ** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through ** to the following instruction. */ case OP_Rewind: { /* jump */ VdbeCursor *pC; BtCursor *pCrsr; int res; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); if( (pCrsr = pC->pCursor)!=0 ){ rc = sqlite3BtreeFirst(pCrsr, &res); pC->atFirst = res==0 ?1:0; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; pC->rowidIsValid = 0; |
︙ | ︙ | |||
4164 4165 4166 4167 4168 4169 4170 | ** P3 is a flag that provides a hint to the b-tree layer that this ** insert is likely to be an append. ** ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. */ case OP_IdxInsert: { /* in2 */ | < | | | | > | 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 | ** P3 is a flag that provides a hint to the b-tree layer that this ** insert is likely to be an append. ** ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. */ case OP_IdxInsert: { /* in2 */ VdbeCursor *pC; BtCursor *pCrsr; int nKey; const char *zKey; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pIn2->flags & MEM_Blob ); pCrsr = pC->pCursor; if( pCrsr!=0 ){ assert( pC->isTable==0 ); rc = ExpandBlob(pIn2); if( rc==SQLITE_OK ){ nKey = pIn2->n; zKey = pIn2->z; rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0, 0, pOp->p3, ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) |
︙ | ︙ | |||
4197 4198 4199 4200 4201 4202 4203 | /* Opcode: IdxDelete P1 P2 P3 * * ** ** The content of P3 registers starting at register P2 form ** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. */ case OP_IdxDelete: { | < < | > | | > | 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 | /* Opcode: IdxDelete P1 P2 P3 * * ** ** The content of P3 registers starting at register P2 form ** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. */ case OP_IdxDelete: { VdbeCursor *pC; BtCursor *pCrsr; assert( pOp->p3>0 ); assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->pCursor; if( pCrsr!=0 ){ int res; UnpackedRecord r; r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p3; r.flags = 0; r.aMem = &p->aMem[pOp->p2]; rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); |
︙ | ︙ | |||
4232 4233 4234 4235 4236 4237 4238 | ** Write into register P2 an integer which is the last entry in the record at ** the end of the index key pointed to by cursor P1. This integer should be ** the rowid of the table entry to which this index entry points. ** ** See also: Rowid, MakeRecord. */ case OP_IdxRowid: { /* out2-prerelease */ | < | | | | > | 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 | ** Write into register P2 an integer which is the last entry in the record at ** the end of the index key pointed to by cursor P1. This integer should be ** the rowid of the table entry to which this index entry points. ** ** See also: Rowid, MakeRecord. */ case OP_IdxRowid: { /* out2-prerelease */ BtCursor *pCrsr; VdbeCursor *pC; i64 rowid; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->pCursor; if( pCrsr!=0 ){ rc = sqlite3VdbeCursorMoveto(pC); if( rc ) goto abort_due_to_error; assert( pC->deferredMoveto==0 ); assert( pC->isTable==0 ); if( !pC->nullRow ){ rc = sqlite3VdbeIdxRowid(pCrsr, &rowid); if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
4285 4286 4287 4288 4289 4290 4291 | ** Otherwise fall through to the next instruction. ** ** If P5 is non-zero then the key value is increased by an epsilon prior ** to the comparison. This makes the opcode work like IdxLE. */ case OP_IdxLT: /* jump, in3 */ case OP_IdxGE: { /* jump, in3 */ | < | | | | | 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 | ** Otherwise fall through to the next instruction. ** ** If P5 is non-zero then the key value is increased by an epsilon prior ** to the comparison. This makes the opcode work like IdxLE. */ case OP_IdxLT: /* jump, in3 */ case OP_IdxGE: { /* jump, in3 */ VdbeCursor *pC; int res; UnpackedRecord r; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); if( pC->pCursor!=0 ){ assert( pC->deferredMoveto==0 ); assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p4.i; if( pOp->p5 ){ r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; |
︙ | ︙ |