diff --git a/manifest b/manifest index 4863192a1c..c2dfab9d05 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\stable\srecord\sformat\sto\ssupport\smanifest\styping.\s(CVS\s1361) -D 2004-05-12T07:33:33 +C Add\ssome\smore\scode\sto\ssupport\smanifest\styping\sin\sindices.\sNot\sactivated\syet.\s(CVS\s1362) +D 2004-05-12T11:24:03 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -26,7 +26,7 @@ F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79 F src/btree.c 35df9e6d3a30bbe2d32d6b08f51e2a16b835c6e8 F src/btree.h 578dc465c801cf4e7666efbb0fa1c46a54758008 F src/btree_rb.c 9d7973e266ee6f9c61ce592f68742ce9cd5b10e5 -F src/build.c 97d8b3fc6c48fcd355fcfe7b2e291f6e57159d62 +F src/build.c f25e4ac9f102efd70188bc09a459c2b461fe2135 F src/copy.c 4d2038602fd0549d80c59bda27d96f13ea9b5e29 F src/date.c 1564caa119511a1bb23dd0b1530ad38ed8c3349b F src/delete.c 30c8c4375e75e811c3668abf3f78970fe549f375 @@ -36,7 +36,7 @@ F src/func.c 6cf6501f092b41c8cd9368b09c287016c0576438 F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb F src/insert.c 1e63d2774c4d893363e0c072f19d4c92a4ab982d -F src/main.c a5e34ce9bbb9afbb26a95a1e2b125ef496cfc0d4 +F src/main.c 4b82d7e78f4c9799343b02740a5ba9768d5e464d F src/md5.c 8e39fdae6d8776b87558e91dcc94740c9b635a9c F src/os.c ddcda92f7fd71b4513c57c1ec797917f206d504e F src/os.h fbb2f6595fc34fa351830d88fe1c6b85118f0383 @@ -49,7 +49,7 @@ F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c ca99ae4db14a45a436ec51d3e6bd48d44a3efb3c F src/shell.c 255b8b9023cb5274f56d87df437e8ce6ef810b91 F src/sqlite.h.in 799c5e726296ec7bc20e6407cdf4df0e0bc00c0c -F src/sqliteInt.h 3abc94fbd3ca0eff1197c71523ab2772100f1b3f +F src/sqliteInt.h 168f441f72f5d1ab476ea85ac544712fe57f31c0 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/tclsqlite.c fbf0fac73624ae246551a6c671f1de0235b5faa1 F src/test1.c ba4c25985916a82cfa375145a90e2c8d4b0a6a20 @@ -63,10 +63,10 @@ F src/update.c 6ca82fc4a0fb4d7f134e961921c906f6f3c8bc74 F src/utf.c fc799748d43fe1982d157b871e3e420a19c85d4f F src/util.c 778a8cd03ad6e52778602d20a3132c7d2d1b0a0c F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476 -F src/vdbe.c cd9889955eb8d9192d5536ffb9640ee7239928a9 -F src/vdbe.h 2dc4d1161b64f5684faa6a2d292e318a185ecb2e +F src/vdbe.c 9b82d9ed192729e00581ae08d1cd71a27a698fe0 +F src/vdbe.h 71c02a75d506a3ce9f6bdfc78101528d5edf319b F src/vdbeInt.h 3610b51a3207f1d4e780748a6d8f13cfe98ce2f7 -F src/vdbeaux.c 6e36f00843b46863a858146c5d3f8d400f3a4ef2 +F src/vdbeaux.c c976c7fe334a1d1c102dda410546e880549a6060 F src/where.c 487e55b1f64c8fbf0f46a9a90c2247fc45ae6a9a F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83 @@ -121,7 +121,7 @@ F test/progress.test 701b6115c2613128ececdfe1398a1bd0e1a4cfb3 x F test/quick.test 25df45ec1f8551279358dc0f0a2388ab59e06a30 F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d F test/rowid.test 77f7e8c7ca626a15ff91a536595b695cfce7c845 -F test/select1.test 0d708cec567104653ec9aa49fecf3444a2e7d150 +F test/select1.test 3bfcccd2eadcddbb07f1f5da6550aee8484ea4fb F test/select2.test aceea74fd895b9d007512f72499db589735bd8e4 F test/select3.test 445a1a3dde4e2fd32541b311f55da5e2f8079d76 F test/select4.test e7e9a32fa745246cb99fadbeb63af4843a17925b @@ -133,7 +133,7 @@ F test/table.test 371a1fc1c470982b2f68f9732f903a5d96f949c4 F test/tableapi.test e0c4cce61e58343caa84dab33fa6823cb35fe1e1 F test/tclsqlite.test a684fc191b81e6cded8a81263663d5a130fbb013 F test/temptable.test a770ba6308d7f7332fce985086b8e06bed6430c2 -F test/tester.tcl 3780967a81e8d3e32caf167c9db3a66210ff69ff +F test/tester.tcl 4b7e254be6b3f817d992f42391a73465d7330f16 F test/thread1.test 53f050d5be6932d9430df7756edd379366508ff6 F test/threadtest1.c f7f896e62ed46feae1dc411114a48c15a0f82ee2 F test/threadtest2.c d94ca4114fd1504f7e0ae724bcd83d4b40931d86 @@ -142,6 +142,7 @@ F test/trigger1.test 4538c1c7d6bbca5dfe619ea6e1682b07ece95b21 F test/trigger2.test 0767ab30cb5a2c8402c8524f3d566b410b6f5263 F test/trigger3.test a95ccace88291449f5eae7139ec438a42f90654d F test/trigger4.test 542afce45774e8f8e1130b96b8675f414d6e4bd8 +F test/types.test 53e3d97c33651afad7bc8bd4cf71b97b473b19ad F test/unique.test 0e38d4cc7affeef2527720d1dafd1f6870f02f2b F test/update.test b29bd9061a1150426dab6959806fcc73a41b1217 F test/vacuum.test a2a44544df719666efb51afbfeb6062fd59a672a @@ -188,7 +189,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 98f756e6a0809e7034bfb587ff9d9085baac0c6e -R dd0d5c657e5977be7af4601ca71b34fa +P 0242c9e4f7c85e9c911cf30d90b0cdb1015f3d7d +R 55c977fb56a1a23227079a7a24ed9935 U danielk1977 -Z df31445cae4822bd5331db505e4c814c +Z 9a14b0592b340e466792086217d73072 diff --git a/manifest.uuid b/manifest.uuid index f7f6c0179f..0b2ab7a968 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0242c9e4f7c85e9c911cf30d90b0cdb1015f3d7d \ No newline at end of file +2f16c9ef3c101c4280991ce3cb0c3bea7b6ed439 \ No newline at end of file diff --git a/src/build.c b/src/build.c index e250533f8e..b672449492 100644 --- a/src/build.c +++ b/src/build.c @@ -23,7 +23,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.181 2004/05/11 07:11:52 danielk1977 Exp $ +** $Id: build.c,v 1.182 2004/05/12 11:24:03 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -1228,14 +1228,16 @@ void sqlite3DropTable(Parse *pParse, Token *pName, int isView){ v = sqlite3GetVdbe(pParse); if( v ){ static VdbeOpList dropTable[] = { - { OP_Rewind, 0, ADDR(8), 0}, + { OP_Rewind, 0, ADDR(10), 0}, { OP_String, 0, 0, 0}, /* 1 */ { OP_MemStore, 1, 1, 0}, { OP_MemLoad, 1, 0, 0}, /* 3 */ { OP_Column, 0, 2, 0}, - { OP_Ne, 0, ADDR(7), 0}, + { OP_Ne, 0, ADDR(9), 0}, { OP_Delete, 0, 0, 0}, - { OP_Next, 0, ADDR(3), 0}, /* 7 */ + { OP_Rewind, 0, ADDR(10), 0}, + { OP_Goto, 0, ADDR(3), 0}, + { OP_Next, 0, ADDR(3), 0}, /* 9 */ }; Index *pIdx; Trigger *pTrigger; diff --git a/src/main.c b/src/main.c index fe7ace864b..f5c0489c20 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.174 2004/05/11 09:50:02 danielk1977 Exp $ +** $Id: main.c,v 1.175 2004/05/12 11:24:03 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -286,15 +286,9 @@ static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){ }else{ if( iDb==0 ){ /* This SQL statement tries to read the temp.* schema from the - ** sqlite_temp_master table. It might return SQLITE_EMPTY. We - ** unset the SQLITE_InternChanges flag temporarily to ensure - ** that the sqlite_master entry is not removed from the internal - ** schema if this does return SQLITE_EMPTY. + ** sqlite_temp_master table. It might return SQLITE_EMPTY. */ - assert( db->flags&SQLITE_InternChanges ); - db->flags &= ~SQLITE_InternChanges; rc = sqlite3_exec(db, init_script1, sqlite3InitCallback, &initData, 0); - db->flags |= SQLITE_InternChanges; if( rc==SQLITE_OK || rc==SQLITE_EMPTY ){ rc = sqlite3_exec(db, init_script2, sqlite3InitCallback, &initData, 0); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index fcfe381df4..5f264faf6c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.230 2004/05/12 07:33:33 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.231 2004/05/12 11:24:03 danielk1977 Exp $ */ #include "config.h" #include "sqlite.h" @@ -258,6 +258,7 @@ typedef struct TriggerStack TriggerStack; typedef struct FKey FKey; typedef struct Db Db; typedef struct AuthContext AuthContext; +typedef struct KeyClass KeyClass; /* ** Each database file to be accessed by the system is an instance diff --git a/src/vdbe.c b/src/vdbe.c index cdef6a75ff..6f68b87857 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.283 2004/05/12 07:33:33 danielk1977 Exp $ +** $Id: vdbe.c,v 1.284 2004/05/12 11:24:03 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -2280,6 +2280,75 @@ case OP_MakeKey: { break; } +/* Opcode: MakeIdxKey3 P1 P2 P3 +** +** Convert the top P1 entries of the stack into a single entry suitable +** for use as the key in an index. In addition, take one additional integer +** off of the stack, treat that integer as an eight-byte record number, and +** append the integer to the key as a varint. Thus a total of P1+1 entries +** are popped from the stack for this instruction and a single entry is +** pushed back. The first P1 entries that are popped are strings and the +** last entry (the lowest on the stack) is an integer record number. +*/ +case OP_MakeKey3: +case OP_MakeIdxKey3: { + Mem *pRec; + Mem *pData0; + int nField; + u64 rowid; + int nByte = 0; + int addRowid; + char *zKey; /* The new key */ + + nField = pOp->p1; + pData0 = &pTos[1-nField]; + assert( pData0>=p->aStack ); + + addRowid = (pOp->opcode==OP_MakeIdxKey?1:0); + + /* Calculate the number of bytes required for the new index key and + ** store that number in nByte. Also set rowid to the record number to + ** append to the index key. + */ + for(pRec=pData0; pRec<=pTos; pRec++){ + u64 serial_type = sqlite3VdbeSerialType(pRec); + nByte += sqlite3VarintLen(serial_type); + nByte += sqlite3VdbeSerialTypeLen(serial_type); + } + if( addRowid ){ + pRec = &pData0[-nField]; + assert( pRec>=p->aStack ); + Integerify(pRec); + rowid = pRec->i; + nByte += sqlite3VarintLen(rowid); + } + + /* Allocate space for the new key */ + zKey = sqliteMalloc(nByte); + if( !zKey ){ + rc = SQLITE_NOMEM; + goto abort_due_to_error; + } + + /* Build the key in the buffer pointed to by zKey. */ + for(pRec=pData0; pRec<=pTos; pRec++){ + zKey += sqlite3PutVarint(zKey, sqlite3VdbeSerialType(pRec)); + zKey += sqlite3VdbeSerialPut(zKey, pRec); + } + if( addRowid ){ + sqlite3PutVarint(zKey, rowid); + } + + /* Pop the consumed values off the stack and push on the new key. */ + popStack(&pTos, nField+addRowid); + pTos++; + pTos->flags = MEM_Blob|MEM_Dyn; + pTos->z = zKey; + pTos->n = nByte; + + break; +} + /* Opcode: IncrKey * * * ** ** The top of the stack should contain an index key generated by diff --git a/src/vdbe.h b/src/vdbe.h index ea092e909f..6ba1bfeac0 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -15,7 +15,7 @@ ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.73 2004/05/08 10:56:17 drh Exp $ +** $Id: vdbe.h,v 1.74 2004/05/12 11:24:03 danielk1977 Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -108,6 +108,7 @@ void sqlite3VdbeTrace(Vdbe*,FILE*); void sqlite3VdbeCompressSpace(Vdbe*,int); int sqlite3VdbeReset(Vdbe*,char **); int sqliteVdbeSetVariables(Vdbe*,int,const char**); -int sqlite3VdbeKeyCompare(void*,int,const u8*,int, const u8*); +int sqlite3VdbeKeyCompare(void*,int,const unsigned char*,int, + const unsigned char*); #endif diff --git a/src/vdbeaux.c b/src/vdbeaux.c index ad4ba57e1e..3e69965ec6 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1297,94 +1297,123 @@ int sqlite3VdbeSerialGet(const unsigned char *buf, u64 serial_type, Mem *pMem){ return len; } +/* +** Compare the values contained by the two memory cells, returning +** negative, zero or positive if pMem1 is less than, equal to, or greater +** than pMem2. Sorting order is NULL's first, followed by numbers (integers +** and reals) sorted numerically, followed by text ordered by memcmp() and +** finally blob's ordered by memcmp(). +** +** Two NULL values are considered equal by this function. +*/ +int compareMemCells(Mem *pMem1, Mem *pMem2){ + int rc; + int combined_flags = pMem1->flags|pMem2->flags; + + /* If one value is NULL, it is less than the other. If both values + ** are NULL, return 0. + */ + if( combined_flags&MEM_Null ){ + return (pMem2->flags&MEM_Null) - (pMem1->flags&MEM_Null); + } + + /* If one value is a number and the other is not, the number is less. + ** If both are numbers, compare as reals if one is a real, or as integers + ** if both values are integers. + */ + if( combined_flags&(MEM_Int|MEM_Real) ){ + if( !(pMem1->flags&(MEM_Int|MEM_Real)) ){ + return 1; + } + if( !(pMem2->flags&(MEM_Int|MEM_Real)) ){ + return -1; + } + + if( combined_flags&MEM_Real ){ + if( pMem1->flags&MEM_Int ){ + pMem1->r = pMem1->i; + } + if( pMem2->flags&MEM_Int ){ + pMem2->r = pMem2->i; + } + if( pMem1->r < pMem2->r ) return -1; + if( pMem1->r > pMem2->r ) return 1; + return 0; + } + + if( pMem1->i < pMem2->i ) return -1; + if( pMem1->i > pMem2->i ) return 1; + return 0; + } + + /* Both values must be strings or blobs. If only one is a string, then + ** that value is less. Otherwise, compare with memcmp(). If memcmp() + ** returns 0 and one value is longer than the other, then that value + ** is greater. + */ + rc = (pMem2->flags&MEM_Null) - (pMem1->flags&MEM_Null); + if( rc ){ + return rc; + } + rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n); + if( rc ){ + return rc; + } + + if( pMem1->n < pMem2->n ) return -1; + if( pMem1->n > pMem2->n ) return 1; + return 0; +} + /* ** The following is the comparison function for (non-integer) ** keys in the btrees. This function returns negative, zero, or ** positive if the first key is less than, equal to, or greater than ** the second. ** -** The key consists of multiple fields. Each field begins with a variable -** length integer which determines the field type and the number of bytes -** of key data to follow for that field. -** -** initial varint bytes to follow type -** -------------- --------------- --------------- -** 0 0 NULL -** 1 1 signed integer -** 2 2 signed integer -** 3 4 signed integer -** 4 8 signed integer -** 5 8 IEEE float -** 6..12 reserved for expansion -** N>=12 and even (N-12)/2 BLOB -** N>=13 and odd (N-13)/2 text -** -** For a particular database, text is always either UTF-8, UTF-16BE, or -** UTF-16LE. Which of these three formats to use is determined by one -** of the meta values in the file header. -** +** This function assumes that each key consists of one or more type/blob +** pairs, encoded using the sqlite3VdbeSerialXXX() functions above. One +** of the keys may have some trailing data appended to it. This is OK +** provided that the other key does not have more type/blob pairs than +** the key with the trailing data. */ -#if 0 int sqlite3VdbeKeyCompare( - void *userData, + void *userData, /* not used yet */ int nKey1, const unsigned char *aKey1, - int nKey2, const unsigned char *aKey2, + int nKey2, const unsigned char *aKey2 ){ - KeyClass *pKeyClass = (KeyClass*)userData; - i1 = i2 = 0; - for(i1=i2=0; pKeyClass!=0; pKeyClass=pKeyClass->pNext){ - if( varint32(aKey1, &i1, nKey1, &n1) ) goto bad_key; - if( varint32(aKey2, &i2, nKey2, &n2) ) goto bad_key; - if( n1==0 ){ - if( n2>0 ) return -1; - /* both values are NULL. consider them equal for sorting purposes. */ - }else if( n2==0 ){ - /* right value is NULL but the left value is not. right comes first */ - return +1; - }else if( n1<=5 ){ - if( n2>5 ) return -1; - /* both values are numbers. sort them numerically */ - /******* Finish this ********/ - }else if( n2<=5 ){ - /* right value is numeric and left is TEXT or BLOB. right comes first */ - return +1; - }else if( n1<12 || n2<12 ){ - /* bad coding for either the left or the right value */ - goto bad_key; - }else if( (n1&0x01)==0 ){ - if( n2&0x01)!=0 ) return -1; - /* both values are BLOB. use memcmp() */ - n1 = (n1-12)/2; - n2 = (n2-12)/2; - if( i1+n1>nKey1 || i2+n2>nKey2 ) goto bad_key; - c = memcmp(&aKey1[i1], &aKey2[i2], n1nKey1 || i2+n2>nKey2 ) goto bad_key; - c = pKeyClass->xCompare(pKeyClass->pUser, n1, &aKey1[i1], n2, &aKey2[i2]); - if( c!=0 ){ - return c | 1; - } - i1 += n1; - i2 += n2; - } + int offset1 = 0; + int offset2 = 0; + + while( offset1=1} {puts "*** Giving up..."; finalize_testing} + if {$nErr>=100} {puts "*** Giving up..."; finalize_testing} } else { puts " Ok" } diff --git a/test/types.test b/test/types.test new file mode 100644 index 0000000000..a0ca2bf325 --- /dev/null +++ b/test/types.test @@ -0,0 +1,200 @@ +# 2001 September 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# $Id: + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# +# Test cases are organized as follows: +# +# types-1.*: Insert some records with integers of various sizes, checking +# that the integers are stored correctly and can be retrieved. +# types-2.*: Insert and retrieve some records with reals. +# types-3.*: Insert and retrieve some records with NULLs. +# types-4.*: Insert and retrieve some records with strings of various sizes. +# types-5.*: Some tests inserting and retrieving records with several +# fields each. +# + +# Open the table with root-page $rootpage at the btree +# level. Return a list that is the length of each record +# in the table, in the tables default scanning order. +proc record_sizes {rootpage} { + set bt [btree_open test.db 10 0] + set c [btree_cursor $bt $rootpage 0] + btree_first $c + while 1 { + lappend res [btree_payload_size $c] + if {[btree_next $c]} break + } + btree_close_cursor $c + btree_close $bt + set res +} + + +# Create a table and insert some 1-byte integers. Make sure they +# can be read back OK. These should be 3 byte records. +do_test types-1.1 { + execsql { + CREATE TABLE t1(a integer); + INSERT INTO t1 VALUES(0); + INSERT INTO t1 VALUES(120); + INSERT INTO t1 VALUES(-120); + } +} {} +do_test types-1.2 { + execsql { + SELECT a FROM t1; + } +} {0 120 -120} + +# Try some 2-byte integers (4 byte records) +do_test types-1.3 { + execsql { + INSERT INTO t1 VALUES(30000); + INSERT INTO t1 VALUES(-30000); + } +} {} +do_test types-1.4 { + execsql { + SELECT a FROM t1; + } +} {0 120 -120 30000 -30000} + +# 4-byte integers (6 byte records) +do_test types-1.5 { + execsql { + INSERT INTO t1 VALUES(2100000000); + INSERT INTO t1 VALUES(-2100000000); + } +} {} +do_test types-1.6 { + execsql { + SELECT a FROM t1; + } +} {0 120 -120 30000 -30000 2100000000 -2100000000} + +# 8-byte integers (10 byte records) +do_test types-1.7 { + execsql { + INSERT INTO t1 VALUES(9000000*1000000*1000000); + INSERT INTO t1 VALUES(-9000000*1000000*1000000); + } +} {} +do_test types-1.8 { + execsql { + SELECT a FROM t1; + } +} [list 0 120 -120 30000 -30000 2100000000 -2100000000 \ + 9000000000000000000 -9000000000000000000] + +# Check that all the record sizes are as we expected. +do_test types-1.9 { + set root [db eval {select rootpage from sqlite_master where name = 't1'}] + record_sizes $root +} {3 3 3 4 4 6 6 10 10} + +# Insert some reals. These should be 10 byte records. +do_test types-2.1 { + execsql { + CREATE TABLE t2(a float); + INSERT INTO t2 VALUES(0.0 + 0.0); + INSERT INTO t2 VALUES(12345.678 + 0.0); + INSERT INTO t2 VALUES(-12345.678 + 0.0); + } +} {} +do_test types-2.2 { + execsql { + SELECT a FROM t2; + } +} {0 12345.678 -12345.678} + +# Check that all the record sizes are as we expected. +do_test types-2.3 { + set root [db eval {select rootpage from sqlite_master where name = 't2'}] + record_sizes $root +} {10 10 10} + +# Insert a NULL. This should be a two byte record. +do_test types-3.1 { + execsql { + CREATE TABLE t3(a nullvalue); + INSERT INTO t3 VALUES(NULL); + } +} {} +do_test types-3.2 { + execsql { + SELECT a ISNULL FROM t3; + } +} {1} + +# Check that all the record sizes are as we expected. +do_test types-3.3 { + set root [db eval {select rootpage from sqlite_master where name = 't3'}] + record_sizes $root +} {2} + +# Insert a couple of strings. +do_test types-4.1 { + set string10 abcdefghij + set string500 [string repeat $string10 50] + set string500000 [string repeat $string10 50000] + + execsql " + CREATE TABLE t4(a string); + INSERT INTO t4 VALUES('$string10'); + INSERT INTO t4 VALUES('$string500'); + INSERT INTO t4 VALUES('$string500000'); + " +} {} +do_test types-4.2 { + execsql { + SELECT a FROM t4; + } +} [list $string10 $string500 $string500000] + +# Check that all the record sizes are as we expected. +do_test types-4.3 { + set root [db eval {select rootpage from sqlite_master where name = 't4'}] + record_sizes $root +} {13 504 500005} + +do_test types-5.1 { + execsql { + DROP TABLE t1; + DROP TABLE t2; + DROP TABLE t3; + DROP TABLE t4; + CREATE TABLE t1(a, b, c); + } +} {} +do_test types-5.2 { + set string10 abcdefghij + set string500 [string repeat $string10 50] + set string500000 [string repeat $string10 50000] + + execsql "INSERT INTO t1 VALUES(NULL, '$string10', 4000);" + execsql "INSERT INTO t1 VALUES('$string500', 4000, NULL);" + execsql "INSERT INTO t1 VALUES(4000, NULL, '$string500000');" +} {} +do_test types-5.3 { + execsql { + SELECT * FROM t1; + } +} [list {} $string10 4000 $string500 4000 {} 4000 {} $string500000] + + +finish_test