-C Do\snot\sescape\sthe\sbackslash\scharacter\sin\sshell\soutput.\s(CVS\s353)
-D 2002-01-24T00:00:21
+C Bug\sfix:\sThe\sIN\soperator\swas\snot\sworking\sif\seither\sside\sderived\sfrom\nan\sINTEGER\sPRIMARY\sKEY.\s(CVS\s354)
+D 2002-01-28T15:53:04
F Makefile.in 9fa4277413bf1d9cf91365f07d4108d7d87ed2af
F Makefile.template 3e26a3b9e7aee1b811deaf673e8d8973bdb3f22d
F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
-F VERSION 2af606990ed9af7308a6e04cd7c9efd550f4e7be
+F VERSION 79f8cff9811acbf454323afd9f2fa6cd2a8b7674
F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d
F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588
F config.log 6a73d03433669b10a3f0c221198c3f26b9413914
F src/TODO af7f3cab0228e34149cf98e073aa83d45878e7e6
F src/btree.c c796e387da340cb628dc1e41f684fc20253f561e
F src/btree.h 9ead7f54c270d8a554e59352ca7318fdaf411390
-F src/build.c bf8456b56011bb3761f11ff4a14121cfbbbd78da
+F src/build.c 3f40a6e6cea4180fb742a3d0ce71f06df8121cab
F src/delete.c cc200609f927ee8fefdda5d11d3f3b2288493c0f
F src/expr.c 4cae8bf44d5732182e5e8c25b4552c05ea55593e
F src/hash.c 8f7c740ef2eaaa8decfa8751f2be30680b123e46
F src/hash.h a5f5b3ce2d086a172c5879b0b06a27a82eac9fac
-F src/insert.c 813c37719866c583e6ca7660f94f10230f4e385d
+F src/insert.c e3a3b5a1d46a02778feb3e2ccd9a6989201c03b5
F src/main.c 0205771a6c31a9858ff131fc1e797b589afb76bf
F src/md5.c 52f677bfc590e09f71d07d7e327bd59da738d07c
F src/os.c c615faa4d23e742e0650e0751a6ad2a18438ad53
F src/parse.y f3fc4fb5766393003577bd175eb611495f6efd9f
F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
F src/random.c f6b36bec5ebd3edb3440224bf5bf811fe4ac9a1b
-F src/select.c de0d1d12e258d339a7936556512680366177f277
+F src/select.c fc11d5a8c2bae1b62d8028ffb111c773ad6bf161
F src/shell.c c102dfe388c7618a668c944ff157c49cb48f28e3
F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
F src/sqlite.h.in f57074c84a2c112a5093ba7a9d9636aa9cacc87c
F src/test2.c e9f99aa5ee73872819259d6612c11e55e1644321
F src/test3.c d6775f95fd91f5b3cf0e2382a28e5aaeb68f745b
F src/tokenize.c 830e9ef684334070a26583d94770bb869e2727bf
-F src/update.c f30a47928fb7e894221eab2a81c8fa2653f96fb0
+F src/update.c 6f87a9aa0b3ec0dfec0b0758104461445e701fdb
F src/util.c 8f8973dd55a6ec63be9632fc5de86965c99d6327
-F src/vdbe.c 158bab65e4eafceb75a83f616caafa2c58f00242
-F src/vdbe.h e5cc6fb13d1905a4339db4d6dba4ab393c0765fa
-F src/where.c a9b286ac7323e7ebed5d3d217b3963acf1e6a355
+F src/vdbe.c 71c0b7d368dd4c58867d7e577df0ee5404e25722
+F src/vdbe.h 22d4df31cc16ca50b66b8125caec3495e5b407b2
+F src/where.c 2dda39367f193194e4c7d2e0dcab31527d9d8aba
F test/all.test 2a51e5395ac7c2c539689b123b9782a05e3837fe
F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
F test/btree.test 6ab4dc5f595905a276ef588fad3c9236dc07a47b
F test/delete.test c904a62129fe102b314a96111a8417f10249e4d8
F test/expr.test c8a495050dcec3f9e68538c3ef466726933302c1
F test/func.test 51dbe3f8a4c28972751697423e6acc5d6b551df1
-F test/in.test 9323681388be301dc73f370b4cd62c5a33f79d1e
+F test/in.test c09312672e3f0709fa02c8e2e9cd8fb4bd6269aa
F test/index.test c8a471243bbf878974b99baf5badd59407237cf3
F test/insert.test a5c122aa726f1cef6f07d6767e8fd6f220994c11
F test/insert2.test d6901ca931e308fea7fca8c95ebe7dc957cc9fc2
F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
F www/arch.tcl 72a0c80e9054cc7025a50928d28d9c75c02c2b8b
F www/c_interface.tcl 82a026b1681757f13b3f62e035f3a31407c1d353
-F www/changes.tcl f3f730787338087282e50bd27d152ed68686df15
+F www/changes.tcl 6b802e152436c7596308b6a4901e91415be0d9d4
F www/crosscompile.tcl 3622ebbe518927a3854a12de51344673eb2dd060
F www/download.tcl 1ea61f9d89a2a5a9b2cee36b0d5cf97321bdefe0
F www/dynload.tcl 02eb8273aa78cfa9070dd4501dca937fb22b466c
F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
F www/tclsqlite.tcl 829b393d1ab187fd7a5e978631b3429318885c49
F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 16712dae4feedd001d8153141a55e298b3a80a94
-R 0530842c82f7bef6b5f9c0ae1cc69c65
+P 5f8c097ebef28315ac2335a768d101e995ccbba2
+R 8bfbd1ab9c2165331e9740c7a67704b7
U drh
-Z 61c11f99131a5810bde1ae96d98c46d4
+Z 7c022c8c65d60ef92494dfd3fd54cead
-5f8c097ebef28315ac2335a768d101e995ccbba2
\ No newline at end of file
+dbcfe198fbaa155874ef82a96b6a4b993ccf3931
\ No newline at end of file
** ROLLBACK
** PRAGMA
**
-** $Id: build.c,v 1.65 2002/01/22 03:13:42 drh Exp $
+** $Id: build.c,v 1.66 2002/01/28 15:53:05 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
addr = sqliteVdbeAddOp(v, OP_String, 0, 0);
sqliteVdbeChangeP3(v, addr, pParse->sFirstToken.z, n);
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
- sqliteVdbeAddOp(v, OP_Put, 0, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
changeCookie(db);
sqliteVdbeAddOp(v, OP_SetCookie, db->next_cookie, 0);
sqliteVdbeAddOp(v, OP_Close, 0, 0);
sqliteVdbeChangeP3(v, addr, pStart->z, n);
}
sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
- sqliteVdbeAddOp(v, OP_Put, 0, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
}
if( pTable ){
sqliteVdbeAddOp(v, isTemp ? OP_OpenAux : OP_Open, 2, pTab->tnum);
}
}
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
- sqliteVdbeAddOp(v, OP_Put, 0, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
if( pIdx->pNext ){
sqliteVdbeAddOp(v, OP_Dup, 0, 0);
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.32 2002/01/06 17:07:40 drh Exp $
+** $Id: insert.c,v 1.33 2002/01/28 15:53:05 drh Exp $
*/
#include "sqliteInt.h"
/* Create the new record and put it into the database.
*/
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
- sqliteVdbeAddOp(v, OP_Put, base, keyColumn>=0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, base, keyColumn>=0);
/* Create appropriate entries for the new data row in all indices
** of the table.
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
-** $Id: select.c,v 1.55 2002/01/22 14:11:29 drh Exp $
+** $Id: select.c,v 1.56 2002/01/28 15:53:05 drh Exp $
*/
#include "sqliteInt.h"
sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
sqliteVdbeResolveLabel(v, lbl);
sqliteVdbeAddOp(v, OP_String, 0, 0);
- sqliteVdbeAddOp(v, OP_Put, distinct, 0);
+ sqliteVdbeAddOp(v, OP_PutStrKey, distinct, 0);
}
/* If there is an ORDER BY clause, then store the results
if( eDest==SRT_Union ){
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
sqliteVdbeAddOp(v, OP_String, iParm, 0);
- sqliteVdbeAddOp(v, OP_Put, iParm, 0);
+ sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0);
}else
/* Store the result as data using a unique key.
sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0);
sqliteVdbeAddOp(v, OP_Pull, 1, 0);
- sqliteVdbeAddOp(v, OP_Put, iParm, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, iParm, 0);
}else
/* Construct a record from the query result, but instead of
if( eDest==SRT_Set ){
assert( nColumn==1 );
sqliteVdbeAddOp(v, OP_String, 0, 0);
- sqliteVdbeAddOp(v, OP_Put, iParm, 0);
+ sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0);
}else
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
-** $Id: update.c,v 1.27 2002/01/22 03:13:42 drh Exp $
+** $Id: update.c,v 1.28 2002/01/28 15:53:05 drh Exp $
*/
#include "sqliteInt.h"
/* Write the new data back into the database.
*/
sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
- sqliteVdbeAddOp(v, OP_Put, base, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, base, 0);
/* Increment the count of rows affected by the update
*/
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
-** $Id: vdbe.c,v 1.107 2002/01/16 21:00:27 drh Exp $
+** $Id: vdbe.c,v 1.108 2002/01/28 15:53:05 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
"Transaction", "Commit", "Rollback", "ReadCookie",
"SetCookie", "VerifyCookie", "Open", "OpenTemp",
"OpenWrite", "OpenAux", "OpenWrAux", "Close",
- "MoveTo", "NewRecno", "Put", "Distinct",
- "Found", "NotFound", "Delete", "Column",
- "KeyAsData", "Recno", "FullKey", "Rewind",
- "Next", "Destroy", "Clear", "CreateIndex",
- "CreateTable", "Reorganize", "IdxPut", "IdxDelete",
- "IdxRecno", "IdxGT", "IdxGE", "MemLoad",
- "MemStore", "ListWrite", "ListRewind", "ListRead",
- "ListReset", "SortPut", "SortMakeRec", "SortMakeKey",
- "Sort", "SortNext", "SortCallback", "SortReset",
- "FileOpen", "FileRead", "FileColumn", "AggReset",
- "AggFocus", "AggIncr", "AggNext", "AggSet",
- "AggGet", "SetInsert", "SetFound", "SetNotFound",
- "MakeRecord", "MakeKey", "MakeIdxKey", "IncrKey",
- "Goto", "If", "Halt", "ColumnCount",
- "ColumnName", "Callback", "NullCallback", "Integer",
- "String", "Pop", "Dup", "Pull",
- "MustBeInt", "Add", "AddImm", "Subtract",
- "Multiply", "Divide", "Remainder", "BitAnd",
- "BitOr", "BitNot", "ShiftLeft", "ShiftRight",
- "AbsValue", "Precision", "Min", "Max",
- "Like", "Glob", "Eq", "Ne",
- "Lt", "Le", "Gt", "Ge",
- "IsNull", "NotNull", "Negative", "And",
- "Or", "Not", "Concat", "Noop",
- "Strlen", "Substr", "Limit",
+ "MoveTo", "NewRecno", "PutIntKey", "PutStrKey",
+ "Distinct", "Found", "NotFound", "NotExists",
+ "Delete", "Column", "KeyAsData", "Recno",
+ "FullKey", "Rewind", "Next", "Destroy",
+ "Clear", "CreateIndex", "CreateTable", "Reorganize",
+ "IdxPut", "IdxDelete", "IdxRecno", "IdxGT",
+ "IdxGE", "MemLoad", "MemStore", "ListWrite",
+ "ListRewind", "ListRead", "ListReset", "SortPut",
+ "SortMakeRec", "SortMakeKey", "Sort", "SortNext",
+ "SortCallback", "SortReset", "FileOpen", "FileRead",
+ "FileColumn", "AggReset", "AggFocus", "AggIncr",
+ "AggNext", "AggSet", "AggGet", "SetInsert",
+ "SetFound", "SetNotFound", "MakeRecord", "MakeKey",
+ "MakeIdxKey", "IncrKey", "Goto", "If",
+ "Halt", "ColumnCount", "ColumnName", "Callback",
+ "NullCallback", "Integer", "String", "Pop",
+ "Dup", "Pull", "MustBeInt", "Add",
+ "AddImm", "Subtract", "Multiply", "Divide",
+ "Remainder", "BitAnd", "BitOr", "BitNot",
+ "ShiftLeft", "ShiftRight", "AbsValue", "Precision",
+ "Min", "Max", "Like", "Glob",
+ "Eq", "Ne", "Lt", "Le",
+ "Gt", "Ge", "IsNull", "NotNull",
+ "Negative", "And", "Or", "Not",
+ "Concat", "Noop", "Strlen", "Substr",
+ "Limit",
};
/*
/* Opcode: Distinct P1 P2 *
**
-** Use the top of the stack as a key. If a record with that key does
+** Use the top of the stack as a string key. If a record with that key does
** not exist in the table of cursor P1, then jump to P2. If the record
** does already exist, then fall thru. The cursor is left pointing
** at the record if it exists. The key is not popped from the stack.
*/
/* Opcode: Found P1 P2 *
**
-** Use the top of the stack as a key. If a record with that key
+** Use the top of the stack as a string key. If a record with that key
** does exist in table of P1, then jump to P2. If the record
** does not exist, then fall thru. The cursor is left pointing
** to the record if it exists. The key is popped from the stack.
*/
/* Opcode: NotFound P1 P2 *
**
-** Use the top of the stack as a key. If a record with that key
+** Use the top of the stack as a string key. If a record with that key
** does not exist in table of P1, then jump to P2. If the record
** does exist, then fall thru. The cursor is left pointing to the
** record if it exists. The key is popped from the stack.
** The difference between this operation and Distinct is that
** Distinct does not pop the key from the stack.
**
-** See also: Distinct, Found, MoveTo
+** See also: Distinct, Found, MoveTo, NotExists
*/
case OP_Distinct:
case OP_NotFound:
VERIFY( if( tos<0 ) goto not_enough_stack; )
if( VERIFY( i>=0 && i<p->nCursor && ) (pC = &p->aCsr[i])->pCursor!=0 ){
int res, rx;
- if( aStack[tos].flags & STK_Int ){
- int iKey = intToKey(aStack[tos].i);
- rx = sqliteBtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
- }else{
- if( Stringify(p, tos) ) goto no_mem;
- rx = sqliteBtreeMoveto(pC->pCursor, zStack[tos], aStack[tos].n, &res);
- }
+ if( Stringify(p, tos) ) goto no_mem;
+ rx = sqliteBtreeMoveto(pC->pCursor, zStack[tos], aStack[tos].n, &res);
alreadyExists = rx==SQLITE_OK && res==0;
}
if( pOp->opcode==OP_Found ){
break;
}
+/* Opcode: NotExists P1 P2 *
+**
+** Use the top of the stack as a integer key. If a record with that key
+** does not exist in table of P1, then jump to P2. If the record
+** does exist, then fall thru. The cursor is left pointing to the
+** record if it exists. The integer key is popped from the stack.
+**
+** The difference between this operation and NotFound is that this
+** operation assumes the key is an integer and NotFound assumes it
+** is a string.
+**
+** See also: Distinct, Found, MoveTo, NotExists
+*/
+case OP_NotExists: {
+ int i = pOp->p1;
+ int tos = p->tos;
+ int alreadyExists = 0;
+ Cursor *pC;
+ VERIFY( if( tos<0 ) goto not_enough_stack; )
+ if( VERIFY( i>=0 && i<p->nCursor && ) (pC = &p->aCsr[i])->pCursor!=0 ){
+ int res, rx, iKey;
+ assert( aStack[tos].flags & STK_Int );
+ iKey = intToKey(aStack[tos].i);
+ rx = sqliteBtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
+ if( rx!=SQLITE_OK || res!=0 ){
+ pc = pOp->p2 - 1;
+ }
+ }
+ POPSTACK;
+ break;
+}
+
/* Opcode: NewRecno P1 * *
**
** Get a new integer record number used as the key to a table.
break;
}
-/* Opcode: Put P1 P2 *
+/* Opcode: PutIK P1 P2 *
+**
+** Write an entry into the database file P1. A new entry is
+** created if it doesn't already exist or the data for an existing
+** entry is overwritten. The data is the value on the top of the
+** stack. The key is the next value down on the stack. The key must
+** be an integer. The stack is popped twice by this instruction.
+**
+** If P2==1 then overwriting is prohibited. If a prior entry with
+** the same key exists, an SQLITE_CONSTRAINT exception is raised.
+*/
+/* Opcode: PutSK P1 P2 *
**
** Write an entry into the database file P1. A new entry is
** created if it doesn't already exist or the data for an existing
** entry is overwritten. The data is the value on the top of the
-** stack. The key is the next value down on the stack. The stack
-** is popped twice by this instruction.
+** stack. The key is the next value down on the stack. The key must
+** be a string. The stack is popped twice by this instruction.
**
** If P2==1 then overwriting is prohibited. If a prior entry with
** the same key exists, an SQLITE_CONSTRAINT exception is raised.
*/
-case OP_Put: {
+case OP_PutIntKey:
+case OP_PutStrKey: {
int tos = p->tos;
int nos = p->tos-1;
int i = pOp->p1;
if( VERIFY( i>=0 && i<p->nCursor && ) p->aCsr[i].pCursor!=0 ){
char *zKey;
int nKey, iKey;
- if( (aStack[nos].flags & STK_Int)==0 ){
+ if( pOp->opcode==OP_PutStrKey ){
if( Stringify(p, nos) ) goto no_mem;
nKey = aStack[nos].n;
zKey = zStack[nos];
}else{
+ assert( aStack[nos].flags & STK_Int );
nKey = sizeof(int);
iKey = intToKey(aStack[nos].i);
zKey = (char*)&iKey;
** 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.37 2001/12/22 14:49:26 drh Exp $
+** $Id: vdbe.h,v 1.38 2002/01/28 15:53:05 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#define OP_Close 12
#define OP_MoveTo 13
#define OP_NewRecno 14
-#define OP_Put 15
-#define OP_Distinct 16
-#define OP_Found 17
-#define OP_NotFound 18
-#define OP_Delete 19
-#define OP_Column 20
-#define OP_KeyAsData 21
-#define OP_Recno 22
-#define OP_FullKey 23
-#define OP_Rewind 24
-#define OP_Next 25
-
-#define OP_Destroy 26
-#define OP_Clear 27
-#define OP_CreateIndex 28
-#define OP_CreateTable 29
-#define OP_Reorganize 30
-
-#define OP_IdxPut 31
-#define OP_IdxDelete 32
-#define OP_IdxRecno 33
-#define OP_IdxGT 34
-#define OP_IdxGE 35
-
-#define OP_MemLoad 36
-#define OP_MemStore 37
-
-#define OP_ListWrite 38
-#define OP_ListRewind 39
-#define OP_ListRead 40
-#define OP_ListReset 41
-
-#define OP_SortPut 42
-#define OP_SortMakeRec 43
-#define OP_SortMakeKey 44
-#define OP_Sort 45
-#define OP_SortNext 46
-#define OP_SortCallback 47
-#define OP_SortReset 48
-
-#define OP_FileOpen 49
-#define OP_FileRead 50
-#define OP_FileColumn 51
-
-#define OP_AggReset 52
-#define OP_AggFocus 53
-#define OP_AggIncr 54
-#define OP_AggNext 55
-#define OP_AggSet 56
-#define OP_AggGet 57
-
-#define OP_SetInsert 58
-#define OP_SetFound 59
-#define OP_SetNotFound 60
-
-#define OP_MakeRecord 61
-#define OP_MakeKey 62
-#define OP_MakeIdxKey 63
-#define OP_IncrKey 64
-
-#define OP_Goto 65
-#define OP_If 66
-#define OP_Halt 67
-
-#define OP_ColumnCount 68
-#define OP_ColumnName 69
-#define OP_Callback 70
-#define OP_NullCallback 71
-
-#define OP_Integer 72
-#define OP_String 73
-#define OP_Pop 74
-#define OP_Dup 75
-#define OP_Pull 76
-#define OP_MustBeInt 77
-
-#define OP_Add 78
-#define OP_AddImm 79
-#define OP_Subtract 80
-#define OP_Multiply 81
-#define OP_Divide 82
-#define OP_Remainder 83
-#define OP_BitAnd 84
-#define OP_BitOr 85
-#define OP_BitNot 86
-#define OP_ShiftLeft 87
-#define OP_ShiftRight 88
-#define OP_AbsValue 89
-#define OP_Precision 90
-#define OP_Min 91
-#define OP_Max 92
-#define OP_Like 93
-#define OP_Glob 94
-#define OP_Eq 95
-#define OP_Ne 96
-#define OP_Lt 97
-#define OP_Le 98
-#define OP_Gt 99
-#define OP_Ge 100
-#define OP_IsNull 101
-#define OP_NotNull 102
-#define OP_Negative 103
-#define OP_And 104
-#define OP_Or 105
-#define OP_Not 106
-#define OP_Concat 107
-#define OP_Noop 108
-
-#define OP_Strlen 109
-#define OP_Substr 110
-
-#define OP_Limit 111
-
-#define OP_MAX 111
+#define OP_PutIntKey 15
+#define OP_PutStrKey 16
+#define OP_Distinct 17
+#define OP_Found 18
+#define OP_NotFound 19
+#define OP_NotExists 20
+#define OP_Delete 21
+#define OP_Column 22
+#define OP_KeyAsData 23
+#define OP_Recno 24
+#define OP_FullKey 25
+#define OP_Rewind 26
+#define OP_Next 27
+
+#define OP_Destroy 28
+#define OP_Clear 29
+#define OP_CreateIndex 30
+#define OP_CreateTable 31
+#define OP_Reorganize 32
+
+#define OP_IdxPut 33
+#define OP_IdxDelete 34
+#define OP_IdxRecno 35
+#define OP_IdxGT 36
+#define OP_IdxGE 37
+
+#define OP_MemLoad 38
+#define OP_MemStore 39
+
+#define OP_ListWrite 40
+#define OP_ListRewind 41
+#define OP_ListRead 42
+#define OP_ListReset 43
+
+#define OP_SortPut 44
+#define OP_SortMakeRec 45
+#define OP_SortMakeKey 46
+#define OP_Sort 47
+#define OP_SortNext 48
+#define OP_SortCallback 49
+#define OP_SortReset 50
+
+#define OP_FileOpen 51
+#define OP_FileRead 52
+#define OP_FileColumn 53
+
+#define OP_AggReset 54
+#define OP_AggFocus 55
+#define OP_AggIncr 56
+#define OP_AggNext 57
+#define OP_AggSet 58
+#define OP_AggGet 59
+
+#define OP_SetInsert 60
+#define OP_SetFound 61
+#define OP_SetNotFound 62
+
+#define OP_MakeRecord 63
+#define OP_MakeKey 64
+#define OP_MakeIdxKey 65
+#define OP_IncrKey 66
+
+#define OP_Goto 67
+#define OP_If 68
+#define OP_Halt 69
+
+#define OP_ColumnCount 70
+#define OP_ColumnName 71
+#define OP_Callback 72
+#define OP_NullCallback 73
+
+#define OP_Integer 74
+#define OP_String 75
+#define OP_Pop 76
+#define OP_Dup 77
+#define OP_Pull 78
+#define OP_MustBeInt 79
+
+#define OP_Add 80
+#define OP_AddImm 81
+#define OP_Subtract 82
+#define OP_Multiply 83
+#define OP_Divide 84
+#define OP_Remainder 85
+#define OP_BitAnd 86
+#define OP_BitOr 87
+#define OP_BitNot 88
+#define OP_ShiftLeft 89
+#define OP_ShiftRight 90
+#define OP_AbsValue 91
+#define OP_Precision 92
+#define OP_Min 93
+#define OP_Max 94
+#define OP_Like 95
+#define OP_Glob 96
+#define OP_Eq 97
+#define OP_Ne 98
+#define OP_Lt 99
+#define OP_Le 100
+#define OP_Gt 101
+#define OP_Ge 102
+#define OP_IsNull 103
+#define OP_NotNull 104
+#define OP_Negative 105
+#define OP_And 106
+#define OP_Or 107
+#define OP_Not 108
+#define OP_Concat 109
+#define OP_Noop 110
+
+#define OP_Strlen 111
+#define OP_Substr 112
+
+#define OP_Limit 113
+
+#define OP_MAX 113
/*
** Prototypes for the VDBE interface. See comments on the implementation
** the WHERE clause of SQL statements. Also found here are subroutines
** to generate VDBE code to evaluate expressions.
**
-** $Id: where.c,v 1.32 2002/01/09 03:20:00 drh Exp $
+** $Id: where.c,v 1.33 2002/01/28 15:53:05 drh Exp $
*/
#include "sqliteInt.h"
cont = pLevel->cont = brk;
sqliteVdbeAddOp(v, OP_MustBeInt, 0, brk);
if( i==pTabList->nId-1 && pushKey ){
+ /* Note: The OP_Dup below will cause the key to be left on the
+ ** stack if the key does not exists and the OP_NotExists jump is
+ ** taken. This violates a general rule of the VDBE that you should
+ ** never leave values on the stack in order to avoid a stack overflow.
+ ** But in this case, the OP_Dup will never happen inside of a loop,
+ ** so it is safe to leave it on the stack.
+ */
haveKey = 1;
- sqliteVdbeAddOp(v, OP_Distinct, base+idx, brk);
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0);
}else{
- sqliteVdbeAddOp(v, OP_NotFound, base+idx, brk);
haveKey = 0;
}
+ sqliteVdbeAddOp(v, OP_NotExists, base+idx, brk);
pLevel->op = OP_Noop;
}else if( pIdx!=0 && pLevel->score%4==0 ){
/* Case 2: All index constraints are equality operators.
# This file implements regression tests for SQLite library. The
# focus of this file is testing the IN and BETWEEN operator.
#
-# $Id: in.test,v 1.5 2001/09/16 00:13:28 drh Exp $
+# $Id: in.test,v 1.6 2002/01/28 15:53:05 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
}
} {hello world}
+# Make sure the IN operator works with INTEGER PRIMARY KEY fields.
+#
+do_test in-6.1 {
+ execsql {
+ CREATE TABLE ta(a INTEGER PRIMARY KEY, b);
+ INSERT INTO ta VALUES(1,1);
+ INSERT INTO ta VALUES(2,2);
+ INSERT INTO ta VALUES(3,3);
+ INSERT INTO ta VALUES(4,4);
+ INSERT INTO ta VALUES(6,6);
+ INSERT INTO ta VALUES(8,8);
+ SELECT * FROM ta;
+ }
+} {1 1 2 2 3 3 4 4 6 6 8 8}
+do_test in-6.2 {
+ execsql {
+ CREATE TABLE tb(a INTEGER PRIMARY KEY, b);
+ INSERT INTO tb VALUES(1,1);
+ INSERT INTO tb VALUES(2,2);
+ INSERT INTO tb VALUES(3,3);
+ INSERT INTO tb VALUES(5,5);
+ INSERT INTO tb VALUES(7,7);
+ INSERT INTO tb VALUES(9,9);
+ SELECT * FROM tb;
+ }
+} {1 1 2 2 3 3 5 5 7 7 9 9}
+do_test in-6.3 {
+ execsql {
+ SELECT a FROM ta WHERE b IN (SELECT a FROM tb);
+ }
+} {1 2 3}
+do_test in-6.4 {
+ execsql {
+ SELECT a FROM ta WHERE b NOT IN (SELECT a FROM tb);
+ }
+} {4 6 8}
+do_test in-6.5 {
+ execsql {
+ SELECT a FROM ta WHERE b IN (SELECT b FROM tb);
+ }
+} {1 2 3}
+do_test in-6.6 {
+ execsql {
+ SELECT a FROM ta WHERE b NOT IN (SELECT b FROM tb);
+ }
+} {4 6 8}
+do_test in-6.7 {
+ execsql {
+ SELECT a FROM ta WHERE a IN (SELECT a FROM tb);
+ }
+} {1 2 3}
+do_test in-6.8 {
+ execsql {
+ SELECT a FROM ta WHERE a NOT IN (SELECT a FROM tb);
+ }
+} {4 6 8}
+do_test in-6.9 {
+ execsql {
+ SELECT a FROM ta WHERE a IN (SELECT b FROM tb);
+ }
+} {1 2 3}
+do_test in-6.10 {
+ execsql {
+ SELECT a FROM ta WHERE a NOT IN (SELECT b FROM tb);
+ }
+} {4 6 8}
+
+
finish_test
puts "<DD><P><UL>$desc</UL></P></DD>"
}
+chng {2002 Jan 28 (2.2.5)} {
+<li>Important bug fix: the IN operator was not working if either the
+ left-hand or right-hand side was derived from an INTEGER PRIMARY KEY.</li>
+<li>Do not escape the backslash '\' character in the output of the
+ <b>sqlite</b> command-line access program.</li>
+}
+
chng {2002 Jan 22 (2.2.4)} {
<li>The label to the right of an AS in the column list of a SELECT can now
be used as part of an expression in the WHERE, ORDER BY, GROUP BY, and/or