Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add decoder logic to facilitate extracting column values from the key of a key/value pair for a row. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
30167422e474fd427d033f0db087f033 |
User & Date: | drh 2013-07-26 15:30:15.319 |
Context
2013-07-26
| ||
16:20 | Change the data encoding (again) to make content-in-key use fewer bytes, since one suspects that this will become a common encoding. FILE FORMAT CHANGE. check-in: 0275ee48db user: drh tags: trunk | |
15:30 | Add decoder logic to facilitate extracting column values from the key of a key/value pair for a row. check-in: 30167422e4 user: drh tags: trunk | |
2013-07-25
| ||
23:26 | Add the kvreplace(K,V) pragma for use in testing. check-in: b5ceafc26f user: drh tags: trunk | |
Changes
Changes to src/pragma.c.
︙ | ︙ | |||
651 652 653 654 655 656 657 | int r1, r2; Vdbe *v = sqlite4GetVdbe(pParse); pParse->nTab = 1; pParse->nMem = 3; sqlite4BeginWriteOperation(pParse, 0, iDb); r1 = sqlite4ExprCodeTarget(pParse, pList->a[0].pExpr, 1); sqlite4VdbeAddOp4(v, OP_HaltIfNull, SQLITE4_CONSTRAINT, OE_Abort, | | | | 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 | int r1, r2; Vdbe *v = sqlite4GetVdbe(pParse); pParse->nTab = 1; pParse->nMem = 3; sqlite4BeginWriteOperation(pParse, 0, iDb); r1 = sqlite4ExprCodeTarget(pParse, pList->a[0].pExpr, 1); sqlite4VdbeAddOp4(v, OP_HaltIfNull, SQLITE4_CONSTRAINT, OE_Abort, r1, "key may not be null", P4_STATIC); sqlite4VdbeAddOp1(v, OP_ToBlob, r1); r2 = sqlite4ExprCodeTarget(pParse, pList->a[1].pExpr, 2); sqlite4VdbeAddOp4(v, OP_HaltIfNull, SQLITE4_CONSTRAINT, OE_Abort, r2, "value may not be null", P4_STATIC); sqlite4VdbeAddOp1(v, OP_ToBlob, r2); sqlite4VdbeAddOp0(v, OP_OpenWrite); sqlite4VdbeAddOp3(v, OP_IdxInsert, 0, r2, r1); sqlite4VdbeAddOp0(v, OP_Halt); }else #endif /* SQLITE4_DEBUG |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 | case OP_NewRowid: { /* out2-prerelease */ i64 v; /* The new rowid */ VdbeCursor *pC; /* Cursor of table to get the new rowid */ const KVByteArray *aKey; /* Key of an existing row */ KVSize nKey; /* Size of the existing row key */ int n; /* Number of bytes decoded */ i64 i3; /* Integer value from pIn3 */ v = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); /* Some compilers complain about constants of the form 0x7fffffffffffffff. | > | 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 | case OP_NewRowid: { /* out2-prerelease */ i64 v; /* The new rowid */ VdbeCursor *pC; /* Cursor of table to get the new rowid */ const KVByteArray *aKey; /* Key of an existing row */ KVSize nKey; /* Size of the existing row key */ int n; /* Number of bytes decoded */ i64 i3; /* Integer value from pIn3 */ sqlite4_num vNum; /* Intermediate result */ v = 0; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); /* Some compilers complain about constants of the form 0x7fffffffffffffff. |
︙ | ︙ | |||
3293 3294 3295 3296 3297 3298 3299 | rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey); if( rc==SQLITE4_OK ){ n = sqlite4GetVarint64((u8 *)aKey, nKey, (u64 *)&v); if( n==0 ) rc = SQLITE4_CORRUPT_BKPT; if( v!=pC->iRoot ) rc = SQLITE4_CORRUPT_BKPT; } if( rc==SQLITE4_OK ){ | | | | 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 | rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey); if( rc==SQLITE4_OK ){ n = sqlite4GetVarint64((u8 *)aKey, nKey, (u64 *)&v); if( n==0 ) rc = SQLITE4_CORRUPT_BKPT; if( v!=pC->iRoot ) rc = SQLITE4_CORRUPT_BKPT; } if( rc==SQLITE4_OK ){ n = sqlite4VdbeDecodeNumericKey(&aKey[n], nKey-n, &vNum); if( n==0 || (v = sqlite4_num_to_int64(vNum,0))==LARGEST_INT64 ){ assert( 0 ); rc = SQLITE4_FULL; } } }else{ break; } |
︙ | ︙ | |||
3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 | */ case OP_Rowid: { /* out2-prerelease */ VdbeCursor *pC; i64 v; const KVByteArray *aKey; KVSize nKey; int n; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; rc = sqlite4VdbeCursorMoveto(pC); if( rc!=SQLITE4_OK ) break; assert( pC->sSeekKey.n==0 ); assert( pC->pPseudoTab==0 ); | > | 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 | */ case OP_Rowid: { /* out2-prerelease */ VdbeCursor *pC; i64 v; const KVByteArray *aKey; KVSize nKey; int n; sqlite4_num vNum; assert( pOp->p1>=0 && pOp->p1<p->nCursor ); pC = p->apCsr[pOp->p1]; rc = sqlite4VdbeCursorMoveto(pC); if( rc!=SQLITE4_OK ) break; assert( pC->sSeekKey.n==0 ); assert( pC->pPseudoTab==0 ); |
︙ | ︙ | |||
3705 3706 3707 3708 3709 3710 3711 | rc = pModule->xRowid(pC->pVtabCursor, &v); importVtabErrMsg(p, pVtab); #endif /* SQLITE4_OMIT_VIRTUALTABLE */ }else{ rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey); if( rc==SQLITE4_OK ){ n = sqlite4GetVarint64(aKey, nKey, (sqlite4_uint64*)&v); | | > | 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 | rc = pModule->xRowid(pC->pVtabCursor, &v); importVtabErrMsg(p, pVtab); #endif /* SQLITE4_OMIT_VIRTUALTABLE */ }else{ rc = sqlite4KVCursorKey(pC->pKVCur, &aKey, &nKey); if( rc==SQLITE4_OK ){ n = sqlite4GetVarint64(aKey, nKey, (sqlite4_uint64*)&v); n = sqlite4VdbeDecodeNumericKey(&aKey[n], nKey-n, &vNum); if( n==0 ) rc = SQLITE4_CORRUPT; v = sqlite4_num_to_int64(vNum,0); } } pOut->u.num = sqlite4_num_from_int64(v); break; } /* Opcode: NullRow P1 * * * * |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
133 134 135 136 137 138 139 | 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 */ | < | 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 */ |
︙ | ︙ | |||
168 169 170 171 172 173 174 | #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 */ | | < < < < < < < < < < | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | #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 0x00ff /* Mask of type bits */ /* 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 */ #define MEM_Term 0x0200 /* String rep is nul terminated */ |
︙ | ︙ | |||
387 388 389 390 391 392 393 | int iTabno, /* The table this key applies to */ KeyInfo *pKeyInfo, /* Collating sequence information */ u8 **pzOut, /* Write the resulting key here */ int *pnOut, /* Number of bytes in the key */ int nExtra /* Append extra bytes on end of key */ ); int sqlite4VdbeEncodeIntKey(u8 *aBuf,sqlite4_int64 v); | | | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 | int iTabno, /* The table this key applies to */ KeyInfo *pKeyInfo, /* Collating sequence information */ u8 **pzOut, /* Write the resulting key here */ int *pnOut, /* Number of bytes in the key */ int nExtra /* Append extra bytes on end of key */ ); int sqlite4VdbeEncodeIntKey(u8 *aBuf,sqlite4_int64 v); int sqlite4VdbeDecodeNumericKey(const KVByteArray*, KVSize, sqlite4_num*); int sqlite4VdbeShortKey(const u8 *, int, int, int *); int sqlite4MemCompare(Mem*, Mem*, const CollSeq*,int*); int sqlite4VdbeExec(Vdbe*); int sqlite4VdbeList(Vdbe*); int sqlite4VdbeHalt(Vdbe*); int sqlite4VdbeChangeEncoding(Mem *, int); int sqlite4VdbeMemTooBig(Mem*); |
︙ | ︙ |
Changes to src/vdbecodec.c.
︙ | ︙ | |||
108 109 110 111 112 113 114 | p->n = pReg->n; rc = SQLITE4_OK; } return rc; } /* | > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | < < | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | p->n = pReg->n; rc = SQLITE4_OK; } return rc; } /* ** Make sure the p->aKey and p->nKey fields are valid and current. */ static int decoderFetchKey(RowDecoder *p){ VdbeCursor *pCur = p->pCur; int rc; if( pCur==0 ){ rc = sqlite4KVCursorKey(p->pKVCur, &p->aKey, &p->nKey); return rc; } assert( p->a!=0 ); if( p->aKey ) return SQLITE4_OK; if( pCur->pKVCur ){ rc = sqlite4KVCursorKey(pCur->pKVCur, &p->aKey, &p->nKey); }else{ Mem *pReg = pCur->pPseudoTab + 1; assert( pReg!=0 ); p->aKey = (const KVByteArray*)pReg->z; p->nKey = pReg->n; rc = SQLITE4_OK; } return rc; } /* ** Decode a blob from a key. The blob-key is in a[0] through a[n-1]. ** xorMask is either 0x00 for ascending order or 0xff for descending. ** Store the blob in pOut. */ static int decoderMemSetFromBlob( const KVByteArray *a, KVSize n, /* The blob as a key */ unsigned int xorMask, /* 0x00 (ascending) or 0xff (descending) */ Mem *pOut /* Write the blob here */ ){ int rc; unsigned int m = 0; int i, j, k; sqlite4VdbeMemSetStr(pOut, "", 0, 0, 0, 0); rc = sqlite4VdbeMemGrow(pOut, n, 0); if( rc==SQLITE4_OK ){ i = 0; j = 0; k = 0; while( i<n ){ m = (m<<7) | ((a[i++] ^ xorMask)&0x7f); j += 7; if( j>=8 ){ pOut->z[k++] = (m>>(j-8))&0xff; j -= 8; } } if( j>0 ){ pOut->z[k] = m<<(7-j); } pOut->n = k; } return rc; } /* ** Decode a numeric key encoding. Return the number of bytes in the ** encoding on success. On an error, return 0. */ int sqlite4VdbeDecodeNumericKey( const KVByteArray *aKey, /* Input encoding */ KVSize nKey, /* Number of bytes in aKey[] */ sqlite4_num *pVal /* Write the result here */ ){ unsigned int i, y; unsigned int xorMask = 0; short e; sqlite4_uint64 m; sqlite4_int64 eBig; KVByteArray aInvertedKey[4]; pVal->approx = 0; pVal->sign = 0; if( nKey<1 ) return 0; switch( aKey[0] ){ case 0x06: /* NaN ascending */ case 0xf9: /* NaN descending */ pVal->m = 0; pVal->e = 1000; return 1; case 0x07: /* -inf ascending */ case 0xf8: /* -inf descending */ pVal->m = 1; pVal->sign = 1; pVal->e = 1000; return 1; case 0x15: /* zero ascending */ case 0xea: /* zero descending */ pVal->m = 0; pVal->e = 0; return 1; case 0x23: /* +inf ascending */ case 0xdc: /* +inf descending */ pVal->m = 1; pVal->e = 1000; return 1; case 0x09: case 0x0a: case 0x0b: case 0x0c: case 0x0d: case 0x0e: case 0x0f: case 0x10: case 0x11: case 0x12: case 0x13: /* -medium ascending */ pVal->sign = 1; xorMask = 0xff; e = 0x13 - aKey[0]; i = 1; break; case 0xf6: case 0xf5: case 0xf4: case 0xf3: case 0xf2: case 0xf1: case 0xf0: case 0xef: case 0xee: case 0xed: case 0xec: /* -medium descending */ pVal->sign = 1; e = aKey[0] - 0xec; i = 1; break; case 0x17: case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f: case 0x20: case 0x21: /* +medium ascending */ e = aKey[0] - 0x17; i = 1; break; case 0xe8: case 0xe7: case 0xe6: case 0xe5: case 0xe4: case 0xe3: case 0xe2: case 0xe1: case 0xe0: case 0xdf: case 0xde: /* +medium descending */ e = 0xe8 - aKey[0]; xorMask = 0xff; i = 1; break; case 0x14: /* -small ascending */ case 0xe9: /* +small descending */ i = 1 + sqlite4GetVarint64(aKey+1, 2, &eBig); e = (short)-eBig; xorMask = 0xff; break; case 0x16: /* +small ascending */ case 0xeb: /* -small descending */ aInvertedKey[0] = aKey[1] ^ 0xff; aInvertedKey[1] = aKey[2] ^ 0xff; i = 1 + sqlite4GetVarint64(aInvertedKey, 2, &eBig); e = (short)-eBig; break; case 0x08: /* -large ascending */ case 0xdd: /* +large descending */ aInvertedKey[0] = aKey[1] ^ 0xff; aInvertedKey[1] = aKey[2] ^ 0xff; i = 1 + sqlite4GetVarint64(aInvertedKey, 2, &eBig); e = (short)eBig; xorMask = 0xff; break; case 0x22: /* +large ascending */ case 0xf7: /* -large descending */ i = 1 + sqlite4GetVarint64(aKey+1, 2, &eBig); e = (short)eBig; break; default: return 0; } m = 0; do{ y = aKey[i++] ^ xorMask; m = m*100 + y/2; e--; }while( y & 1 ); if( m==0 ) return 0; pVal->m = m; pVal->e = 2*e; return i; } /* ** This is a private method for the RowDecoder object. ** ** Attempt to extract a single column value from the key of the current ** key/value pair. If beginning of the value is iOfst bytes from the beginning ** of the key. If affReal is true, then force numeric values to be floating ** point. Write the result in pOut. Or return non-zero if there is an ** error. */ static int decoderFromKey( RowDecoder *p, /* The current key/value pair */ int affReal, /* True to coerce numbers to floating point */ sqlite4_int64 iOfst, /* Offset of value in the key */ Mem *pOut /* Write the results here */ ){ int rc; KVSize i; KVSize n; const KVByteArray *a; char *z; if( iOfst<0 ){ return SQLITE4_CORRUPT_BKPT; } rc = decoderFetchKey(p); if( rc ) return rc; if( iOfst>=p->nKey ){ return SQLITE4_CORRUPT_BKPT; } a = p->aKey; n = p->nKey; switch( a[iOfst++] ){ case 0x05: case 0xFA: /* NULL */ case 0x06: case 0xF9: { /* NaN */ sqlite4VdbeMemSetNull(pOut); break; } case 0x24: { /* Text (ascending index) */ for(i=iOfst; i<n && a[i]!=0; i++){} rc = sqlite4VdbeMemSetStr(pOut, &a[iOfst], i-iOfst, SQLITE4_UTF8, SQLITE4_TRANSIENT, 0); break; } case 0xDB: { /* Text (descending index) */ for(i=iOfst; i<n && a[i]!=0xFF; i++){} rc = sqlite4VdbeMemSetStr(pOut, &a[iOfst+1], n = i - iOfst, SQLITE4_UTF8, SQLITE4_TRANSIENT, 0); if( rc==SQLITE4_OK ){ z = pOut->z; for(i=n-1; i>=0; i--) *(z++) ^= 0xFF; } break; } case 0x25: { /* Blob (ascending index) */ for(i=iOfst; i<n && a[i]!=0; i++){} rc = decoderMemSetFromBlob(&a[iOfst], i-iOfst, 0x00, pOut); break; } case 0xDA: { /* Blob (descending index) */ for(i=iOfst; i<n && a[i]!=0xFF; i++){} rc = decoderMemSetFromBlob(&a[iOfst], i-iOfst, 0xFF, pOut); break; } case 0x26: { /* Blob-final (ascending) */ rc = sqlite4VdbeMemSetStr(pOut, &a[iOfst], n-iOfst, 0, SQLITE4_TRANSIENT, 0); break; } case 0xD9: { /* Blob-final (descending) */ rc = sqlite4VdbeMemSetStr(pOut, &a[iOfst], n-iOfst, SQLITE4_UTF8, SQLITE4_TRANSIENT, 0); if( rc==SQLITE4_OK ){ z = pOut->z; for(i=n-iOfst; i>0; i--) *(z++) ^= 0xFF; } break; } default: { sqlite4_num v; i = sqlite4VdbeDecodeNumericKey(a+iOfst-1, n-iOfst+1, &v); if( i==0 ){ rc = SQLITE4_CORRUPT_BKPT; }else{ sqlite4VdbeMemSetNum(pOut, v, affReal ? MEM_Real : MEM_Int); rc = SQLITE4_OK; } break; } }; return rc; } /* ** Decode a single column from a key/value pair taken from the storage ** engine. The key/value pair to be decoded is the one that the VdbeCursor ** or KVCursor is currently pointing to. ** ** iVal is the column index of the value. 0 is the first column of the ** value. If N is the number of columns in the value and iVal>=N then ** the result is pDefault. Write the result into pOut. Return SQLITE4_OK ** on success or an appropriate error code on failure. ** ** The key is referenced only if the iVal-th column in the value is either ** the 22 or 23 header code which indicates that the value is stored in the ** key instead. */ int sqlite4VdbeDecoderGetColumn( 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 */ ){ |
︙ | ︙ | |||
159 160 161 162 163 164 165 | n += sz; } size = (type-24)/3; }else if( type<=2 ){ size = 0; }else if( type<=10 ){ size = type - 2; | | | 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | n += sz; } size = (type-24)/3; }else if( type<=2 ){ size = 0; }else if( type<=10 ){ size = type - 2; }else if( type<=21 ){ size = type - 9; }else{ /* value in key */ size = 0; sz = sqlite4GetVarint64(p->a+n, p->n-n, &subtype); if( sz==0 ) return SQLITE4_CORRUPT; n += sz; |
︙ | ︙ | |||
198 199 200 201 202 203 204 | 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 ){ | < | < | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 | 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 ){ return decoderFromKey(p, type==23, subtype, pOut); }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{ |
︙ | ︙ | |||
592 593 594 595 596 597 598 | assert( flags & MEM_Blob ); n = pMem->n; a = (u8*)pMem->z; s = 1; t = 0; if( enlargeEncoderAllocation(p, (n*8+6)/7 + 2) ) return SQLITE4_NOMEM; p->aOut[p->nOut++] = 0x25; /* Blob */ | | | 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 | assert( flags & MEM_Blob ); n = pMem->n; a = (u8*)pMem->z; s = 1; t = 0; if( enlargeEncoderAllocation(p, (n*8+6)/7 + 2) ) return SQLITE4_NOMEM; p->aOut[p->nOut++] = 0x25; /* Blob */ for(i=0; i<n; i++){ unsigned char x = a[i]; p->aOut[p->nOut++] = 0x80 | t | (x>>s); if( s<7 ){ t = x<<(7-s); s++; }else{ p->aOut[p->nOut++] = 0x80 | x; |
︙ | ︙ | |||
750 751 752 753 754 755 756 | sqlite4DbFree(db, x.aOut); }else{ *paOut = x.aOut; *pnOut = x.nOut; } return rc; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 1063 1064 1065 1066 1067 1068 1069 | sqlite4DbFree(db, x.aOut); }else{ *paOut = x.aOut; *pnOut = x.nOut; } return rc; } |