/ Check-in [ad4a9641]
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:Fix many problems with manifest types and column affinity. Most things are working now. (CVS 1393)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ad4a964158ba9ca9d221cf7ea0439577f3894890
User & Date: danielk1977 2004-05-18 10:06:25
Context
2004-05-18
12:50
Additional debugging output from btree.c (CVS 1394) check-in: b2def185 user: drh tags: trunk
10:06
Fix many problems with manifest types and column affinity. Most things are working now. (CVS 1393) check-in: ad4a9641 user: danielk1977 tags: trunk
09:58
Fix many problems with manifest types and column affinity. Most things are working now. (CVS 1392) check-in: a62872aa user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     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         -** $Id: btree.c,v 1.141 2004/05/16 16:24:37 drh Exp $
           12  +** $Id: btree.c,v 1.142 2004/05/18 10:06:25 danielk1977 Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** For a detailed discussion of BTrees, refer to
    16     16   **
    17     17   **     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
    18     18   **     "Sorting And Searching", pages 473-480. Addison-Wesley
    19     19   **     Publishing Company, Reading, Massachusetts.
................................................................................
  1401   1401     if( pCur ){
  1402   1402       releasePage(pCur->pPage);
  1403   1403       sqliteFree(pCur);
  1404   1404     }
  1405   1405     unlockBtreeIfUnused(pBt);
  1406   1406     return rc;
  1407   1407   }
         1408  +
         1409  +void sqlite3BtreeSetCompare(
         1410  +  BtCursor *pCur,
         1411  +  int(* xCmp)(void*,int,const void*,int,const void*),
         1412  +  void *pArg
         1413  +){
         1414  +  pCur->xCompare = xCmp ? xCmp : dfltCompare;
         1415  +  pCur->pArg = pArg;
         1416  +}
  1408   1417   
  1409   1418   /*
  1410   1419   ** Close a cursor.  The read lock on the database file is released
  1411   1420   ** when the last cursor is closed.
  1412   1421   */
  1413   1422   int sqlite3BtreeCloseCursor(BtCursor *pCur){
  1414   1423     Btree *pBt = pCur->pBt;

Changes to src/btree.h.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This header file defines the interface that the sqlite B-Tree file
    13     13   ** subsystem.  See comments in the source code for a detailed description
    14     14   ** of what each interface routine does.
    15     15   **
    16         -** @(#) $Id: btree.h,v 1.47 2004/05/12 19:18:17 drh Exp $
           16  +** @(#) $Id: btree.h,v 1.48 2004/05/18 10:06:25 danielk1977 Exp $
    17     17   */
    18     18   #ifndef _BTREE_H_
    19     19   #define _BTREE_H_
    20     20   
    21     21   /* TODO: This definition is just included so other modules compile. It
    22     22   ** needs to be revisited.
    23     23   */
................................................................................
    68     68     Btree*,                              /* BTree containing table to open */
    69     69     int iTable,                          /* Index of root page */
    70     70     int wrFlag,                          /* 1 for writing.  0 for read-only */
    71     71     int(*)(void*,int,const void*,int,const void*),  /* Key comparison function */
    72     72     void*,                               /* First argument to compare function */
    73     73     BtCursor **ppCursor                  /* Returned cursor */
    74     74   );
           75  +
           76  +void sqlite3BtreeSetCompare(
           77  +  BtCursor *,
           78  +  int(*)(void*,int,const void*,int,const void*),
           79  +  void*
           80  +);
    75     81   
    76     82   int sqlite3BtreeCloseCursor(BtCursor*);
    77     83   int sqlite3BtreeMoveto(BtCursor*, const void *pKey, i64 nKey, int *pRes);
    78     84   int sqlite3BtreeDelete(BtCursor*);
    79     85   int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
    80     86                                     const void *pData, int nData);
    81     87   int sqlite3BtreeFirst(BtCursor*, int *pRes);

Changes to src/expr.c.

     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   ** This file contains routines used for analyzing expressions and
    13     13   ** for generating VDBE code that evaluates expressions in SQLite.
    14     14   **
    15         -** $Id: expr.c,v 1.121 2004/05/17 10:48:58 danielk1977 Exp $
           15  +** $Id: expr.c,v 1.122 2004/05/18 10:06:25 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include <ctype.h>
    19     19   
    20     20   char const *sqlite3AffinityString(char affinity){
    21     21     switch( affinity ){
    22     22       case SQLITE_AFF_INTEGER: return "i";
................................................................................
    41     41   ** have an affinity:
    42     42   **
    43     43   ** CREATE TABLE t1(a);
    44     44   ** SELECT * FROM t1 WHERE a;
    45     45   ** SELECT a AS b FROM t1 WHERE b;
    46     46   ** SELECT * FROM t1 WHERE (select a from t1);
    47     47   */
    48         -static char exprAffinity(Expr *pExpr){
           48  +char sqlite3ExprAffinity(Expr *pExpr){
    49     49     if( pExpr->op==TK_AS ){
    50         -    return exprAffinity(pExpr->pLeft);
           50  +    return sqlite3ExprAffinity(pExpr->pLeft);
    51     51     }
    52     52     if( pExpr->op==TK_SELECT ){
    53         -    return exprAffinity(pExpr->pSelect->pEList->a[0].pExpr);
           53  +    return sqlite3ExprAffinity(pExpr->pSelect->pEList->a[0].pExpr);
    54     54     }
    55     55     return pExpr->affinity;
    56     56   }
    57     57   
    58     58   char sqlite3CompareAffinity(Expr *pExpr, char aff2){
    59         -  char aff1 = exprAffinity(pExpr);
           59  +  char aff1 = sqlite3ExprAffinity(pExpr);
    60     60     if( aff1 && aff2 ){
    61     61       /* Both sides of the comparison are columns. If one has numeric or
    62     62       ** integer affinity, use that. Otherwise use no affinity.
    63     63       */
    64     64       if( aff1==SQLITE_AFF_INTEGER || aff2==SQLITE_AFF_INTEGER ){
    65     65         return SQLITE_AFF_INTEGER;
    66     66       }else if( aff1==SQLITE_AFF_NUMERIC || aff2==SQLITE_AFF_NUMERIC ){
................................................................................
    81     81   
    82     82   static char comparisonAffinity(Expr *pExpr){
    83     83     char aff;
    84     84     assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT ||
    85     85             pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE ||
    86     86             pExpr->op==TK_NE );
    87     87     assert( pExpr->pLeft );
    88         -  aff = exprAffinity(pExpr->pLeft);
           88  +  aff = sqlite3ExprAffinity(pExpr->pLeft);
    89     89     if( pExpr->pRight ){
    90     90       aff = sqlite3CompareAffinity(pExpr->pRight, aff);
    91     91     }
    92     92     else if( pExpr->pSelect ){
    93     93       aff = sqlite3CompareAffinity(pExpr->pSelect->pEList->a[0].pExpr, aff);
    94     94     }
    95     95     else if( !aff ){
................................................................................
   117    117   ** Return the P1 value that should be used for a binary comparison
   118    118   ** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.
   119    119   ** If jumpIfNull is true, then set the low byte of the returned
   120    120   ** P1 value to tell the opcode to jump if either expression
   121    121   ** evaluates to NULL.
   122    122   */
   123    123   static int binaryCompareP1(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){
   124         -  char aff = exprAffinity(pExpr2);
          124  +  char aff = sqlite3ExprAffinity(pExpr2);
   125    125     return (((int)sqlite3CompareAffinity(pExpr1, aff))<<8)+(jumpIfNull?1:0);
   126    126   }
   127    127   
   128    128   /*
   129    129   ** Construct a new expression node and return a pointer to it.  Memory
   130    130   ** for this node is obtained from sqliteMalloc().  The calling function
   131    131   ** is responsible for making sure the node eventually gets freed.
................................................................................
   798    798       case TK_IN: {
   799    799         char affinity;
   800    800         Vdbe *v = sqlite3GetVdbe(pParse);
   801    801         if( v==0 ) return 1;
   802    802         if( sqlite3ExprResolveIds(pParse, pSrcList, pEList, pExpr->pLeft) ){
   803    803           return 1;
   804    804         }
   805         -      affinity = exprAffinity(pExpr->pLeft);
          805  +      affinity = sqlite3ExprAffinity(pExpr->pLeft);
   806    806   
   807    807         /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
   808    808         ** expression it is handled the same way. A temporary table is 
   809    809         ** filled with single-field index keys representing the results
   810    810         ** from the SELECT or the <exprlist>.
   811    811         **
   812    812         ** If the 'x' expression is a column value, or the SELECT...
................................................................................
   824    824           /* Case 1:     expr IN (SELECT ...)
   825    825           **
   826    826           ** Generate code to write the results of the select into the temporary
   827    827           ** table allocated and opened above.
   828    828           */
   829    829           int iParm = pExpr->iTable +  (((int)affinity)<<16);
   830    830           assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
   831         -        sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0);
          831  +        sqlite3Select(pParse, pExpr->pSelect, SRT_Set, iParm, 0, 0, 0, 0);
   832    832         }else if( pExpr->pList ){
   833    833           /* Case 2:     expr IN (exprlist)
   834    834           **
   835    835   	** For each expression, build an index key from the evaluation and
   836    836           ** store it in the temporary table. If <expr> is a column, then use
   837    837           ** that columns affinity when building index keys. If <expr> is not
   838    838           ** a column, use numeric affinity.
................................................................................
   870    870   
   871    871       case TK_SELECT: {
   872    872         /* This has to be a scalar SELECT.  Generate code to put the
   873    873         ** value of this select in a memory cell and record the number
   874    874         ** of the memory cell in iColumn.
   875    875         */
   876    876         pExpr->iColumn = pParse->nMem++;
   877         -      if( sqlite3Select(pParse, pExpr->pSelect, SRT_Mem, pExpr->iColumn,0,0,0) ){
          877  +      if(sqlite3Select(pParse, pExpr->pSelect, SRT_Mem,pExpr->iColumn,0,0,0,0)){
   878    878           return 1;
   879    879         }
   880    880         break;
   881    881       }
   882    882   
   883    883       /* For all else, just recursively walk the tree */
   884    884       default: {

Changes to src/parse.y.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains SQLite's grammar for SQL.  Process this file
    13     13   ** using the lemon parser generator to generate C code that runs
    14     14   ** the parser.  Lemon will also generate a header file containing
    15     15   ** numeric codes for all of the tokens.
    16     16   **
    17         -** @(#) $Id: parse.y,v 1.113 2004/05/08 08:23:30 danielk1977 Exp $
           17  +** @(#) $Id: parse.y,v 1.114 2004/05/18 10:06:25 danielk1977 Exp $
    18     18   */
    19     19   %token_prefix TK_
    20     20   %token_type {Token}
    21     21   %default_type {Token}
    22     22   %extra_argument {Parse *pParse}
    23     23   %syntax_error {
    24     24     if( pParse->zErrMsg==0 ){
................................................................................
   274    274   cmd ::= DROP VIEW nm(X). {
   275    275     sqlite3DropTable(pParse, &X, 1);
   276    276   }
   277    277   
   278    278   //////////////////////// The SELECT statement /////////////////////////////////
   279    279   //
   280    280   cmd ::= select(X).  {
   281         -  sqlite3Select(pParse, X, SRT_Callback, 0, 0, 0, 0);
          281  +  sqlite3Select(pParse, X, SRT_Callback, 0, 0, 0, 0, 0);
   282    282     sqlite3SelectDelete(X);
   283    283   }
   284    284   
   285    285   %type select {Select*}
   286    286   %destructor select {sqlite3SelectDelete($$);}
   287    287   %type oneselect {Select*}
   288    288   %destructor oneselect {sqlite3SelectDelete($$);}

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.235 2004/05/17 10:48:58 danielk1977 Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.236 2004/05/18 10:06:26 danielk1977 Exp $
    15     15   */
    16     16   #include "config.h"
    17     17   #include "sqlite.h"
    18     18   #include "hash.h"
    19     19   #include "parse.h"
    20     20   #include <stdio.h>
    21     21   #include <stdlib.h>
................................................................................
  1187   1187   void sqlite3SrcListAssignCursors(Parse*, SrcList*);
  1188   1188   void sqlite3IdListDelete(IdList*);
  1189   1189   void sqlite3SrcListDelete(SrcList*);
  1190   1190   void sqlite3CreateIndex(Parse*,Token*,SrcList*,IdList*,int,Token*,Token*);
  1191   1191   void sqlite3DropIndex(Parse*, SrcList*);
  1192   1192   void sqlite3AddKeyType(Vdbe*, ExprList*);
  1193   1193   void sqlite3AddIdxKeyType(Vdbe*, Index*);
  1194         -int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*);
         1194  +int sqlite3Select(Parse*, Select*, int, int, Select*, int, int*, char *aff);
  1195   1195   Select *sqlite3SelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
  1196   1196                           int,int,int);
  1197   1197   void sqlite3SelectDelete(Select*);
  1198   1198   void sqlite3SelectUnbind(Select*);
  1199   1199   Table *sqlite3SrcListLookup(Parse*, SrcList*);
  1200   1200   int sqlite3IsReadOnly(Parse*, Table*, int);
  1201   1201   void sqlite3DeleteFrom(Parse*, SrcList*, Expr*);
................................................................................
  1305   1305   int sqlite3VarintLen(u64 v);
  1306   1306   char sqlite3AffinityType(const char *, int);
  1307   1307   void sqlite3IndexAffinityStr(Vdbe *, Index *);
  1308   1308   void sqlite3TableAffinityStr(Vdbe *, Table *);
  1309   1309   char sqlite3CompareAffinity(Expr *pExpr, char aff2);
  1310   1310   char const *sqlite3AffinityString(char affinity);
  1311   1311   int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
         1312  +char sqlite3ExprAffinity(Expr *pExpr);

Changes to src/trigger.c.

   185    185       static VdbeOpList insertTrig[] = {
   186    186         { OP_NewRecno,   0, 0,  0          },
   187    187         { OP_String,     0, 0,  "trigger"  },
   188    188         { OP_String,     0, 0,  0          },  /* 2: trigger name */
   189    189         { OP_String,     0, 0,  0          },  /* 3: table name */
   190    190         { OP_Integer,    0, 0,  0          },
   191    191         { OP_String,     0, 0,  0          },  /* 5: SQL */
   192         -      { OP_MakeRecord, 5, 0,  0          },
          192  +      { OP_MakeRecord, 5, 0,  "tttit"    },
   193    193         { OP_PutIntKey,  0, 0,  0          },
   194    194       };
   195    195       int addr;
   196    196       Vdbe *v;
   197    197   
   198    198       /* Make an entry in the sqlite_master table */
   199    199       v = sqlite3GetVdbe(pParse);
................................................................................
   611    611       orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
   612    612       pParse->trigStack->orconf = orconf;
   613    613       switch( pTriggerStep->op ){
   614    614         case TK_SELECT: {
   615    615   	Select * ss = sqlite3SelectDup(pTriggerStep->pSelect);		  
   616    616   	assert(ss);
   617    617   	assert(ss->pSrc);
   618         -	sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0);
          618  +	sqlite3Select(pParse, ss, SRT_Discard, 0, 0, 0, 0, 0);
   619    619   	sqlite3SelectDelete(ss);
   620    620   	break;
   621    621         }
   622    622         case TK_UPDATE: {
   623    623           SrcList *pSrc;
   624    624           pSrc = targetSrcList(pParse, pTriggerStep);
   625    625           sqlite3VdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);

Changes to src/vdbe.h.

    11     11   *************************************************************************
    12     12   ** Header file for the Virtual DataBase Engine (VDBE)
    13     13   **
    14     14   ** This header defines the interface to the virtual database engine
    15     15   ** or VDBE.  The VDBE implements an abstract machine that runs a
    16     16   ** simple program to access and modify the underlying database.
    17     17   **
    18         -** $Id: vdbe.h,v 1.75 2004/05/13 05:16:17 danielk1977 Exp $
           18  +** $Id: vdbe.h,v 1.76 2004/05/18 10:06:26 danielk1977 Exp $
    19     19   */
    20     20   #ifndef _SQLITE_VDBE_H_
    21     21   #define _SQLITE_VDBE_H_
    22     22   #include <stdio.h>
    23     23   
    24     24   /*
    25     25   ** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
    90     90   int sqlite3VdbeOp3(Vdbe*,int,int,int,const char *zP3,int);
    91     91   int sqlite3VdbeCode(Vdbe*,...);
    92     92   int sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
    93     93   void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1);
    94     94   void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2);
    95     95   void sqlite3VdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
    96     96   void sqlite3VdbeDequoteP3(Vdbe*, int addr);
    97         -int sqlite3VdbeFindOp(Vdbe*, int, int);
           97  +int sqlite3VdbeFindOp(Vdbe*, int, int, int);
    98     98   VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
    99     99   int sqlite3VdbeMakeLabel(Vdbe*);
   100    100   void sqlite3VdbeDelete(Vdbe*);
   101    101   void sqlite3VdbeMakeReady(Vdbe*,int,int);
   102    102   int sqlite3VdbeExec(Vdbe*);
   103    103   int sqlite3VdbeList(Vdbe*);
   104    104   int sqlite3VdbeFinalize(Vdbe*,char**);
   105    105   void sqlite3VdbeResolveLabel(Vdbe*, int);
   106    106   int sqlite3VdbeCurrentAddr(Vdbe*);
   107    107   void sqlite3VdbeTrace(Vdbe*,FILE*);
   108    108   void sqlite3VdbeCompressSpace(Vdbe*,int);
   109    109   int sqlite3VdbeReset(Vdbe*,char **);
   110    110   int sqliteVdbeSetVariables(Vdbe*,int,const char**);
   111         -int sqlite3VdbeKeyCompare(void*,int,const void*,int, const void*);
   112    111   
   113    112   #endif

Changes to src/vdbeInt.h.

   330    330   int sqlite3VdbeSerialPut(unsigned char *, const Mem *);
   331    331   int sqlite3VdbeSerialGet(const unsigned char *, u64, Mem *);
   332    332   
   333    333   int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
   334    334   int sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int, int*);
   335    335   int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
   336    336   int sqlite3MemCompare(Mem *, Mem *);
          337  +int sqlite3VdbeKeyCompare(void*,int,const void*,int, const void*);
          338  +int sqlite3VdbeRowCompare(void*,int,const void*,int, const void*);

Changes to test/quick.test.

     6      6   #    May you do good and not evil.
     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 runs all tests.
    12     12   #
    13         -# $Id: quick.test,v 1.11 2004/05/14 11:00:53 danielk1977 Exp $
           13  +# $Id: quick.test,v 1.12 2004/05/18 10:06:26 danielk1977 Exp $
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   rename finish_test really_finish_test
    18     18   proc finish_test {} {}
    19     19   set ISQUICK 1
    20     20   
................................................................................
    41     41   lappend EXCLUDE tableapi.test     ;# sqlite3_XX vs sqlite_XX problem
    42     42   lappend EXCLUDE version.test      ;# uses the btree_meta API (not updated)
    43     43   
    44     44   # Some tests fail in these file as a result of the partial manifest types
    45     45   # implementation.
    46     46   lappend EXCLUDE misc1.test 
    47     47   lappend EXCLUDE capi2.test 
    48         -lappend EXCLUDE sort.test
    49     48   lappend EXCLUDE where.test
    50     49   
    51     50   
    52     51   if {[sqlite -has-codec]} {
    53     52     lappend EXCLUDE \
    54     53       attach.test \
    55     54       attach2.test \

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.3 2004/05/16 22:55:28 danielk1977 Exp $
           15  +# $Id: types.test,v 1.4 2004/05/18 10:06:26 danielk1977 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
................................................................................
   195    195   } [list 0 120 -120 30000 -30000 2100000000 -2100000000 \
   196    196           9000000000000000000 -9000000000000000000]
   197    197   
   198    198   # Check that all the record sizes are as we expected.
   199    199   do_test types-2.1.9 {
   200    200     set root [db eval {select rootpage from sqlite_master where name = 't1'}]
   201    201     record_sizes $root
   202         -} {3 3 3 4 4 6 6 10 10}
          202  +} {2 2 2 3 3 5 5 9 9}
   203    203   
   204    204   # Insert some reals. These should be 10 byte records.
   205    205   do_test types-2.2.1 {
   206    206     execsql {
   207    207       CREATE TABLE t2(a float);
   208    208       INSERT INTO t2 VALUES(0.0);
   209    209       INSERT INTO t2 VALUES(12345.678);
................................................................................
   216    216     }
   217    217   } {0 12345.678 -12345.678}
   218    218   
   219    219   # Check that all the record sizes are as we expected.
   220    220   do_test types-2.2.3 {
   221    221     set root [db eval {select rootpage from sqlite_master where name = 't2'}]
   222    222     record_sizes $root
   223         -} {10 10 10}
          223  +} {9 9 9}
   224    224   
   225    225   # Insert a NULL. This should be a two byte record.
   226    226   do_test types-2.3.1 {
   227    227     execsql {
   228    228       CREATE TABLE t3(a nullvalue);
   229    229       INSERT INTO t3 VALUES(NULL);
   230    230     }
................................................................................
   235    235     }
   236    236   } {1}
   237    237   
   238    238   # Check that all the record sizes are as we expected.
   239    239   do_test types-2.3.3 {
   240    240     set root [db eval {select rootpage from sqlite_master where name = 't3'}]
   241    241     record_sizes $root
   242         -} {2}
          242  +} {1}
   243    243   
   244    244   # Insert a couple of strings.
   245    245   do_test types-2.4.1 {
   246    246     set string10 abcdefghij
   247    247     set string500 [string repeat $string10 50]
   248    248     set string500000 [string repeat $string10 50000]
   249    249   
................................................................................
   260    260     }
   261    261   } [list $string10 $string500 $string500000]
   262    262   
   263    263   # Check that all the record sizes are as we expected.
   264    264   do_test types-2.4.3 {
   265    265     set root [db eval {select rootpage from sqlite_master where name = 't4'}]
   266    266     record_sizes $root
   267         -} {13 504 500005}
          267  +} {11 502 500003}
   268    268   
   269    269   do_test types-2.5.1 {
   270    270     execsql {
   271    271       DROP TABLE t1;
   272    272       DROP TABLE t2;
   273    273       DROP TABLE t3;
   274    274       DROP TABLE t4;