/ Check-in [ae301db8]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Add serial-types 8 and 9 for integer constants of 0 and 1 that use zero bytes of storage. Make the default file format 4. Add the SQLITE_DEFAULT_FILE_FORMAT compile-time option to lower the default file format number so that newly created databases can be read and written by older versions of SQLite. (CVS 2845)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ae301db8a61a74bc72f67f5766811d89a3b3ec72
User & Date: drh 2005-12-29 19:23:07
Context
2005-12-29
23:04
Bug fix in codec processing. (CVS 2846) check-in: a88580bc user: drh tags: trunk
19:23
Add serial-types 8 and 9 for integer constants of 0 and 1 that use zero bytes of storage. Make the default file format 4. Add the SQLITE_DEFAULT_FILE_FORMAT compile-time option to lower the default file format number so that newly created databases can be read and written by older versions of SQLite. (CVS 2845) check-in: ae301db8 user: drh tags: trunk
12:53
Fix for ticket #1575. (CVS 2844) check-in: 1586921b user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    18     18   **     CREATE INDEX
    19     19   **     DROP INDEX
    20     20   **     creating ID lists
    21     21   **     BEGIN TRANSACTION
    22     22   **     COMMIT
    23     23   **     ROLLBACK
    24     24   **
    25         -** $Id: build.c,v 1.362 2005/12/29 01:11:37 drh Exp $
           25  +** $Id: build.c,v 1.363 2005/12/29 19:23:07 drh Exp $
    26     26   */
    27     27   #include "sqliteInt.h"
    28     28   #include <ctype.h>
    29     29   
    30     30   /*
    31     31   ** This routine is called when a new SQL statement is beginning to
    32     32   ** be parsed.  Initialize the pParse structure as needed.
................................................................................
   760    760   
   761    761       /* If the file format and encoding in the database have not been set, 
   762    762       ** set them now.
   763    763       */
   764    764       sqlite3VdbeAddOp(v, OP_ReadCookie, iDb, 1);   /* file_format */
   765    765       lbl = sqlite3VdbeMakeLabel(v);
   766    766       sqlite3VdbeAddOp(v, OP_If, 0, lbl);
   767         -    sqlite3VdbeAddOp(v, OP_Integer, 1, 0);   /* file format defaults to 1 */
          767  +    sqlite3VdbeAddOp(v, OP_Integer, SQLITE_DEFAULT_FILE_FORMAT, 0);
   768    768       sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 1);
   769    769       sqlite3VdbeAddOp(v, OP_Integer, db->enc, 0);
   770    770       sqlite3VdbeAddOp(v, OP_SetCookie, iDb, 4);
   771    771       sqlite3VdbeResolveLabel(v, lbl);
   772    772   
   773    773       /* This just creates a place-holder record in the sqlite_master table.
   774    774       ** The record created does not contain anything yet.  It will be replaced
................................................................................
  2108   2108     Index *pIndex = 0;   /* The index to be created */
  2109   2109     char *zName = 0;     /* Name of the index */
  2110   2110     int nName;           /* Number of characters in zName */
  2111   2111     int i, j;
  2112   2112     Token nullId;        /* Fake token for an empty ID list */
  2113   2113     DbFixer sFix;        /* For assigning database names to pTable */
  2114   2114     int sortOrderMask;   /* 1 to honor DESC in index.  0 to ignore. */
  2115         -  int descSeen = 0;    /* Changes to true if a DESC is seen */
  2116   2115     sqlite3 *db = pParse->db;
  2117   2116     Db *pDb;             /* The specific table containing the indexed database */
  2118   2117     int iDb;             /* Index of the database that is being written */
  2119   2118     Token *pName = 0;    /* Unqualified name of the index to create */
  2120   2119     struct ExprList_item *pListItem; /* For looping over pList */
  2121   2120   
  2122   2121     if( pParse->nErr || sqlite3Tsd()->mallocFailed ) goto exit_create_index;
................................................................................
  2260   2259     pIndex->nColumn = pList->nExpr;
  2261   2260     pIndex->onError = onError;
  2262   2261     pIndex->autoIndex = pName==0;
  2263   2262     pIndex->iDb = iDb;
  2264   2263   
  2265   2264     /* Check to see if we should honor DESC requests on index columns
  2266   2265     */
  2267         -  if( pDb->file_format>=4 || (!pDb->descIndex && !db->init.busy) ){
         2266  +  if( pDb->file_format>=4 ){
  2268   2267       sortOrderMask = -1;   /* Honor DESC */
  2269   2268     }else{
  2270   2269       sortOrderMask = 0;    /* Ignore DESC */
  2271   2270     }
  2272   2271   
  2273   2272     /* Scan the names of the columns of the table to be indexed and
  2274   2273     ** load the column indices into the Index structure.  Report an error
................................................................................
  2295   2294       }
  2296   2295       assert( pIndex->keyInfo.aColl[i] );
  2297   2296       if( !db->init.busy && 
  2298   2297           sqlite3CheckCollSeq(pParse, pIndex->keyInfo.aColl[i]) 
  2299   2298       ){
  2300   2299         goto exit_create_index;
  2301   2300       }
  2302         -    requestedSortOrder = pListItem->sortOrder;
  2303         -    pDb->descIndex |= requestedSortOrder;
  2304         -    requestedSortOrder &= sortOrderMask;
         2301  +    requestedSortOrder = pListItem->sortOrder & sortOrderMask;
  2305   2302       pIndex->keyInfo.aSortOrder[i] = requestedSortOrder;
  2306         -    descSeen |= requestedSortOrder;
  2307   2303     }
  2308   2304     pIndex->keyInfo.nField = pList->nExpr;
  2309   2305     sqlite3DefaultRowEst(pIndex);
  2310   2306   
  2311   2307     if( pTab==pParse->pNewTable ){
  2312   2308       /* This routine has been called to create an automatic index as a
  2313   2309       ** result of a PRIMARY KEY or UNIQUE clause on a column definition, or
................................................................................
  2400   2396   
  2401   2397       /* Create the rootpage for the index
  2402   2398       */
  2403   2399       sqlite3BeginWriteOperation(pParse, 1, iDb);
  2404   2400       sqlite3VdbeAddOp(v, OP_CreateIndex, iDb, 0);
  2405   2401       sqlite3VdbeAddOp(v, OP_MemStore, iMem, 0);
  2406   2402   
  2407         -    /* Make sure the file_format is at least 4 if we have DESC indices. */
  2408         -    if( descSeen ){
  2409         -      sqlite3MinimumFileFormat(pParse, iDb, 4);
  2410         -    }
  2411         -
  2412   2403       /* Gather the complete text of the CREATE INDEX statement into
  2413   2404       ** the zStmt variable
  2414   2405       */
  2415   2406       if( pStart && pEnd ){
  2416   2407         /* A named index with an explicit CREATE INDEX statement */
  2417   2408         zStmt = sqlite3MPrintf("CREATE%s INDEX %.*s",
  2418   2409           onError==OE_None ? "" : " UNIQUE",

Changes to src/prepare.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains the implementation of the sqlite3_prepare()
    13     13   ** interface, and routines that contribute to loading the database schema
    14     14   ** from disk.
    15     15   **
    16         -** $Id: prepare.c,v 1.10 2005/12/16 01:06:17 drh Exp $
           16  +** $Id: prepare.c,v 1.11 2005/12/29 19:23:07 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "os.h"
    20     20   #include <ctype.h>
    21     21   
    22     22   /*
    23     23   ** Fill the InitData structure with an error message that indicates
................................................................................
   254    254     pDb->cache_size = size;
   255    255     sqlite3BtreeSetCacheSize(pDb->pBt, pDb->cache_size);
   256    256   
   257    257     /*
   258    258     ** file_format==1    Version 3.0.0.
   259    259     ** file_format==2    Version 3.1.3.  // ALTER TABLE ADD COLUMN
   260    260     ** file_format==3    Version 3.1.4.  // ditto but with non-NULL defaults
   261         -  ** file_format==4    Version 3.3.0.  // DESC indices
          261  +  ** file_format==4    Version 3.3.0.  // DESC indices.  Boolean constants
   262    262     */
   263    263     pDb->file_format = meta[1];
   264    264     if( pDb->file_format==0 ){
   265    265       pDb->file_format = 1;
   266    266     }
   267         -  if( pDb->file_format>4 ){
          267  +  if( pDb->file_format>SQLITE_MAX_FILE_FORMAT ){
   268    268       sqlite3BtreeCloseCursor(curMain);
   269    269       sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
   270    270       return SQLITE_ERROR;
   271    271     }
   272    272   
   273    273   
   274    274     /* Read the schema information out of the schema tables

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.443 2005/12/29 01:11:37 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.444 2005/12/29 19:23:07 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** Many people are failing to set -DNDEBUG=1 when compiling SQLite.
    21     21   ** Setting NDEBUG makes the code smaller and run faster.  So the following
................................................................................
   136    136   #define MAX_ATTACHED 10
   137    137   
   138    138   /*
   139    139   ** The maximum value of a ?nnn wildcard that the parser will accept.
   140    140   */
   141    141   #define SQLITE_MAX_VARIABLE_NUMBER 999
   142    142   
          143  +/*
          144  +** The "file format" number is an integer that is incremented whenever
          145  +** the VDBE-level file format changes.  The following macros define the
          146  +** the default file format for new databases and the maximum file format
          147  +** that the library can read.
          148  +*/
          149  +#define SQLITE_MAX_FILE_FORMAT 4
          150  +#ifndef SQLITE_DEFAULT_FILE_FORMAT
          151  +# define SQLITE_DEFAULT_FILE_FORMAT 4
          152  +#endif
          153  +
   143    154   /*
   144    155   ** Provide a default value for TEMP_STORE in case it is not specified
   145    156   ** on the command-line
   146    157   */
   147    158   #ifndef TEMP_STORE
   148    159   # define TEMP_STORE 1
   149    160   #endif
................................................................................
   356    367     Hash idxHash;        /* All (named) indices indexed by name */
   357    368     Hash trigHash;       /* All triggers indexed by name */
   358    369     Hash aFKey;          /* Foreign keys indexed by to-table */
   359    370     u16 flags;           /* Flags associated with this database */
   360    371     u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
   361    372     u8 safety_level;     /* How aggressive at synching data to disk */
   362    373     u8 file_format;      /* Schema format version for this file */
   363         -  u8 descIndex;        /* True if any index uses the DESC attribute */
   364    374     int cache_size;      /* Number of pages to use in the cache */
   365    375     Table *pSeqTab;      /* The sqlite_sequence table used by AUTOINCREMENT */
   366    376     void *pAux;               /* Auxiliary data.  Usually NULL */
   367    377     void (*xFreeAux)(void*);  /* Routine to free pAux */
   368    378   };
   369    379   
   370    380   /*

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.508 2005/12/21 18:36:46 drh Exp $
           46  +** $Id: vdbe.c,v 1.509 2005/12/29 19:23:07 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
  2103   2103   ** The mapping from character to affinity is given by the SQLITE_AFF_
  2104   2104   ** macros defined in sqliteInt.h.
  2105   2105   **
  2106   2106   ** If P3 is NULL then all index fields have the affinity NONE.
  2107   2107   **
  2108   2108   ** See also OP_MakeIdxRec
  2109   2109   */
  2110         -/* Opcode: MakeRecordI P1 P2 P3
         2110  +/* Opcode: MakeIdxRec P1 P2 P3
  2111   2111   **
  2112   2112   ** This opcode works just OP_MakeRecord except that it reads an extra
  2113   2113   ** integer from the stack (thus reading a total of abs(P1+1) entries)
  2114   2114   ** and appends that extra integer to the end of the record as a varint.
  2115   2115   ** This results in an index key.
  2116   2116   */
  2117   2117   case OP_MakeIdxRec:
................................................................................
  2145   2145     Mem *pData0;
  2146   2146   
  2147   2147     int leaveOnStack;      /* If true, leave the entries on the stack */
  2148   2148     int nField;            /* Number of fields in the record */
  2149   2149     int jumpIfNull;        /* Jump here if non-zero and any entries are NULL. */
  2150   2150     int addRowid;          /* True to append a rowid column at the end */
  2151   2151     char *zAffinity;       /* The affinity string for the record */
         2152  +  int file_format;       /* File format to use for encoding */
  2152   2153   
  2153   2154     leaveOnStack = ((pOp->p1<0)?1:0);
  2154   2155     nField = pOp->p1 * (leaveOnStack?-1:1);
  2155   2156     jumpIfNull = pOp->p2;
  2156   2157     addRowid = pOp->opcode==OP_MakeIdxRec;
  2157   2158     zAffinity = pOp->p3;
  2158   2159   
  2159   2160     pData0 = &pTos[1-nField];
  2160   2161     assert( pData0>=p->aStack );
  2161   2162     containsNull = 0;
         2163  +  file_format = p->minWriteFileFormat;
  2162   2164   
  2163   2165     /* Loop through the elements that will make up the record to figure
  2164   2166     ** out how much space is required for the new record.
  2165   2167     */
  2166   2168     for(pRec=pData0; pRec<=pTos; pRec++){
  2167   2169       if( zAffinity ){
  2168   2170         applyAffinity(pRec, zAffinity[pRec-pData0], db->enc);
  2169   2171       }
  2170   2172       if( pRec->flags&MEM_Null ){
  2171   2173         containsNull = 1;
  2172   2174       }
  2173         -    serial_type = sqlite3VdbeSerialType(pRec);
         2175  +    serial_type = sqlite3VdbeSerialType(pRec, file_format);
  2174   2176       nData += sqlite3VdbeSerialTypeLen(serial_type);
  2175   2177       nHdr += sqlite3VarintLen(serial_type);
  2176   2178     }
  2177   2179   
  2178   2180     /* If we have to append a varint rowid to this record, set 'rowid'
  2179   2181     ** to the value of the rowid and increase nByte by the amount of space
  2180   2182     ** required to store it and the 0x00 seperator byte.
  2181   2183     */
  2182   2184     if( addRowid ){
  2183   2185       pRowid = &pTos[0-nField];
  2184   2186       assert( pRowid>=p->aStack );
  2185   2187       sqlite3VdbeMemIntegerify(pRowid);
  2186         -    serial_type = sqlite3VdbeSerialType(pRowid);
         2188  +    serial_type = sqlite3VdbeSerialType(pRowid, 0);
  2187   2189       nData += sqlite3VdbeSerialTypeLen(serial_type);
  2188   2190       nHdr += sqlite3VarintLen(serial_type);
  2189   2191     }
  2190   2192   
  2191   2193     /* Add the initial header varint and total the size */
  2192   2194     nHdr += nVarint = sqlite3VarintLen(nHdr);
  2193   2195     if( nVarint<sqlite3VarintLen(nHdr) ){
................................................................................
  2205   2207       zNewRecord = (u8*)zTemp;
  2206   2208     }
  2207   2209   
  2208   2210     /* Write the record */
  2209   2211     zCsr = zNewRecord;
  2210   2212     zCsr += sqlite3PutVarint(zCsr, nHdr);
  2211   2213     for(pRec=pData0; pRec<=pTos; pRec++){
  2212         -    serial_type = sqlite3VdbeSerialType(pRec);
         2214  +    serial_type = sqlite3VdbeSerialType(pRec, file_format);
  2213   2215       zCsr += sqlite3PutVarint(zCsr, serial_type);      /* serial type */
  2214   2216     }
  2215   2217     if( addRowid ){
  2216         -    zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid));
         2218  +    zCsr += sqlite3PutVarint(zCsr, sqlite3VdbeSerialType(pRowid, 0));
  2217   2219     }
  2218   2220     for(pRec=pData0; pRec<=pTos; pRec++){
  2219         -    zCsr += sqlite3VdbeSerialPut(zCsr, pRec);  /* serial data */
         2221  +    zCsr += sqlite3VdbeSerialPut(zCsr, pRec, file_format);  /* serial data */
  2220   2222     }
  2221   2223     if( addRowid ){
  2222         -    zCsr += sqlite3VdbeSerialPut(zCsr, pRowid);
         2224  +    zCsr += sqlite3VdbeSerialPut(zCsr, pRowid, 0);
  2223   2225     }
  2224   2226     assert( zCsr==(zNewRecord+nByte) );
  2225   2227   
  2226   2228     /* Pop entries off the stack if required. Push the new record on. */
  2227   2229     if( !leaveOnStack ){
  2228   2230       popStack(&pTos, nField+addRowid);
  2229   2231     }
................................................................................
  2511   2513   case OP_OpenWrite: {       /* no-push */
  2512   2514     int i = pOp->p1;
  2513   2515     int p2 = pOp->p2;
  2514   2516     int wrFlag;
  2515   2517     Btree *pX;
  2516   2518     int iDb;
  2517   2519     Cursor *pCur;
         2520  +  Db *pDb;
  2518   2521     
  2519   2522     assert( pTos>=p->aStack );
  2520   2523     sqlite3VdbeMemIntegerify(pTos);
  2521   2524     iDb = pTos->i;
  2522   2525     assert( (pTos->flags & MEM_Dyn)==0 );
  2523   2526     pTos--;
  2524   2527     assert( iDb>=0 && iDb<db->nDb );
  2525         -  pX = db->aDb[iDb].pBt;
         2528  +  pDb = &db->aDb[iDb];
         2529  +  pX = pDb->pBt;
  2526   2530     assert( pX!=0 );
  2527         -  wrFlag = pOp->opcode==OP_OpenWrite;
         2531  +  if( pOp->opcode==OP_OpenWrite ){
         2532  +    wrFlag = 1;
         2533  +    if( pDb->file_format < p->minWriteFileFormat ){
         2534  +      p->minWriteFileFormat = pDb->file_format;
         2535  +    }
         2536  +  }else{
         2537  +    wrFlag = 0;
         2538  +  }
  2528   2539     if( p2<=0 ){
  2529   2540       assert( pTos>=p->aStack );
  2530   2541       sqlite3VdbeMemIntegerify(pTos);
  2531   2542       p2 = pTos->i;
  2532   2543       assert( (pTos->flags & MEM_Dyn)==0 );
  2533   2544       pTos--;
  2534   2545       assert( p2>=2 );

Changes to src/vdbeInt.h.

   303    303     int popStack;           /* Pop the stack this much on entry to VdbeExec() */
   304    304     char *zErrMsg;          /* Error message written here */
   305    305     u8 resOnStack;          /* True if there are result values on the stack */
   306    306     u8 explain;             /* True if EXPLAIN present on SQL command */
   307    307     u8 changeCntOn;         /* True to update the change-counter */
   308    308     u8 aborted;             /* True if ROLLBACK in another VM causes an abort */
   309    309     u8 expired;             /* True if the VM needs to be recompiled */
          310  +  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
   310    311     int nChange;            /* Number of db changes made since last reset */
   311    312     i64 startTime;          /* Time when query started - used for profiling */
   312    313   };
   313    314   
   314    315   /*
   315    316   ** The following are allowed values for Vdbe.magic
   316    317   */
................................................................................
   328    329   #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
   329    330   void sqlite3VdbePrintOp(FILE*, int, Op*);
   330    331   #endif
   331    332   #ifdef SQLITE_DEBUG
   332    333   void sqlite3VdbePrintSql(Vdbe*);
   333    334   #endif
   334    335   int sqlite3VdbeSerialTypeLen(u32);
   335         -u32 sqlite3VdbeSerialType(Mem*);
   336         -int sqlite3VdbeSerialPut(unsigned char*, Mem*);
          336  +u32 sqlite3VdbeSerialType(Mem*, int);
          337  +int sqlite3VdbeSerialPut(unsigned char*, Mem*, int);
   337    338   int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
   338    339   void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
   339    340   
   340    341   int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
   341    342   int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int*);
   342    343   int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
   343    344   int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);

Changes to src/vdbeaux.c.

   778    778     p->uniqueCnt = 0;
   779    779     p->returnDepth = 0;
   780    780     p->errorAction = OE_Abort;
   781    781     p->popStack =  0;
   782    782     p->explain |= isExplain;
   783    783     p->magic = VDBE_MAGIC_RUN;
   784    784     p->nChange = 0;
          785  +  p->minWriteFileFormat = 255;
   785    786   #ifdef VDBE_PROFILE
   786    787     {
   787    788       int i;
   788    789       for(i=0; i<p->nOp; i++){
   789    790         p->aOp[i].cnt = 0;
   790    791         p->aOp[i].cycles = 0;
   791    792       }
................................................................................
  1486   1487   **      1                     1            signed integer
  1487   1488   **      2                     2            signed integer
  1488   1489   **      3                     3            signed integer
  1489   1490   **      4                     4            signed integer
  1490   1491   **      5                     6            signed integer
  1491   1492   **      6                     8            signed integer
  1492   1493   **      7                     8            IEEE float
  1493         -**     8-11                                reserved for expansion
         1494  +**      8                     0            Integer constant 0
         1495  +**      9                     0            Integer constant 1
         1496  +**     10,11                               reserved for expansion
  1494   1497   **    N>=12 and even       (N-12)/2        BLOB
  1495   1498   **    N>=13 and odd        (N-13)/2        text
  1496   1499   **
  1497   1500   */
  1498   1501   
  1499   1502   /*
  1500   1503   ** Return the serial-type for the value stored in pMem.
  1501   1504   */
  1502         -u32 sqlite3VdbeSerialType(Mem *pMem){
         1505  +u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
  1503   1506     int flags = pMem->flags;
  1504   1507   
  1505   1508     if( flags&MEM_Null ){
  1506   1509       return 0;
  1507   1510     }
  1508   1511     if( flags&MEM_Int ){
  1509   1512       /* Figure out whether to use 1, 2, 4, 6 or 8 bytes. */
  1510   1513   #   define MAX_6BYTE ((((i64)0x00001000)<<32)-1)
  1511   1514       i64 i = pMem->i;
  1512         -    u64 u = i<0 ? -i : i;
         1515  +    u64 u;
         1516  +    if( file_format>=4 && (i&1)==i ){
         1517  +      return 8+i;
         1518  +    }
         1519  +    u = i<0 ? -i : i;
  1513   1520       if( u<=127 ) return 1;
  1514   1521       if( u<=32767 ) return 2;
  1515   1522       if( u<=8388607 ) return 3;
  1516   1523       if( u<=2147483647 ) return 4;
  1517   1524       if( u<=MAX_6BYTE ) return 5;
  1518   1525       return 6;
  1519   1526     }
................................................................................
  1544   1551   }
  1545   1552   
  1546   1553   /*
  1547   1554   ** Write the serialized data blob for the value stored in pMem into 
  1548   1555   ** buf. It is assumed that the caller has allocated sufficient space.
  1549   1556   ** Return the number of bytes written.
  1550   1557   */ 
  1551         -int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem){
  1552         -  u32 serial_type = sqlite3VdbeSerialType(pMem);
         1558  +int sqlite3VdbeSerialPut(unsigned char *buf, Mem *pMem, int file_format){
         1559  +  u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
  1553   1560     int len;
  1554   1561   
  1555         -  /* NULL */
  1556         -  if( serial_type==0 ){
  1557         -    return 0;
  1558         -  }
  1559         - 
  1560   1562     /* Integer and Real */
  1561         -  if( serial_type<=7 ){
         1563  +  if( serial_type<=7 && serial_type>0 ){
  1562   1564       u64 v;
  1563   1565       int i;
  1564   1566       if( serial_type==7 ){
  1565   1567         v = *(u64*)&pMem->r;
  1566   1568       }else{
  1567   1569         v = *(u64*)&pMem->i;
  1568   1570       }
................................................................................
  1569   1571       len = i = sqlite3VdbeSerialTypeLen(serial_type);
  1570   1572       while( i-- ){
  1571   1573         buf[i] = (v&0xFF);
  1572   1574         v >>= 8;
  1573   1575       }
  1574   1576       return len;
  1575   1577     }
  1576         -  
         1578  +
  1577   1579     /* String or blob */
  1578         -  assert( serial_type>=12 );
  1579         -  len = sqlite3VdbeSerialTypeLen(serial_type);
  1580         -  memcpy(buf, pMem->z, len);
  1581         -  return len;
         1580  +  if( serial_type>=12 ){
         1581  +    len = sqlite3VdbeSerialTypeLen(serial_type);
         1582  +    memcpy(buf, pMem->z, len);
         1583  +    return len;
         1584  +  }
         1585  +
         1586  +  /* NULL or constants 0 or 1 */
         1587  +  return 0;
  1582   1588   }
  1583   1589   
  1584   1590   /*
  1585   1591   ** Deserialize the data blob pointed to by buf as serial type serial_type
  1586   1592   ** and store the result in pMem.  Return the number of bytes read.
  1587   1593   */ 
  1588   1594   int sqlite3VdbeSerialGet(
  1589   1595     const unsigned char *buf,     /* Buffer to deserialize from */
  1590   1596     u32 serial_type,              /* Serial type to deserialize */
  1591   1597     Mem *pMem                     /* Memory cell to write value into */
  1592   1598   ){
  1593   1599     switch( serial_type ){
  1594         -    case 8:    /* Reserved for future use */
  1595         -    case 9:    /* Reserved for future use */
  1596   1600       case 10:   /* Reserved for future use */
  1597   1601       case 11:   /* Reserved for future use */
  1598   1602       case 0: {  /* NULL */
  1599   1603         pMem->flags = MEM_Null;
  1600   1604         break;
  1601   1605       }
  1602   1606       case 1: { /* 1-byte signed integer */
................................................................................
  1646   1650           pMem->i = *(i64*)&x;
  1647   1651           pMem->flags = MEM_Int;
  1648   1652         }else{
  1649   1653           pMem->r = *(double*)&x;
  1650   1654           pMem->flags = MEM_Real;
  1651   1655         }
  1652   1656         return 8;
         1657  +    }
         1658  +    case 8:    /* Integer 0 */
         1659  +    case 9: {  /* Integer 1 */
         1660  +      pMem->i = serial_type-8;
         1661  +      pMem->flags = MEM_Int;
         1662  +      return 0;
  1653   1663       }
  1654   1664       default: {
  1655   1665         int len = (serial_type-12)/2;
  1656   1666         pMem->z = (char *)buf;
  1657   1667         pMem->n = len;
  1658   1668         pMem->xDel = 0;
  1659   1669         if( serial_type&0x01 ){

Changes to test/descidx1.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #*************************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is descending indices.
    13     13   #
    14         -# $Id: descidx1.test,v 1.2 2005/12/21 18:36:46 drh Exp $
           14  +# $Id: descidx1.test,v 1.3 2005/12/29 19:23:07 drh Exp $
    15     15   #
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # This procedure sets the value of the file-format in file 'test.db'
    21     21   # to $newval. Also, the schema cookie is incremented.
................................................................................
    36     36   proc get_file_format {{fname test.db}} {
    37     37     set bt [btree_open $fname 10 0]
    38     38     set meta [btree_get_meta $bt]
    39     39     btree_close $bt
    40     40     lindex $meta 2
    41     41   }
    42     42   
    43         -# Verify that the file format jumps to (at least) 4 as soon as a
    44         -# descending index is created.
           43  +# Verify that the file format starts as 4.
    45     44   #
    46     45   do_test descidx1-1.1 {
    47     46     execsql {
    48     47       CREATE TABLE t1(a,b);
    49     48       CREATE INDEX i1 ON t1(b ASC);
    50     49     }
    51     50     get_file_format
    52         -} {1}
           51  +} {4}
    53     52   do_test descidx1-1.2 {
    54     53     execsql {
    55     54       CREATE INDEX i2 ON t1(a DESC);
    56     55     }
    57     56     get_file_format
    58     57   } {4}
    59     58   

Changes to test/descidx2.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #*************************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is descending indices.
    13     13   #
    14         -# $Id: descidx2.test,v 1.1 2005/12/21 18:36:46 drh Exp $
           14  +# $Id: descidx2.test,v 1.2 2005/12/29 19:23:07 drh Exp $
    15     15   #
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # This procedure sets the value of the file-format in file 'test.db'
    21     21   # to $newval. Also, the schema cookie is incremented.
................................................................................
    36     36   proc get_file_format {{fname test.db}} {
    37     37     set bt [btree_open $fname 10 0]
    38     38     set meta [btree_get_meta $bt]
    39     39     btree_close $bt
    40     40     lindex $meta 2
    41     41   }
    42     42   
    43         -# Verify that the file format jumps to (at least) 4 as soon as a
    44         -# descending index is created.
           43  +# Verify that the file format starts as 4
    45     44   #
    46     45   do_test descidx2-1.1 {
    47     46     execsql {
    48     47       CREATE TABLE t1(a,b);
    49     48       CREATE INDEX i1 ON t1(b ASC);
    50     49     }
    51     50     get_file_format
    52         -} {1}
           51  +} {4}
    53     52   do_test descidx2-1.2 {
    54     53     execsql {
    55     54       CREATE INDEX i2 ON t1(a DESC);
    56     55     }
    57     56     get_file_format
    58     57   } {4}
    59     58   

Changes to test/types.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library. Specfically
    12     12   # it tests that the different storage classes (integer, real, text etc.)
    13     13   # all work correctly.
    14     14   #
    15         -# $Id: types.test,v 1.16 2005/11/14 22:29:06 drh Exp $
           15  +# $Id: types.test,v 1.17 2005/12/29 19:23:07 drh Exp $
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Tests in this file are organized roughly as follows:
    21     21   #
    22     22   # types-1.*.*: Test that values are stored using the expected storage
................................................................................
   204    204   } [list 0 120 -120 30000 -30000 2100000000 -2100000000 \
   205    205           9000000000000000000 -9000000000000000000]
   206    206   
   207    207   # Check that all the record sizes are as we expected.
   208    208   do_test types-2.1.9 {
   209    209     set root [db eval {select rootpage from sqlite_master where name = 't1'}]
   210    210     record_sizes $root
   211         -} {3 3 3 4 4 6 6 10 10}
          211  +} {2 3 3 4 4 6 6 10 10}
   212    212   
   213    213   # Insert some reals. These should be 10 byte records.
   214    214   do_test types-2.2.1 {
   215    215     execsql {
   216    216       CREATE TABLE t2(a float);
   217    217       INSERT INTO t2 VALUES(0.0);
   218    218       INSERT INTO t2 VALUES(12345.678);
................................................................................
   225    225     }
   226    226   } {0.0 12345.678 -12345.678}
   227    227   
   228    228   # Check that all the record sizes are as we expected.
   229    229   do_test types-2.2.3 {
   230    230     set root [db eval {select rootpage from sqlite_master where name = 't2'}]
   231    231     record_sizes $root
   232         -} {3 10 10}
          232  +} {2 10 10}
   233    233   
   234    234   # Insert a NULL. This should be a two byte record.
   235    235   do_test types-2.3.1 {
   236    236     execsql {
   237    237       CREATE TABLE t3(a nullvalue);
   238    238       INSERT INTO t3 VALUES(NULL);
   239    239     }