/ Check-in [7277a769]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Simplifications to the OP_MakeRecord opcode and the sqlite3VdbeSerialPut() helper function.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:7277a769694787e0332d1a4efc02041834661e2a
User & Date: drh 2013-12-09 23:17:22
Context
2013-12-10
19:49
Simplify and improve the performance of the sqlite3VdbeMemGrow() routine. check-in: 48ecf187 user: drh tags: trunk
16:35
Merge changes from the trunk. check-in: 3ee736a3 user: dan tags: zipvfs-multifile-commit
2013-12-09
23:17
Simplifications to the OP_MakeRecord opcode and the sqlite3VdbeSerialPut() helper function. check-in: 7277a769 user: drh tags: trunk
21:48
Correct the VFS name as reported by the file control when explicitly using the 'win32-longpath' VFS. check-in: c43b59da user: mistachkin tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

  2595   2595     pOut = &aMem[pOp->p3];
  2596   2596     memAboutToChange(p, pOut);
  2597   2597   
  2598   2598     /* Loop through the elements that will make up the record to figure
  2599   2599     ** out how much space is required for the new record.
  2600   2600     */
  2601   2601     assert( pData0<=pLast );
  2602         -  pRec = pData0;
         2602  +  pRec = pLast;
  2603   2603     do{
  2604   2604       assert( memIsValid(pRec) );
  2605   2605       if( zAffinity ){
  2606   2606         applyAffinity(pRec, zAffinity[pRec-pData0], encoding);
  2607   2607       }
  2608         -    if( (pRec->flags&MEM_Zero)!=0 && pRec->n>0 ){
  2609         -      sqlite3VdbeMemExpandBlob(pRec);
  2610         -    }
  2611   2608       serial_type = sqlite3VdbeSerialType(pRec, file_format);
  2612   2609       len = sqlite3VdbeSerialTypeLen(serial_type);
         2610  +    if( pRec->flags & MEM_Zero ){
         2611  +      if( nData ){
         2612  +        sqlite3VdbeMemExpandBlob(pRec);
         2613  +      }else{
         2614  +        nZero += pRec->u.nZero;
         2615  +        len -= pRec->u.nZero;
         2616  +      }
         2617  +    }
  2613   2618       nData += len;
  2614   2619       testcase( serial_type==127 );
  2615   2620       testcase( serial_type==128 );
  2616   2621       nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
  2617         -    if( pRec->flags & MEM_Zero ){
  2618         -      /* Only pure zero-filled BLOBs can be input to this Opcode.
  2619         -      ** We do not allow blobs with a prefix and a zero-filled tail. */
  2620         -      nZero += pRec->u.nZero;
  2621         -    }else if( len ){
  2622         -      nZero = 0;
  2623         -    }
  2624         -  }while( (++pRec)<=pLast );
         2622  +  }while( (--pRec)>=pData0 );
  2625   2623   
  2626   2624     /* Add the initial header varint and total the size */
  2627   2625     testcase( nHdr==126 );
  2628   2626     testcase( nHdr==127 );
  2629   2627     if( nHdr<=126 ){
  2630   2628       /* The common case */
  2631   2629       nHdr += 1;
  2632   2630     }else{
  2633   2631       /* Rare case of a really large header */
  2634   2632       nVarint = sqlite3VarintLen(nHdr);
  2635   2633       nHdr += nVarint;
  2636   2634       if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
  2637   2635     }
  2638         -  nByte = nHdr+nData-nZero;
         2636  +  nByte = nHdr+nData;
  2639   2637     if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
  2640   2638       goto too_big;
  2641   2639     }
  2642   2640   
  2643   2641     /* Make sure the output register has a buffer large enough to store 
  2644   2642     ** the new record. The output register (pOp->p3) is not allowed to
  2645   2643     ** be one of the input registers (because the following call to
................................................................................
  2653   2651     /* Write the record */
  2654   2652     i = putVarint32(zNewRecord, nHdr);
  2655   2653     j = nHdr;
  2656   2654     assert( pData0<=pLast );
  2657   2655     pRec = pData0;
  2658   2656     do{
  2659   2657       serial_type = sqlite3VdbeSerialType(pRec, file_format);
  2660         -    i += putVarint32(&zNewRecord[i], serial_type);      /* serial type */
  2661         -    j += sqlite3VdbeSerialPut(&zNewRecord[j], (int)(nByte-j), pRec,file_format);
         2658  +    i += putVarint32(&zNewRecord[i], serial_type);            /* serial type */
         2659  +    j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, file_format); /* content */
  2662   2660     }while( (++pRec)<=pLast );
  2663   2661     assert( i==nHdr );
  2664   2662     assert( j==nByte );
  2665   2663   
  2666   2664     assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  2667   2665     pOut->n = (int)nByte;
  2668   2666     pOut->flags = MEM_Blob | MEM_Dyn;

Changes to src/vdbeInt.h.

   385    385   void sqliteVdbePopStack(Vdbe*,int);
   386    386   int sqlite3VdbeCursorMoveto(VdbeCursor*);
   387    387   #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
   388    388   void sqlite3VdbePrintOp(FILE*, int, Op*);
   389    389   #endif
   390    390   u32 sqlite3VdbeSerialTypeLen(u32);
   391    391   u32 sqlite3VdbeSerialType(Mem*, int);
   392         -u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
          392  +u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, int);
   393    393   u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
   394    394   void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
   395    395   
   396    396   int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
   397    397   int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
   398    398   int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
   399    399   int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);

Changes to src/vdbeaux.c.

  2823   2823   #endif
  2824   2824   
  2825   2825   /*
  2826   2826   ** Write the serialized data blob for the value stored in pMem into 
  2827   2827   ** buf. It is assumed that the caller has allocated sufficient space.
  2828   2828   ** Return the number of bytes written.
  2829   2829   **
  2830         -** nBuf is the amount of space left in buf[].  nBuf must always be
  2831         -** large enough to hold the entire field.  Except, if the field is
  2832         -** a blob with a zero-filled tail, then buf[] might be just the right
  2833         -** size to hold everything except for the zero-filled tail.  If buf[]
  2834         -** is only big enough to hold the non-zero prefix, then only write that
  2835         -** prefix into buf[].  But if buf[] is large enough to hold both the
  2836         -** prefix and the tail then write the prefix and set the tail to all
  2837         -** zeros.
         2830  +** nBuf is the amount of space left in buf[].  The caller is responsible
         2831  +** for allocating enough space to buf[] to hold the entire field, exclusive
         2832  +** of the pMem->u.nZero bytes for a MEM_Zero value.
  2838   2833   **
  2839   2834   ** Return the number of bytes actually written into buf[].  The number
  2840   2835   ** of bytes in the zero-filled tail is included in the return value only
  2841   2836   ** if those bytes were zeroed in buf[].
  2842   2837   */ 
  2843         -u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
         2838  +u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, int file_format){
  2844   2839     u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
  2845   2840     u32 len;
  2846   2841   
  2847   2842     /* Integer and Real */
  2848   2843     if( serial_type<=7 && serial_type>0 ){
  2849   2844       u64 v;
  2850   2845       u32 i;
................................................................................
  2852   2847         assert( sizeof(v)==sizeof(pMem->r) );
  2853   2848         memcpy(&v, &pMem->r, sizeof(v));
  2854   2849         swapMixedEndianFloat(v);
  2855   2850       }else{
  2856   2851         v = pMem->u.i;
  2857   2852       }
  2858   2853       len = i = sqlite3VdbeSerialTypeLen(serial_type);
  2859         -    assert( len<=(u32)nBuf );
  2860   2854       while( i-- ){
  2861   2855         buf[i] = (u8)(v&0xFF);
  2862   2856         v >>= 8;
  2863   2857       }
  2864   2858       return len;
  2865   2859     }
  2866   2860   
  2867   2861     /* String or blob */
  2868   2862     if( serial_type>=12 ){
  2869   2863       assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
  2870   2864                == (int)sqlite3VdbeSerialTypeLen(serial_type) );
  2871         -    assert( pMem->n<=nBuf );
  2872   2865       len = pMem->n;
  2873   2866       memcpy(buf, pMem->z, len);
  2874         -    if( pMem->flags & MEM_Zero ){
  2875         -      len += pMem->u.nZero;
  2876         -      assert( nBuf>=0 );
  2877         -      if( len > (u32)nBuf ){
  2878         -        len = (u32)nBuf;
  2879         -      }
  2880         -      memset(&buf[pMem->n], 0, len-pMem->n);
  2881         -    }
  2882   2867       return len;
  2883   2868     }
  2884   2869   
  2885   2870     /* NULL or constants 0 or 1 */
  2886   2871     return 0;
  2887   2872   }
  2888   2873   

Changes to src/vdbemem.c.

  1217   1217     nRet = 1 + nSerial + nVal;
  1218   1218     aRet = sqlite3DbMallocRaw(db, nRet);
  1219   1219     if( aRet==0 ){
  1220   1220       sqlite3_result_error_nomem(context);
  1221   1221     }else{
  1222   1222       aRet[0] = nSerial+1;
  1223   1223       sqlite3PutVarint(&aRet[1], iSerial);
  1224         -    sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format);
         1224  +    sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], file_format);
  1225   1225       sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
  1226   1226       sqlite3DbFree(db, aRet);
  1227   1227     }
  1228   1228   }
  1229   1229   
  1230   1230   /*
  1231   1231   ** Register built-in functions used to help read ANALYZE data.