-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
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
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
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
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
** 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"
**
** See also: MakeKey, SortMakeKey
*/
-case OP_MakeIdxKey:
-case OP_MakeKey: {
+case OP_MakeIdxKey2:
+case OP_MakeKey2: {
char *zNewKey;
int nByte;
int nField;
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
** 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
*/
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;
/* 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;
}
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 ){
Mem *pNos = &pTos[-1];
Cursor *pCx;
BtCursor *pCrsr;
- int R;
+ i64 R;
/* Pop the value R off the top of the stack
*/
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);
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;
}
/* 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;
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] ){
}
}
}
+ assert( p->aCsr[i].intKey==0 );
rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0);
assert( p->aCsr[i].deferredMoveto==0 );
}
/* 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.
*/
assert( i>=0 && i<p->nCursor );
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( sz<sizeof(i64) ){
+ len = ((sz>9)?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;
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;
}
# 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
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;
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;
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;
# 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 {