Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Rename the ValueDecoder object to RowDecoder, in anticipation of enhancing it to be able to extract content from both the key and the value. Simplifications and cleanup of the VdbeCursor object. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
6c7c9133d76d9e9b90b66d692c455dc7 |
User & Date: | drh 2013-07-24 20:07:54.303 |
Context
2013-07-24
| ||
21:38 | Move all VdbeCursor methods into the vdbecursor.c source file. check-in: 5d08b14478 user: drh tags: trunk | |
20:07 | Rename the ValueDecoder object to RowDecoder, in anticipation of enhancing it to be able to extract content from both the key and the value. Simplifications and cleanup of the VdbeCursor object. check-in: 6c7c9133d7 user: drh tags: trunk | |
19:25 | Replace test file distinct.test with the version from sqlite3. This version accounts for NGQP related changes. check-in: 41fc47c1cd user: dan tags: trunk | |
Changes
Changes to src/fts5.c.
︙ | ︙ | |||
2832 2833 2834 2835 2836 2837 2838 | if( rc==SQLITE4_OK ){ rc = sqlite4KVCursorData(pCsr->pCsr, 0, -1, &aData, &nData); } if( rc==SQLITE4_OK ){ int i; | | | | 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 | if( rc==SQLITE4_OK ){ rc = sqlite4KVCursorData(pCsr->pCsr, 0, -1, &aData, &nData); } if( rc==SQLITE4_OK ){ int i; RowDecoder *pCodec; /* The decoder object */ rc = sqlite4VdbeCreateDecoder(db, aData, nData, pInfo->nCol, &pCodec); for(i=0; rc==SQLITE4_OK && i<pInfo->nCol; i++){ rc = sqlite4VdbeExtractColumn(pCodec, i, 0, &pCsr->aMem[i]); } sqlite4VdbeDestroyDecoder(pCodec); } if( rc==SQLITE4_OK ) pCsr->bMemValid = 1; } } |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
214 215 216 217 218 219 220 | p->apCsr[iCur] = 0; } if( SQLITE4_OK==sqlite4VdbeMemGrow(pMem, nByte, 0) ){ p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; memset(pCx, 0, sizeof(VdbeCursor)); pCx->iDb = iDb; pCx->nField = nField; | | | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | p->apCsr[iCur] = 0; } if( SQLITE4_OK==sqlite4VdbeMemGrow(pMem, nByte, 0) ){ p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; memset(pCx, 0, sizeof(VdbeCursor)); pCx->iDb = iDb; pCx->nField = nField; sqlite4_buffer_init(&pCx->sSeekKey, p->db->pEnv->pMM); } return pCx; } /* ** Try to convert a value into a numeric representation if we can ** do so without loss of information. In other words, if the string |
︙ | ︙ | |||
2095 2096 2097 2098 2099 2100 2101 | ** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, ** then the cache of the cursor is reset prior to extracting the column. ** The first OP_Column against a pseudo-table after the value of the content ** register has changed should have this bit set. */ case OP_Column: { KVCursor *pKVCur; /* Cursor for current entry in the KV storage */ | | | 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 | ** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, ** then the cache of the cursor is reset prior to extracting the column. ** The first OP_Column against a pseudo-table after the value of the content ** register has changed should have this bit set. */ case OP_Column: { KVCursor *pKVCur; /* Cursor for current entry in the KV storage */ RowDecoder *pCodec; /* The decoder object */ int p1; /* Index of VdbeCursor to decode */ VdbeCursor *pC; /* The VDBE cursor */ Mem *pDest; /* Where to write the results */ const KVByteArray *aData; /* The content to be decoded */ KVSize nData; /* Size of aData[] in bytes */ Mem *pDefault; /* Default value from P4 */ Mem *pReg; /* */ |
︙ | ︙ | |||
2141 2142 2143 2144 2145 2146 2147 | /* TODO: Fix this somehow... */ int nField = pC->nField; if( pC->pKeyInfo && pC->pKeyInfo->nData ) nField = pC->pKeyInfo->nData; rc = sqlite4VdbeCreateDecoder(db, aData, nData, nField, &pCodec); if( rc==0 ){ pDefault = (pOp->p4type==P4_MEM) ? pOp->p4.pMem : 0; | | | 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 | /* TODO: Fix this somehow... */ int nField = pC->nField; if( pC->pKeyInfo && pC->pKeyInfo->nData ) nField = pC->pKeyInfo->nData; rc = sqlite4VdbeCreateDecoder(db, aData, nData, nField, &pCodec); if( rc==0 ){ pDefault = (pOp->p4type==P4_MEM) ? pOp->p4.pMem : 0; rc = sqlite4VdbeExtractColumn(pCodec, pOp->p2, pDefault, pDest); sqlite4VdbeDestroyDecoder(pCodec); } }else{ sqlite4VdbeMemSetNull(pDest); } UPDATE_MAX_BLOBSIZE(pDest); REGISTER_TRACE(pOp->p3, pDest); |
︙ | ︙ | |||
2761 2762 2763 2764 2765 2766 2767 | }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; | < < < < < < < < | 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 | }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; pCur->iRoot = p2; rc = sqlite4KVStoreOpenCursor(pX, &pCur->pKVCur); pCur->pKeyInfo = pKeyInfo; break; } /* Opcode: OpenEphemeral P1 P2 * P4 P5 ** ** Open a new cursor P1 to a transient table. ** The cursor is always opened read/write even if |
︙ | ︙ | |||
2822 2823 2824 2825 2826 2827 2828 | SQLITE4_KVOPEN_TEMPORARY | SQLITE4_KVOPEN_NO_TRANSACTIONS ); if( rc==SQLITE4_OK ) rc = sqlite4KVStoreOpenCursor(pCx->pTmpKV, &pCx->pKVCur); if( rc==SQLITE4_OK ) rc = sqlite4KVStoreBegin(pCx->pTmpKV, 2); pCx->pKeyInfo = pOp->p4.pKeyInfo; if( pCx->pKeyInfo ) pCx->pKeyInfo->enc = ENC(p->db); | < < | 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 | SQLITE4_KVOPEN_TEMPORARY | SQLITE4_KVOPEN_NO_TRANSACTIONS ); if( rc==SQLITE4_OK ) rc = sqlite4KVStoreOpenCursor(pCx->pTmpKV, &pCx->pKVCur); if( rc==SQLITE4_OK ) rc = sqlite4KVStoreBegin(pCx->pTmpKV, 2); pCx->pKeyInfo = pOp->p4.pKeyInfo; if( pCx->pKeyInfo ) pCx->pKeyInfo->enc = ENC(p->db); break; } /* Opcode: OpenSorter P1 P2 * P4 * ** ** This opcode works like OP_OpenEphemeral except that it opens ** a transient index that is specifically designed to sort large |
︙ | ︙ | |||
2864 2865 2866 2867 2868 2869 2870 | 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->pseudoTableReg = pOp->p2; | < < | 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 | 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->pseudoTableReg = pOp->p2; break; } /* Opcode: Close P1 * * * * ** ** Close a cursor previously opened as P1. If P1 is not ** currently open, this instruction is a no-op. |
︙ | ︙ | |||
2889 2890 2891 2892 2893 2894 2895 | ** ** P1 must be a cursor open on a PRIMARY KEY index. P3 is a cursor open ** on an auxiliary index on the same table. P3 must be pointing to a valid ** index entry. ** ** This opcode seeks cursor P1 so that it points to the PK index entry ** that corresponds to the same table row as the current entry that | | > > > > > | | 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 | ** ** P1 must be a cursor open on a PRIMARY KEY index. P3 is a cursor open ** on an auxiliary index on the same table. P3 must be pointing to a valid ** index entry. ** ** This opcode seeks cursor P1 so that it points to the PK index entry ** that corresponds to the same table row as the current entry that ** cursor P3 points to. The entry must exist. ** ** Actually, the seek is deferred until it is actually needed and if the ** PRIMARY KEY index is never referenced, the seek never takes place. The ** sqlite3VdbeCursorMoveto() does the seek, if necessary. If the target ** row does not exist in the PRIMARY KEY table, then the ** sqlite3VdbeCursorMoveto() routine will throw an SQLITE4_CORRUPT error. */ case OP_SeekPk: { KVByteArray *aKey; /* Key data from cursor pIdx */ KVSize nKey; /* Size of aKey[] in bytes */ VdbeCursor *pPk; /* Cursor P1 */ VdbeCursor *pIdx; /* Cursor P3 */ int nShort; /* Size of aKey[] without PK fields */ |
︙ | ︙ | |||
2917 2918 2919 2920 2921 2922 2923 | }else{ rc = sqlite4KVCursorKey(pIdx->pKVCur, (const KVByteArray **)&aKey, &nKey); if( rc!=SQLITE4_OK ) break; nShort = sqlite4VdbeShortKey(aKey, nKey, pIdx->pKeyInfo->nField - pIdx->pKeyInfo->nPK, 0 ); nVarint = sqlite4VarintLen(pPk->iRoot); | | | | | < < < < | 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 | }else{ rc = sqlite4KVCursorKey(pIdx->pKVCur, (const KVByteArray **)&aKey, &nKey); if( rc!=SQLITE4_OK ) break; nShort = sqlite4VdbeShortKey(aKey, nKey, pIdx->pKeyInfo->nField - pIdx->pKeyInfo->nPK, 0 ); nVarint = sqlite4VarintLen(pPk->iRoot); rc = sqlite4_buffer_resize(&pPk->sSeekKey, nVarint + nKey - nShort); if( rc!=SQLITE4_OK ) break; putVarint32((u8 *)(pPk->sSeekKey.p), pPk->iRoot); memcpy(((u8*)pPk->sSeekKey.p) + nVarint, &aKey[nShort], nKey-nShort); assert( pPk->sSeekKey.n>0 ); } break; } /* Opcode: SeekGe P1 P2 P3 P4 * ** |
︙ | ︙ | |||
2997 2998 2999 3000 3001 3002 3003 | KVSize nProbe; /* Size of aProbe[] in bytes */ int dir; /* KV search dir (+ve or -ve) */ const KVByteArray *aKey; /* Pointer to final cursor key */ KVSize nKey; /* Size of aKey[] in bytes */ pC = p->apCsr[pOp->p1]; pC->nullRow = 0; | | < | 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 | KVSize nProbe; /* Size of aProbe[] in bytes */ int dir; /* KV search dir (+ve or -ve) */ const KVByteArray *aKey; /* Pointer to final cursor key */ KVSize nKey; /* Size of aKey[] in bytes */ pC = p->apCsr[pOp->p1]; pC->nullRow = 0; pC->sSeekKey.n = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p2!=0 ); assert( pC!=0 ); assert( pC->pseudoTableReg==0 ); assert( OP_SeekLe == OP_SeekLt+1 ); assert( OP_SeekGe == OP_SeekLt+2 ); assert( OP_SeekGt == OP_SeekLt+3 ); /* Encode a database key consisting of the contents of the P4 registers ** starting at register P3. Have the vdbecodec module allocate an extra ** free byte at the end of the database key (see below). */ op = pOp->opcode; nField = pOp->p4.i; pIn3 = &aMem[pOp->p3]; |
︙ | ︙ | |||
3075 3076 3077 3078 3079 3080 3081 | KVCursor *pKVCur; KVByteArray *aKey; KVSize nKey; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); | < | 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 | KVCursor *pKVCur; KVByteArray *aKey; KVSize nKey; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pKVCur = pC->pKVCur; rc = sqlite4VdbeEncodeKey(db, aMem+pOp->p2, 1, 1, pC->iRoot, 0, &aKey, &nKey, 0); if( rc==SQLITE4_OK ){ rc = sqlite4KVCursorSeek(pKVCur, aKey, nKey, 0); if( rc==SQLITE4_NOTFOUND ) rc = SQLITE4_CORRUPT_BKPT; } |
︙ | ︙ | |||
3149 3150 3151 3152 3153 3154 3155 | sqlite4_found_count++; #endif alreadyExists = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p4type==P4_INT32 ); pC = p->apCsr[pOp->p1]; | | < | 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 | sqlite4_found_count++; #endif alreadyExists = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); assert( pOp->p4type==P4_INT32 ); pC = p->apCsr[pOp->p1]; pC->sSeekKey.n = 0; assert( pC!=0 ); pIn3 = &aMem[pOp->p3]; assert( pC->pKVCur!=0 ); if( pOp->p4.i>0 ){ rc = sqlite4VdbeEncodeKey( db, pIn3, pOp->p4.i, pOp->p4.i + (pOp->p5 & OPFLAG_PARTIALKEY), pC->iRoot, pC->pKeyInfo, &pProbe, &nProbe, 0 ); pFree = pProbe; }else{ |
︙ | ︙ | |||
3499 3500 3501 3502 3503 3504 3505 | ** P1 must not be pseudo-table. It has to be a real table. */ case OP_Delete: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); | | | 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 | ** P1 must not be pseudo-table. It has to be a real table. */ case OP_Delete: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->sSeekKey.n==0 ); rc = sqlite4KVCursorDelete(pC->pKVCur); if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; break; } /* Opcode: ResetCount * * * * * ** |
︙ | ︙ | |||
3717 3718 3719 3720 3721 3722 3723 | KVSize nKey; int n; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; rc = sqlite4VdbeCursorMoveto(db, pC); if( rc!=SQLITE4_OK ) break; | | | 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 | KVSize nKey; int n; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; rc = sqlite4VdbeCursorMoveto(db, pC); if( rc!=SQLITE4_OK ) break; assert( pC->sSeekKey.n==0 ); assert( pC->pseudoTableReg==0 ); if( pC->nullRow ){ pOut->flags = MEM_Null; break; #ifndef SQLITE4_OMIT_VIRTUALTABLE }else if( pC->pVtabCursor ){ pVtab = pC->pVtabCursor->pVtab; |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
33 34 35 36 37 38 39 | /* Opaque type used by code in vdbesort.c */ typedef struct VdbeSorter VdbeSorter; /* Opaque type used by the explainer */ typedef struct Explain Explain; /* Opaque type used by vdbecodec.c */ | | | < < < < < < < < | > | < < < < | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | /* Opaque type used by code in vdbesort.c */ typedef struct VdbeSorter VdbeSorter; /* Opaque type used by the explainer */ typedef struct Explain Explain; /* Opaque type used by vdbecodec.c */ typedef struct RowDecoder RowDecoder; /* ** A cursor is a pointer into a single database. ** The cursor can seek to an entry with a particular key, or ** loop over all entries. You can also insert new ** entries or retrieve the key or data from the entry that the cursor ** is currently pointing to. ** ** Every cursor that the virtual machine has open is represented by an ** instance of the following structure. */ struct VdbeCursor { KVCursor *pKVCur; /* The cursor structure of the storage engine */ KVStore *pTmpKV; /* Separate file holding a temporary table */ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ int iDb; /* Index of cursor database in db->aDb[] (or -1) */ int iRoot; /* Root page of the table */ int pseudoTableReg; /* Register holding pseudotable content. */ int nField; /* Number of fields in the header */ Bool nullRow; /* True if pointing to a row with no data */ i64 seqCount; /* Sequence counter */ VdbeSorter *pSorter; /* Sorter object for OP_SorterOpen cursors */ Fts5Cursor *pFts; /* Fts5 cursor object (or NULL) */ sqlite4_vtab_cursor *pVtabCursor; /* The cursor for a virtual table */ const sqlite4_module *pModule; /* Module for cursor pVtabCursor */ sqlite4_buffer sSeekKey; /* Key for deferred seek */ }; /* ** When a sub-program is executed (OP_Program), a structure of this type ** is allocated to store the current value of the program counter, as ** well as the current memory cell array and various other frame specific ** values stored in the Vdbe struct. When the sub-program is finished, |
︙ | ︙ | |||
133 134 135 136 137 138 139 140 141 142 143 144 145 146 | sqlite4 *db; /* The associated database connection */ char *z; /* String or BLOB value */ union { sqlite4_num num; /* Numeric value used by MEM_Int and/or MEM_Real */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ } u; int n; /* Number of characters in string value, excluding '\0' */ u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 type; /* One of SQLITE4_NULL, _TEXT, _INTEGER, etc */ u8 enc; /* SQLITE4_UTF8, SQLITE4_UTF16BE, SQLITE4_UTF16LE */ #ifdef SQLITE4_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ | > | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | sqlite4 *db; /* The associated database connection */ char *z; /* String or BLOB value */ union { sqlite4_num num; /* Numeric value used by MEM_Int and/or MEM_Real */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ sqlite4_int64 iOfst;/* Used when flags==MEM_FromKey */ } u; int n; /* Number of characters in string value, excluding '\0' */ u16 flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */ u8 type; /* One of SQLITE4_NULL, _TEXT, _INTEGER, etc */ u8 enc; /* SQLITE4_UTF8, SQLITE4_UTF16BE, SQLITE4_UTF16LE */ #ifdef SQLITE4_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ |
︙ | ︙ | |||
167 168 169 170 171 172 173 | #define MEM_Str 0x0002 /* Value is a string */ #define MEM_Int 0x0004 /* Value is an integer */ #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_RowSet 0x0020 /* Value is a RowSet object */ #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ #define MEM_Invalid 0x0080 /* Value is undefined */ | | > > > > > > > > > | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | #define MEM_Str 0x0002 /* Value is a string */ #define MEM_Int 0x0004 /* Value is an integer */ #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_RowSet 0x0020 /* Value is a RowSet object */ #define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ #define MEM_Invalid 0x0080 /* Value is undefined */ #define MEM_TypeMask 0x01ff /* Mask of type bits */ /* ** The following flag is used in the return from sqlite4VdbeDecodeValue() ** to signal that the value is stored in the key of the record. If this ** bit is set and then the Mem.n field holds an offset into the key for ** the start of the value. If Mem.type is set to SQLITE_REAL then numeric ** keys are interpreted as real numbers instead of integers. */ #define MEM_FromKey 0x0100 /* Actual value stored in key */ /* Whenever Mem contains a valid string or blob representation, one of ** the following flags must be set to determine the memory management ** policy for Mem.z. The MEM_Term flag tells us whether or not the ** string is \000 or \u0000 terminated */ |
︙ | ︙ | |||
349 350 351 352 353 354 355 | void sqlite4VdbeDeleteAuxData(VdbeFunc*, int); int sqlite4VdbeCreateDecoder( sqlite4 *db, /* The database connection */ const unsigned char *aIn, /* The input data blob */ int nIn, /* Number of bytes in aIn[] */ int mxCol, /* Maximum number of columns in aIn[] */ | | | | | | 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 | void sqlite4VdbeDeleteAuxData(VdbeFunc*, int); int sqlite4VdbeCreateDecoder( sqlite4 *db, /* The database connection */ const unsigned char *aIn, /* The input data blob */ int nIn, /* Number of bytes in aIn[] */ int mxCol, /* Maximum number of columns in aIn[] */ RowDecoder **ppOut /* The newly generated decoder object */ ); int sqlite4VdbeDestroyDecoder(RowDecoder *pDecoder); int sqlite4VdbeExtractColumn( RowDecoder *pDecoder, /* The decoder for the whole string */ int iVal, /* Index of the value to decode. First is 0 */ Mem *pDefault, /* The default value. Often NULL */ Mem *pOut /* Write the result here */ ); int sqlite4VdbeEncodeData( sqlite4 *db, /* The database connection */ Mem *aIn, /* Array of values to encode */ |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1497 1498 1499 1500 1501 1502 1503 | sqlite4Fts5Close(pCx->pFts); if( pCx->pKVCur ){ sqlite4KVCursorClose(pCx->pKVCur); } if( pCx->pTmpKV ){ sqlite4KVStoreClose(pCx->pTmpKV); } | | | 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 | sqlite4Fts5Close(pCx->pFts); if( pCx->pKVCur ){ sqlite4KVCursorClose(pCx->pKVCur); } if( pCx->pTmpKV ){ sqlite4KVStoreClose(pCx->pTmpKV); } sqlite4_buffer_clear(&pCx->sSeekKey); #ifndef SQLITE4_OMIT_VIRTUALTABLE if( pCx->pVtabCursor ){ sqlite4_vtab_cursor *pVtabCursor = pCx->pVtabCursor; const sqlite4_module *pModule = pCx->pModule; p->inVtabMethod = 1; pModule->xClose(pVtabCursor); p->inVtabMethod = 0; |
︙ | ︙ | |||
2283 2284 2285 2286 2287 2288 2289 | ** ** If the operation is a success, SQLITE4_OK is returned. Or, if the ** required entry is not found in the PK index, SQLITE4_CORRUPT. Or if ** some other error occurs, an error code is returned. */ int sqlite4VdbeCursorMoveto(sqlite4 *db, VdbeCursor *pPk){ int rc = SQLITE4_OK; /* Return code */ | | | | < | 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 | ** ** If the operation is a success, SQLITE4_OK is returned. Or, if the ** required entry is not found in the PK index, SQLITE4_CORRUPT. Or if ** some other error occurs, an error code is returned. */ int sqlite4VdbeCursorMoveto(sqlite4 *db, VdbeCursor *pPk){ int rc = SQLITE4_OK; /* Return code */ if( pPk->sSeekKey.n!=0 ){ assert( pPk->pKeyInfo->nPK==0 ); rc = sqlite4KVCursorSeek(pPk->pKVCur, pPk->sSeekKey.p, pPk->sSeekKey.n, 0); if( rc==SQLITE4_NOTFOUND ){ rc = SQLITE4_CORRUPT_BKPT; } pPk->nullRow = 0; pPk->sSeekKey.n = 0; } return rc; } |
Changes to src/vdbecodec.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 | ** insertion and reading from the key/value storage engine. */ #include "sqliteInt.h" #include "vdbeInt.h" /* ** The decoder object. */ | > > > > > > > > > | | | | | > > > > > > | | | 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 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | ** insertion and reading from the key/value storage engine. */ #include "sqliteInt.h" #include "vdbeInt.h" /* ** The decoder object. ** ** An instance of this object is used to extract individual columns (numbers, ** strings, blobs, or NULLs) from a row of a table or index. Usually the ** content is extract from the value side of the key/value pair, though ** sometimes information might be taken from the key as well. ** ** When the VDBE needs to extract multiple columns from the same row, it will ** try to reuse a single decoder object. The decoder, therefore, should attempt ** to cache any intermediate results that might be useful on later invocations. */ struct RowDecoder { sqlite4 *db; /* The database connection */ const u8 *a; /* Content to be decoded */ int n; /* Bytes of content in a[] */ int mxCol; /* Maximum number of columns */ }; /* ** Create an object that can be used to decode fields of the data encoding. ** ** The aIn[] value must remain stable for the life of the decoder. */ int sqlite4VdbeCreateDecoder( sqlite4 *db, /* The database connection */ const unsigned char *aIn, /* The input data blob */ int nIn, /* Number of bytes in aIn[] */ int mxCol, /* Maximum number of columns in aIn[] */ RowDecoder **ppOut /* The newly generated decoder object */ ){ RowDecoder *p; p = sqlite4DbMallocZero(db, sizeof(*p)); *ppOut = p; if( p==0 ) return SQLITE4_NOMEM; p->db = db; p->a = aIn; p->n = nIn; p->mxCol = mxCol; return SQLITE4_OK; } /* ** Destroy a decoder object previously created ** using sqlite4VdbeCreateDecoder(). */ int sqlite4VdbeDestroyDecoder(RowDecoder *p){ if( p ){ sqlite4DbFree(p->db, p); } return SQLITE4_OK; } /* ** Decode a single value from a data string. Store that value in pOut. ** ** If the value is a FROM-KEY reference (header codes 22 and 23) then the ** pOut->flags field is set to MEM_FromKey and pOut->iOfst is the offset into ** the key of the start of the actual value. The pOut->type field is set to ** SQLITE_FLOAT if a numeric value extracted from the key should be interpreted ** as a floating point even if it has no fractional part. */ int sqlite4VdbeExtractColumn( RowDecoder *p, /* The decoder for the whole string */ int iVal, /* Index of the value to decode. First is 0 */ Mem *pDefault, /* The default value. Often NULL */ Mem *pOut /* Write the result here */ ){ u32 size; /* Size of a field */ sqlite4_uint64 ofst; /* Offset to the payload */ sqlite4_uint64 type; /* Datatype */ |
︙ | ︙ | |||
137 138 139 140 141 142 143 | num.m = x; num.e = (e >> 2); if( e & 0x02 ) num.e = -1 * num.e; if( e & 0x01 ) num.sign = 1; pOut->u.num = num; MemSetTypeFlag(pOut, MEM_Real); | | > > > | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | num.m = x; num.e = (e >> 2); if( e & 0x02 ) num.e = -1 * num.e; if( e & 0x01 ) num.sign = 1; pOut->u.num = num; MemSetTypeFlag(pOut, MEM_Real); }else if( type<=23 ){ MemSetTypeFlag(pOut, MEM_FromKey); pOut->u.iOfst = subtype; pOut->type = type==23 ? SQLITE4_FLOAT : SQLITE4_INTEGER; }else if( cclass==0 ){ if( size==0 ){ sqlite4VdbeMemSetStr(pOut, "", 0, SQLITE4_UTF8, SQLITE4_TRANSIENT, 0); }else if( p->a[ofst]>0x02 ){ sqlite4VdbeMemSetStr(pOut, (char*)(p->a+ofst), size, SQLITE4_UTF8, SQLITE4_TRANSIENT, 0); }else{ |
︙ | ︙ |