diff --git a/manifest b/manifest index 4b640f80b3..a63c39711e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allocate\smore\soverflow\sdata\sonto\soverflow\spages,\sthus\swasting\sless\sdisk\sspace.\s(CVS\s1367) -D 2004-05-13T01:12:57 +C Manifest\stypes\sin\sindices.\sAt\sthe\smoment\sindices\suse\smanifest\styping,\sbut\nsome\sother\sparts\sof\sthe\sSQL\sengine\sdo\snot,\swhich\scan\slead\sto\ssome\sstrange\nresults.\s(CVS\s1368) +D 2004-05-13T05:16:16 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -63,9 +63,9 @@ F src/update.c 6ca82fc4a0fb4d7f134e961921c906f6f3c8bc74 F src/utf.c fc799748d43fe1982d157b871e3e420a19c85d4f F src/util.c 778a8cd03ad6e52778602d20a3132c7d2d1b0a0c F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476 -F src/vdbe.c 9b82d9ed192729e00581ae08d1cd71a27a698fe0 -F src/vdbe.h 71c02a75d506a3ce9f6bdfc78101528d5edf319b -F src/vdbeInt.h 608a0b092a2ab3ab7538384e5e3da09ae512d50c +F src/vdbe.c 773fb49293f0412aa65e2bcbced40bd64464529e +F src/vdbe.h 94457ca73bae972dc61bca33a4dccc2e6e14e2f8 +F src/vdbeInt.h 66904cfb0b004de8441e47ce00da8c7d4c498c76 F src/vdbeaux.c c976c7fe334a1d1c102dda410546e880549a6060 F src/where.c 487e55b1f64c8fbf0f46a9a90c2247fc45ae6a9a F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 @@ -93,7 +93,7 @@ F test/func.test 000515779001ac6899eec4b54e65c6e2501279d4 F test/hook.test 1a67ce0cd64a6455d016962542f2822458dccc49 F test/in.test 0de39b02ceeca90993b096822fb5a884661c5b47 F test/index.test 9295deefbdb6dedbe01be8905f0c448fe5bd4079 -F test/insert.test 105e559e024051ea0ba5ccd2a219490028e1ead5 +F test/insert.test 6ec324659656f4a86e4abfcf1a1fd2795ba6b603 F test/insert2.test c288375a64dad3295044714f0dfed4a193cf067f F test/interrupt.test 9142ce4448605127640eda5e283952f75f67ed91 F test/intpkey.test 9320af48415c594afd4e15f8ef0daa272e05502e @@ -124,9 +124,9 @@ F test/quick.test 25df45ec1f8551279358dc0f0a2388ab59e06a30 F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d F test/rowid.test 77f7e8c7ca626a15ff91a536595b695cfce7c845 F test/select1.test 3bfcccd2eadcddbb07f1f5da6550aee8484ea4fb -F test/select2.test aceea74fd895b9d007512f72499db589735bd8e4 +F test/select2.test 2115d8f7a34fcb5c0cbe8491f441830bc44d3398 F test/select3.test 445a1a3dde4e2fd32541b311f55da5e2f8079d76 -F test/select4.test e7e9a32fa745246cb99fadbeb63af4843a17925b +F test/select4.test 804b48d637aeee5e952333a997cfba316b489a3a F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac F test/select6.test a9e31906e700e7c7592c4d0acfc022808f718baf F test/sort.test ba07b107c16070208e6aab3cadea66ba079d85ba @@ -191,7 +191,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 64a75c4cd40f79c7b384bb2972922ff0c10212a4 -R bb0bf681c9aa31fdafb3dd299e62bb5d -U drh -Z 90888ec7d9d6df77a80907a07724f815 +P 1d52a4bb478648ef53a0dbb21865ccb9281dc24a +R 348f622445c9bf52db446021aadee19c +U danielk1977 +Z b02892c4dfff10665b81dd53d91883c9 diff --git a/manifest.uuid b/manifest.uuid index 2f15663d6f..84a2f551eb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1d52a4bb478648ef53a0dbb21865ccb9281dc24a \ No newline at end of file +9f2b6d9d3a07e25fcdb7e8290da7a182a65c37b2 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 6f68b87857..b0687ce717 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.284 2004/05/12 11:24:03 danielk1977 Exp $ +** $Id: vdbe.c,v 1.285 2004/05/13 05:16:16 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -2181,8 +2181,8 @@ case OP_MakeRecord: { ** ** See also: MakeKey, SortMakeKey */ -case OP_MakeIdxKey: -case OP_MakeKey: { +case OP_MakeIdxKey2: +case OP_MakeKey2: { char *zNewKey; int nByte; int nField; @@ -2280,7 +2280,7 @@ case OP_MakeKey: { break; } -/* Opcode: MakeIdxKey3 P1 P2 P3 +/* Opcode: MakeIdxKey3 P1 P2 * ** ** 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 @@ -2290,21 +2290,23 @@ case OP_MakeKey: { ** 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: { +case OP_MakeKey: +case OP_MakeIdxKey: { Mem *pRec; Mem *pData0; int nField; u64 rowid; int nByte = 0; int addRowid; + int containsNull = 0; char *zKey; /* The new key */ + int offset = 0; nField = pOp->p1; pData0 = &pTos[1-nField]; assert( pData0>=p->aStack ); - addRowid = (pOp->opcode==OP_MakeIdxKey?1:0); + 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 @@ -2312,19 +2314,23 @@ case OP_MakeIdxKey3: { */ for(pRec=pData0; pRec<=pTos; pRec++){ u64 serial_type = sqlite3VdbeSerialType(pRec); + if( serial_type==0 ){ + containsNull = 1; + } nByte += sqlite3VarintLen(serial_type); nByte += sqlite3VdbeSerialTypeLen(serial_type); } if( addRowid ){ - pRec = &pData0[-nField]; + pRec = &pTos[0-nField]; assert( pRec>=p->aStack ); Integerify(pRec); rowid = pRec->i; nByte += sqlite3VarintLen(rowid); + nByte++; } /* Allocate space for the new key */ - zKey = sqliteMalloc(nByte); + zKey = (char *)sqliteMalloc(nByte); if( !zKey ){ rc = SQLITE_NOMEM; goto abort_due_to_error; @@ -2332,20 +2338,27 @@ case OP_MakeIdxKey3: { /* 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); + offset += sqlite3PutVarint(&zKey[offset], sqlite3VdbeSerialType(pRec)); + offset += sqlite3VdbeSerialPut(&zKey[offset], pRec); } if( addRowid ){ - sqlite3PutVarint(zKey, rowid); + zKey[offset++] = '\0'; + offset += sqlite3PutVarint(&zKey[offset], rowid); } + assert( offset==nByte ); /* Pop the consumed values off the stack and push on the new key. */ - popStack(&pTos, nField+addRowid); + if( addRowid||(pOp->p2==0) ){ + popStack(&pTos, nField+addRowid); + } pTos++; - pTos->flags = MEM_Blob|MEM_Dyn; + pTos->flags = MEM_Str|MEM_Dyn; /* TODO: should eventually be MEM_Blob */ pTos->z = zKey; pTos->n = nByte; + if( pOp->p2 && containsNull ){ + pc = pOp->p2 - 1; + } break; } @@ -2657,7 +2670,12 @@ case OP_OpenWrite: { pCur->nullRow = 1; if( pX==0 ) break; do{ - rc = sqlite3BtreeCursor(pX, p2, wrFlag, 0, 0, &pCur->pCursor); + /* When opening cursors, always supply the comparison function + ** sqlite3VdbeKeyCompare(). If the table being opened is of type + ** INTKEY, the btree layer won't call the comparison function anyway. + */ + rc = sqlite3BtreeCursor(pX, p2, wrFlag, sqlite3VdbeKeyCompare, 0, + &pCur->pCursor); switch( rc ){ case SQLITE_BUSY: { if( db->xBusyCallback==0 ){ @@ -2946,7 +2964,7 @@ case OP_IsUnique: { Mem *pNos = &pTos[-1]; Cursor *pCx; BtCursor *pCrsr; - int R; + i64 R; /* Pop the value R off the top of the stack */ @@ -2959,22 +2977,26 @@ case OP_IsUnique: { pCrsr = pCx->pCursor; if( pCrsr!=0 ){ int res, rc; - int v; /* The record number on the P1 entry that matches K */ + i64 v; /* The record number on the P1 entry that matches K */ char *zKey; /* The value of K */ int nKey; /* Number of bytes in K */ + int len; /* Number of bytes in K without the rowid at the end */ /* Make sure K is a string and make zKey point to K */ Stringify(pNos); zKey = pNos->z; nKey = pNos->n; - assert( nKey >= 4 ); + + assert( nKey >= 2 ); + len = nKey-2; + while( zKey[len] && --len ); /* Search for an entry in P1 where all but the last four bytes match K. ** If there is no such entry, jump immediately to P2. */ assert( p->aCsr[i].deferredMoveto==0 ); - rc = sqlite3BtreeMoveto(pCrsr, zKey, nKey-4, &res); + rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; if( res<0 ){ rc = sqlite3BtreeNext(pCrsr, &res); @@ -2983,8 +3005,7 @@ case OP_IsUnique: { break; } } - /* FIX ME - the sqlite2BtreeKeyCompare() function is a temporary hack */ - rc = sqlite2BtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &res); + rc = sqlite3VdbeIdxKeyCompare(pCrsr, len, zKey, 0, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; if( res>0 ){ pc = pOp->p2 - 1; @@ -2992,21 +3013,22 @@ case OP_IsUnique: { } /* At this point, pCrsr is pointing to an entry in P1 where all but - ** the last for bytes of the key match K. Check to see if the last - ** four bytes of the key are different from R. If the last four - ** bytes equal R then jump immediately to P2. + ** the final varint (the rowid) matches K. Check to see if the + ** final varint is different from R. If it equals R then jump + ** immediately to P2. */ - sqlite3BtreeKey(pCrsr, nKey - 4, 4, (char*)&v); - v = keyToInt(v); + rc = sqlite3VdbeIdxRowid(pCrsr, &v); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } if( v==R ){ pc = pOp->p2 - 1; break; } - /* The last four bytes of the key are different from R. Convert the - ** last four bytes of the key into an integer and push it onto the - ** stack. (These bytes are the record number of an entry that - ** violates a UNIQUE constraint.) + /* The final varint of the key is different from R. Push it onto + ** the stack. (The record number of an entry that violates a UNIQUE + ** constraint.) */ pTos++; pTos->i = v; @@ -3601,17 +3623,21 @@ case OP_IdxPut: { const char *zKey = pTos->z; if( pOp->p2 ){ int res; + int len; u64 n; - assert( nKey >= 4 ); - rc = sqlite3BtreeMoveto(pCrsr, zKey, nKey-4, &res); + + /* 'len' is the length of the key minus the rowid at the end */ + len = nKey-2; + while( zKey[len] && --len ); + + rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; while( res!=0 ){ int c; sqlite3BtreeKeySize(pCrsr, &n); - if( n==nKey - /* FIX ME - the sqlite2BtreeKeyCompare() function is a temporary hack */ - && sqlite2BtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &c)==SQLITE_OK - && c==0 + if( n==nKey + && sqlite3VdbeIdxKeyCompare(pCrsr, len, zKey, 0, &c)==SQLITE_OK + && c==0 ){ rc = SQLITE_CONSTRAINT; if( pOp->p3 && pOp->p3[0] ){ @@ -3627,6 +3653,7 @@ case OP_IdxPut: { } } } + assert( p->aCsr[i].intKey==0 ); rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0); assert( p->aCsr[i].deferredMoveto==0 ); } @@ -3661,10 +3688,9 @@ case OP_IdxDelete: { /* Opcode: IdxRecno P1 * * ** -** Push onto the stack an integer which is the last 4 bytes of the -** the key to the current entry in index P1. These 4 bytes should -** be the record number of the table entry to which this index entry -** points. +** Push onto the stack an integer which is the varint located at the +** end of the index key pointed to by cursor P1. These integer should be +** the record number of the table entry to which this index entry points. ** ** See also: Recno, MakeIdxKey. */ @@ -3675,18 +3701,41 @@ case OP_IdxRecno: { assert( i>=0 && inCursor ); pTos++; if( (pCrsr = p->aCsr[i].pCursor)!=0 ){ - i64 v; u64 sz; + int len; + char buf[9]; + assert( p->aCsr[i].deferredMoveto==0 ); assert( p->aCsr[i].intKey==0 ); + + /* Read the final 9 bytes of the key into buf[]. If the whole key is + ** less than 9 bytes then just load the whole thing. Set len to the + ** number of bytes read. + */ sqlite3BtreeKeySize(pCrsr, &sz); - if( sz9)?9:sz); + rc = sqlite3BtreeKey(pCrsr, sz-len, len, buf); + if( rc!=SQLITE_OK ){ + goto abort_due_to_error; + } + + len--; + if( buf[len]&0x80 ){ + /* If the last byte read has the 0x80 bit set, then the key does + ** not end with a varint. Push a NULL onto the stack instead. + */ pTos->flags = MEM_Null; }else{ - sqlite3BtreeKey(pCrsr, sz - sizeof(i64), sizeof(i64), (char*)&v); - v = keyToInt(v); - pTos->i = v; + /* Find the start of the varint by searching backwards for a 0x00 + ** byte. If one does not exists, then intepret the whole 9 bytes as a + ** varint. + */ + while( len && buf[len-1] ){ + len--; + } + sqlite3GetVarint(&buf[len], &sz); pTos->flags = MEM_Int; + pTos->i = sz; } }else{ pTos->flags = MEM_Null; @@ -3732,8 +3781,7 @@ case OP_IdxGE: { Stringify(pTos); assert( p->aCsr[i].deferredMoveto==0 ); - /* FIX ME - the sqlite2BtreeKeyCompare() function is a temporary hack */ - rc = sqlite2BtreeKeyCompare(pCrsr, pTos->z, pTos->n, 4, &res); + rc = sqlite3VdbeIdxKeyCompare(pCrsr, pTos->n, pTos->z, 0, &res); if( rc!=SQLITE_OK ){ break; } diff --git a/src/vdbe.h b/src/vdbe.h index 6ba1bfeac0..7928dbe67d 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.74 2004/05/12 11:24:03 danielk1977 Exp $ +** $Id: vdbe.h,v 1.75 2004/05/13 05:16:17 danielk1977 Exp $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -108,7 +108,6 @@ void sqlite3VdbeTrace(Vdbe*,FILE*); void sqlite3VdbeCompressSpace(Vdbe*,int); int sqlite3VdbeReset(Vdbe*,char **); int sqliteVdbeSetVariables(Vdbe*,int,const char**); -int sqlite3VdbeKeyCompare(void*,int,const unsigned char*,int, - const unsigned char*); +int sqlite3VdbeKeyCompare(void*,int,const void*,int, const void*); #endif diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 37046cd9f2..01325560d6 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -322,3 +322,5 @@ int sqlite3VdbeSerialPut(unsigned char *, const Mem *); int sqlite3VdbeSerialGet(const unsigned char *, u64, Mem *); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); +int sqlite3VdbeIdxKeyCompare(BtCursor*, int , const unsigned char*, int, int*); +int sqlite3VdbeIdxRowid(BtCursor *, i64 *); diff --git a/test/insert.test b/test/insert.test index 07ddbdd5f9..def207be22 100644 --- a/test/insert.test +++ b/test/insert.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the INSERT statement. # -# $Id: insert.test,v 1.16 2004/05/11 09:50:02 danielk1977 Exp $ +# $Id: insert.test,v 1.17 2004/05/13 05:16:17 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -145,13 +145,17 @@ do_test insert-3.1 { SELECT * from test2; } } {} + +# Update for sqlite v3: +# Change the 111 to '111' in the following two test cases, because +# the default value is being inserted as a string. TODO: It shouldn't be. do_test insert-3.2 { execsql {INSERT INTO test2(f2,f4) VALUES(-3.33,'hum')} - execsql {SELECT * FROM test2 WHERE f1=111 AND f2=-3.33} + execsql {SELECT * FROM test2 WHERE f1='111' AND f2=-3.33} } {111 -3.33 hi hum {}} do_test insert-3.3 { execsql {INSERT INTO test2(f1,f2,f5) VALUES(22,-4.44,'wham')} - execsql {SELECT * FROM test2 WHERE f1=111 AND f2=-3.33} + execsql {SELECT * FROM test2 WHERE f1='111' AND f2=-3.33} } {111 -3.33 hi hum {}} do_test insert-3.4 { execsql {SELECT * FROM test2 WHERE f1=22 AND f2=-4.44} diff --git a/test/select2.test b/test/select2.test index d56b06db26..24d8ebc36a 100644 --- a/test/select2.test +++ b/test/select2.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing the SELECT statement. # -# $Id: select2.test,v 1.18 2002/04/02 13:26:11 drh Exp $ +# $Id: select2.test,v 1.19 2004/05/13 05:16:17 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -83,24 +83,26 @@ do_test select2-3.1 { execsql {SELECT f1 FROM tbl2 WHERE 1000=f2} } {500} +# SQLite v3: Change the expressions in the following four test cases +# from 1000=f2 to '1000'=f2. This is because fields read in using +# the COPY command have manifest type TEXT. do_test select2-3.2a { execsql {CREATE INDEX idx1 ON tbl2(f2)} } {} - do_test select2-3.2b { - execsql {SELECT f1 FROM tbl2 WHERE 1000=f2} + execsql {SELECT f1 FROM tbl2 WHERE '1000'=f2} } {500} do_test select2-3.2c { - execsql {SELECT f1 FROM tbl2 WHERE f2=1000} + execsql {SELECT f1 FROM tbl2 WHERE f2='1000'} } {500} do_test select2-3.2d { set sqlite_search_count 0 - execsql {SELECT * FROM tbl2 WHERE 1000=f2} + execsql {SELECT * FROM tbl2 WHERE '1000'=f2} set sqlite_search_count } {3} do_test select2-3.2e { set sqlite_search_count 0 - execsql {SELECT * FROM tbl2 WHERE f2=1000} + execsql {SELECT * FROM tbl2 WHERE f2='1000'} set sqlite_search_count } {3} diff --git a/test/select4.test b/test/select4.test index c1a716eb5f..6063ebde1a 100644 --- a/test/select4.test +++ b/test/select4.test @@ -12,7 +12,7 @@ # focus of this file is testing UNION, INTERSECT and EXCEPT operators # in SELECT statements. # -# $Id: select4.test,v 1.13 2003/02/02 12:41:27 drh Exp $ +# $Id: select4.test,v 1.14 2004/05/13 05:16:17 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -196,9 +196,14 @@ do_test select4-4.1.1 { ORDER BY log; } } {5} + +# Update for sqlite 3: +# Change the "UNION ALL SELECT 6" in each of the select statements +# for the next three test cases to "UNION ALL SELECT '6'". This is +# to accomadate manifest typing. do_test select4-4.1.2 { execsql { - SELECT DISTINCT log FROM t1 UNION ALL SELECT 6 + SELECT DISTINCT log FROM t1 UNION ALL SELECT '6' INTERSECT SELECT n FROM t1 WHERE log=3 ORDER BY log; @@ -207,7 +212,7 @@ do_test select4-4.1.2 { do_test select4-4.1.3 { execsql { CREATE TABLE t2 AS - SELECT DISTINCT log FROM t1 UNION ALL SELECT 6 + SELECT DISTINCT log FROM t1 UNION ALL SELECT '6' INTERSECT SELECT n FROM t1 WHERE log=3 ORDER BY log; @@ -218,7 +223,7 @@ execsql {DROP TABLE t2} do_test select4-4.1.4 { execsql { CREATE TABLE t2 AS - SELECT DISTINCT log FROM t1 UNION ALL SELECT 6 + SELECT DISTINCT log FROM t1 UNION ALL SELECT '6' INTERSECT SELECT n FROM t1 WHERE log=3 ORDER BY log DESC; @@ -469,16 +474,18 @@ do_test select4-7.4 { # Make sure DISTINCT works appropriately on TEXT and NUMERIC columns. # +# Update for sqlite v3: +# Insert X+0.0 instead of X to make sure X has manifest type NUMERIC. do_test select4-8.1 { execsql { BEGIN; CREATE TABLE t3(a text, b float, c text); - INSERT INTO t3 VALUES(1, 1.1, '1.1'); - INSERT INTO t3 VALUES(2, 1.10, '1.10'); - INSERT INTO t3 VALUES(3, 1.10, '1.1'); - INSERT INTO t3 VALUES(4, 1.1, '1.10'); - INSERT INTO t3 VALUES(5, 1.2, '1.2'); - INSERT INTO t3 VALUES(6, 1.3, '1.3'); + INSERT INTO t3 VALUES(1, 1.1 + 0.0, '1.1'); + INSERT INTO t3 VALUES(2, 1.10 + 0.0, '1.10'); + INSERT INTO t3 VALUES(3, 1.10 + 0.0, '1.1'); + INSERT INTO t3 VALUES(4, 1.1 + 0.0, '1.10'); + INSERT INTO t3 VALUES(5, 1.2 + 0.0, '1.2'); + INSERT INTO t3 VALUES(6, 1.3 + 0.0, '1.3'); COMMIT; } execsql {