-C Changes\sto\sbtree\sand\spager\sin\spreparation\sfor\smoving\sto\srun-time\spage\nsize\sdetermination.\s(CVS\s1374)
-D 2004-05-14T01:58:12
+C Implement\stype\saffinity\sfor\stable\sand\sindex\srecords\s(CVS\s1375)
+D 2004-05-14T11:00:53
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/btree.c 2b85dc8f6b169bbe6bc0dab1730757f77d72811b
F src/btree.h 6f51ad0ffebfba71295fcacdbe86007512200050
F src/btree_rb.c 9d7973e266ee6f9c61ce592f68742ce9cd5b10e5
-F src/build.c f25e4ac9f102efd70188bc09a459c2b461fe2135
+F src/build.c e93f443a20eab57ffb77ff6244b1e09a1f7d9390
F src/copy.c 4d2038602fd0549d80c59bda27d96f13ea9b5e29
-F src/date.c 1564caa119511a1bb23dd0b1530ad38ed8c3349b
+F src/date.c 0eb0a89960bb45c7f7e768748605a7a97b0c8064
F src/delete.c 30c8c4375e75e811c3668abf3f78970fe549f375
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
F src/expr.c a3aed7057bafb3a01e8af98a5f74a102621b7a91
-F src/func.c 4b3147e841a4db9bf41768d79aaa46e6655b239a
+F src/func.c 4053dc2141ea46e8e35df089d87bfcbab54320bc
F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
-F src/insert.c 1e63d2774c4d893363e0c072f19d4c92a4ab982d
+F src/insert.c 5d4d1a59f66b558213984391985a418efc1c2797
F src/main.c 4b82d7e78f4c9799343b02740a5ba9768d5e464d
F src/md5.c 8e39fdae6d8776b87558e91dcc94740c9b635a9c
F src/os.c ddcda92f7fd71b4513c57c1ec797917f206d504e
F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c ca99ae4db14a45a436ec51d3e6bd48d44a3efb3c
-F src/shell.c 255b8b9023cb5274f56d87df437e8ce6ef810b91
+F src/shell.c 0c4662e13bfbfd3d13b066c5859cc97ad2f95d21
F src/sqlite.h.in 799c5e726296ec7bc20e6407cdf4df0e0bc00c0c
-F src/sqliteInt.h 168f441f72f5d1ab476ea85ac544712fe57f31c0
+F src/sqliteInt.h 3b593addbd54228a545ec3ea4f7689c261ae5fa1
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
F src/tclsqlite.c fbf0fac73624ae246551a6c671f1de0235b5faa1
F src/test1.c 12ef76b8aaba4408422f21f269256b630d4dd627
F src/test5.c eb39aac8fed61bd930b92613cd705c145244074a
F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847
F src/trigger.c 8df308e09113410bb895e88a2db65b55490268db
-F src/update.c 6ca82fc4a0fb4d7f134e961921c906f6f3c8bc74
+F src/update.c 0441f8b64d616ef244583449e66c984e536c6c9b
F src/utf.c fc799748d43fe1982d157b871e3e420a19c85d4f
-F src/util.c 778a8cd03ad6e52778602d20a3132c7d2d1b0a0c
+F src/util.c 58407b133dfe0b21af23e0aa89c058a2b3d8cb0f
F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476
-F src/vdbe.c a6ba83386f8137cb5aff7980a519c1529052849a
+F src/vdbe.c a6e1bfe1188f16783260a1fdc391ecc2c6a1dab6
F src/vdbe.h 94457ca73bae972dc61bca33a4dccc2e6e14e2f8
-F src/vdbeInt.h d53f38078ca4727c5f2851bc47ad648645bfab82
-F src/vdbeaux.c 8bf71f7ba91a208c5e0a8bcf5da03889bc858041
-F src/where.c 487e55b1f64c8fbf0f46a9a90c2247fc45ae6a9a
+F src/vdbeInt.h 03f4c3642482570a697a42a9bbb12908c6535bbe
+F src/vdbeaux.c d8dc16e7bfb6201a2e2e4c020ba813e295de717f
+F src/where.c 292f3d3d056d69197573eceb5578d7ba905725df
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
F test/attach2.test 7c388dee63a4c1997695c3d41957f32ce784ac56
F test/expr.test 8b62f3fcac64fbd5c3d43d7a7984245743dcbe65
F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7
F test/format3.test 149cc166c97923fa60def047e90dd3fb32bba916
-F test/func.test 000515779001ac6899eec4b54e65c6e2501279d4
+F test/func.test e77f46af34c23081c3aacb84f25238b808bd7202
F test/hook.test 1a67ce0cd64a6455d016962542f2822458dccc49
F test/in.test 0de39b02ceeca90993b096822fb5a884661c5b47
-F test/index.test 9295deefbdb6dedbe01be8905f0c448fe5bd4079
+F test/index.test 231ff7a4c9d4d002c07d8383dc44184dad06e6ec
F test/insert.test 6ec324659656f4a86e4abfcf1a1fd2795ba6b603
F test/insert2.test c288375a64dad3295044714f0dfed4a193cf067f
F test/interrupt.test 9142ce4448605127640eda5e283952f75f67ed91
F test/pragma.test 06c4e51998dd68115ef7a60abeeff7accf198f83
F test/printf.test 46b3d07d59d871d0831b4a657f6dfcafe0574850
F test/progress.test 701b6115c2613128ececdfe1398a1bd0e1a4cfb3 x
-F test/quick.test b9dc7ad37e96da28f7d0c5e9e154024307ef568b
+F test/quick.test fa37bb9bf8f6a531b33f852284fa03f89a407697
F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d
F test/rowid.test 863e6e75878cccf03d166fe52023f20e09508683
F test/select1.test 3bfcccd2eadcddbb07f1f5da6550aee8484ea4fb
-F test/select2.test 2115d8f7a34fcb5c0cbe8491f441830bc44d3398
+F test/select2.test bafe576b76616f101c06a780a8155d5a6c363127
F test/select3.test 445a1a3dde4e2fd32541b311f55da5e2f8079d76
-F test/select4.test 804b48d637aeee5e952333a997cfba316b489a3a
+F test/select4.test d2443e558c5013b22eaa25533fa22ef0ff0b1095
F test/select5.test c2a6c4a003316ee42cbbd689eebef8fdce0db2ac
F test/select6.test a9e31906e700e7c7592c4d0acfc022808f718baf
-F test/sort.test ba07b107c16070208e6aab3cadea66ba079d85ba
+F test/sort.test 63e1b0e982f08f0ff5b55d420db31f6f8c0d4c1c
F test/subselect.test f0fea8cf9f386d416d64d152e3c65f9116d0f50f
F test/table.test 371a1fc1c470982b2f68f9732f903a5d96f949c4
F test/tableapi.test e0c4cce61e58343caa84dab33fa6823cb35fe1e1
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 790226c94493a6d58a7e52fd3ed35ef495fab11e
-R 1732d9617f45de2d10dd8c0de779aa14
-U drh
-Z 4d4be7c36b4d139bc06baaeae3481d2d
+P f63fb6dd4e8e33d4c1983396b1a0305836ee4df7
+R 063a4d7caa30f9e2870f52d893366e1a
+U danielk1977
+Z 458386d9c0f0338b7a617dad680da64b
-f63fb6dd4e8e33d4c1983396b1a0305836ee4df7
\ No newline at end of file
+dbfe6e93166d9557d66cab9dca7977baa3501e5e
\ No newline at end of file
** ROLLBACK
** PRAGMA
**
-** $Id: build.c,v 1.182 2004/05/12 11:24:03 danielk1977 Exp $
+** $Id: build.c,v 1.183 2004/05/14 11:00:53 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
}
sqliteFree(pTable->zName);
sqliteFree(pTable->aCol);
+ if( pTable->zColAff ){
+ sqliteFree(pTable->zColAff);
+ }
sqlite3SelectDelete(pTable->pSelect);
sqliteFree(pTable);
}
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: date.c,v 1.18 2004/05/10 10:34:35 danielk1977 Exp $
+** $Id: date.c,v 1.19 2004/05/14 11:00:53 danielk1977 Exp $
**
** NOTES:
**
return 0;
}
return 1;
- }else if( sqlite3IsNumber(zDate) ){
+ }else if( sqlite3IsNumber(zDate, 0) ){
p->rJD = sqlite3AtoF(zDate, 0);
p->validJD = 1;
return 0;
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: func.c,v 1.46 2004/05/13 11:34:16 danielk1977 Exp $
+** $Id: func.c,v 1.47 2004/05/14 11:00:53 danielk1977 Exp $
*/
#include <ctype.h>
#include <math.h>
if( argc<1 ) return;
if( argv[0]==0 ){
sqlite3_set_result_string(context, "NULL", 4);
- }else if( sqlite3IsNumber(argv[0]) ){
+ }else if( sqlite3IsNumber(argv[0], 0) ){
sqlite3_set_result_string(context, argv[0], -1);
}else{
int i,j,n;
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
-** $Id: insert.c,v 1.97 2004/05/11 07:11:53 danielk1977 Exp $
+** $Id: insert.c,v 1.98 2004/05/14 11:00:53 danielk1977 Exp $
*/
#include "sqliteInt.h"
+/*
+** Set P3 of the most recently inserted opcode to a column affinity
+** string for table pTab. A column affinity string has one character
+** for each column in the table, according to the affinity of the column:
+**
+** Character Column affinity
+** ------------------------------
+** 'n' NUMERIC
+** 'i' INTEGER
+** 't' TEXT
+** 'o' NONE
+*/
+int sqlite3AddRecordType(Vdbe *v, Table *pTab){
+ assert( pTab );
+
+ /* The first time a column affinity string for a particular table
+ ** is required, it is allocated and populated here. It is then
+ ** stored as a member of the Table structure for subsequent use.
+ **
+ ** The column affinity string will eventually be deleted by
+ ** sqlite3DeleteTable() when the Table structure itself is cleaned up.
+ */
+ if( !pTab->zColAff ){
+ char *zColAff;
+ int i;
+
+ zColAff = sqliteMalloc(pTab->nCol+1);
+ if( !zColAff ){
+ return SQLITE_NOMEM;
+ }
+
+ for(i=0; i<pTab->nCol; i++){
+ if( pTab->aCol[i].sortOrder&SQLITE_SO_TEXT ){
+ zColAff[i] = 't';
+ }else{
+ zColAff[i] = 'n';
+ }
+ }
+ zColAff[pTab->nCol] = '\0';
+
+ pTab->zColAff = zColAff;
+ }
+
+ /* Set the memory management at the vdbe to P3_STATIC, as the column
+ ** affinity string is managed as part of the Table structure.
+ */
+ sqlite3VdbeChangeP3(v, -1, pTab->zColAff, P3_STATIC);
+ return SQLITE_OK;
+}
+
+
/*
** This routine is call to handle SQL of the following forms:
**
srcTab = pParse->nTab++;
sqlite3VdbeResolveLabel(v, iInsertBlock);
sqlite3VdbeAddOp(v, OP_MakeRecord, nColumn, 0);
+ sqlite3AddRecordType(v, pTab);
sqlite3VdbeAddOp(v, OP_NewRecno, srcTab, 0);
sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
sqlite3VdbeAddOp(v, OP_PutIntKey, srcTab, 0);
}
}
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
+ sqlite3AddRecordType(v, pTab);
sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
/* Fire BEFORE or INSTEAD OF triggers */
sqlite3VdbeAddOp(v, OP_IdxPut, base+i+1, 0);
}
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
+ sqlite3AddRecordType(v, pTab);
if( newIdx>=0 ){
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
sqlite3VdbeAddOp(v, OP_Dup, 1, 0);
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
-** $Id: shell.c,v 1.95 2004/05/10 10:34:52 danielk1977 Exp $
+** $Id: shell.c,v 1.96 2004/05/14 11:00:53 danielk1977 Exp $
*/
#include <stdlib.h>
#include <string.h>
/*
** Determines if a string is a number of not.
*/
-extern int sqlite3IsNumber(const char*);
+extern int sqlite3IsNumber(const char*, int*);
/*
** This routine reads a line of text from standard input, stores
char *zSep = i>0 ? ",": "";
if( azArg[i]==0 ){
fprintf(p->out,"%sNULL",zSep);
- }else if( sqlite3IsNumber(azArg[i]) ){
+ }else if( sqlite3IsNumber(azArg[i], 0) ){
fprintf(p->out,"%s%s",zSep, azArg[i]);
}else{
if( zSep[0] ) fprintf(p->out,"%s",zSep);
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.231 2004/05/12 11:24:03 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.232 2004/05/14 11:00:53 danielk1977 Exp $
*/
#include "config.h"
#include "sqlite.h"
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
Trigger *pTrigger; /* List of SQL triggers on this table */
FKey *pFKey; /* Linked list of all foreign keys in this table */
+ char *zColAff; /* String defining the affinity of each column */
};
/*
int sqlite3StrICmp(const char *, const char *);
int sqlite3StrNICmp(const char *, const char *, int);
int sqlite3HashNoCase(const char *, int);
-int sqlite3IsNumber(const char*);
+int sqlite3IsNumber(const char*, int*);
int sqlite3Compare(const char *, const char *);
int sqlite3SortCompare(const char *, const char *);
void sqlite3RealToSortable(double r, char *);
int sqlite3PutVarint(unsigned char *, u64);
int sqlite3GetVarint(const unsigned char *, u64 *);
int sqlite3VarintLen(u64 v);
+int sqlite3AddRecordType(Vdbe*, Table*);
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
-** $Id: update.c,v 1.72 2004/05/10 10:35:00 danielk1977 Exp $
+** $Id: update.c,v 1.73 2004/05/14 11:00:53 danielk1977 Exp $
*/
#include "sqliteInt.h"
}
}
sqlite3VdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
+ sqlite3AddRecordType(v, pTab);
sqlite3VdbeAddOp(v, OP_PutIntKey, newIdx, 0);
if( !isView ){
sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
-** $Id: util.c,v 1.80 2004/05/11 06:17:22 danielk1977 Exp $
+** $Id: util.c,v 1.81 2004/05/14 11:00:53 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
/*
** Return TRUE if z is a pure numeric string. Return FALSE if the
-** string contains any character which is not part of a number.
+** string contains any character which is not part of a number. If
+** the string is numeric and contains the '.' character, set *realnum
+** to TRUE (otherwise FALSE).
**
** Am empty string is considered non-numeric.
*/
-int sqlite3IsNumber(const char *z){
+int sqlite3IsNumber(const char *z, int *realnum){
if( *z=='-' || *z=='+' ) z++;
if( !isdigit(*z) ){
return 0;
}
z++;
+ if( realnum ) *realnum = 0;
while( isdigit(*z) ){ z++; }
if( *z=='.' ){
z++;
if( !isdigit(*z) ) return 0;
while( isdigit(*z) ){ z++; }
+ if( realnum ) *realnum = 1;
}
if( *z=='e' || *z=='E' ){
z++;
if( *z=='+' || *z=='-' ) z++;
if( !isdigit(*z) ) return 0;
while( isdigit(*z) ){ z++; }
+ if( realnum ) *realnum = 1;
}
return *z==0;
}
}else if( btext==0 ){
return 1;
}
- isNumA = sqlite3IsNumber(atext);
- isNumB = sqlite3IsNumber(btext);
+ isNumA = sqlite3IsNumber(atext, 0);
+ isNumB = sqlite3IsNumber(btext, 0);
if( isNumA ){
if( !isNumB ){
result = -1;
res = strcmp(&a[1],&b[1]);
if( res ) break;
}else{
- isNumA = sqlite3IsNumber(&a[1]);
- isNumB = sqlite3IsNumber(&b[1]);
+ isNumA = sqlite3IsNumber(&a[1], 0);
+ isNumB = sqlite3IsNumber(&b[1], 0);
if( isNumA ){
double rA, rB;
if( !isNumB ){
** 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.287 2004/05/13 13:38:52 danielk1977 Exp $
+** $Id: vdbe.c,v 1.288 2004/05/14 11:00:53 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
** Under Linux (RedHat 7.2) this routine is much faster than atoi()
** for converting strings into integers.
*/
-static int toInt(const char *zNum, int *pNum){
- int v = 0;
+static int toInt(const char *zNum, i64 *pNum){
+ i64 v = 0;
int neg;
int i, c;
if( *zNum=='-' ){
v = v*10 + c - '0';
}
*pNum = neg ? -v : v;
- return c==0 && i>0 && (i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0));
+ return c==0 && i>0 &&
+ (i<10 || (i==19 && memcmp(zNum,"9223372036854775807",19)<=0));
}
/*
return 0;
}
+/*
+** Apply any conversion required by the supplied column affinity to
+** memory cell pRec. affinity may be one of:
+**
+** SQLITE_AFF_NUM
+** SQLITE_AFF_TEXT
+** SQLITE_AFF_NONE
+** SQLITE_AFF_INTEGER
+**
+*/
+static void applyAffinity(Mem *pRec, int affinity){
+ switch( affinity ){
+ case SQLITE_SO_NUM:
+ if( 0==(pRec->flags&(MEM_Real|MEM_Int)) ){
+ /* pRec does not have a valid integer or real representation.
+ ** Attempt a conversion if pRec has a string representation and
+ ** it looks like a number.
+ */
+ int realnum;
+ if( pRec->flags&MEM_Str && sqlite3IsNumber(pRec->z, &realnum) ){
+ if( realnum ){
+ Realify(pRec);
+ }else{
+ Integerify(pRec);
+ }
+ }
+ }
+ break;
+ case SQLITE_SO_TEXT:
+ /* Only attempt the conversion if there is an integer or real
+ ** representation (blob and NULL do not get converted) but no string
+ ** representation.
+ */
+ if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
+ Stringify(pRec);
+ }
+ pRec->flags &= ~(MEM_Real|MEM_Int);
+
+ break;
+
+/*
+ case SQLITE_AFF_INTEGER:
+ case SQLITE_AFF_NONE:
+ break;
+*/
+ default:
+ assert(0);
+ }
+}
+
+/*
+** This function interprets the character 'affinity' according to the
+** following table and calls the applyAffinity() function.
+*/
+static void applyAffinityByChar(Mem *pRec, char affinity){
+ switch( affinity ){
+ case 'n': return applyAffinity(pRec, SQLITE_SO_NUM);
+ case 't': return applyAffinity(pRec, SQLITE_SO_TEXT);
+ default: assert(0);
+ }
+}
+
#ifdef VDBE_PROFILE
/*
** The following routine only works on pentium-class processors.
int nProgressOps = 0; /* Opcodes executed since progress callback. */
#endif
+ /* FIX ME. */
+ expandCursorArraySize(p, 100);
+
if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;
assert( db->magic==SQLITE_MAGIC_BUSY );
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
int v;
assert( pTos>=p->aStack );
if( (pTos->flags & (MEM_Int|MEM_Real))==0
- && ((pTos->flags & MEM_Str)==0 || sqlite3IsNumber(pTos->z)==0) ){
+ && ((pTos->flags & MEM_Str)==0 || sqlite3IsNumber(pTos->z, 0)==0) ){
Release(pTos);
pTos--;
pc = pOp->p2 - 1;
}
pTos->i = i;
}else if( pTos->flags & MEM_Str ){
- int v;
+ i64 v;
if( !toInt(pTos->z, &v) ){
double r;
- if( !sqlite3IsNumber(pTos->z) ){
+ if( !sqlite3IsNumber(pTos->z, 0) ){
goto mismatch;
}
Realify(pTos);
case OP_Gt:
case OP_Ge: {
Mem *pNos = &pTos[-1];
- int c, v;
+ i64 c, v;
int ft, fn;
assert( pNos>=p->aStack );
ft = pTos->flags;
break;
}
-/* Opcode MakeRecord3 P1 * *
+/* Opcode MakeRecord P1 * P3
**
** This opcode (not yet in use) is a replacement for the current
** OP_MakeRecord that supports the SQLite3 manifest typing feature.
** details of the format are irrelavant as long as the OP_Column
** opcode can decode the record later. Refer to source code
** comments for the details of the record format.
+**
+** P3 may be a string that is P1 characters long. The nth character of the
+** string indicates the column affinity that should be used for the nth
+** field of the index key (i.e. the first character of P3 corresponds to the
+** lowest element on the stack).
+**
+** Character Column affinity
+** ------------------------------
+** 'n' NUMERIC
+** 'i' INTEGER
+** 't' TEXT
+** 'o' NONE
+**
+** If P3 is NULL then all index fields have the affinity NONE.
*/
case OP_MakeRecord: {
/* Assuming the record contains N fields, the record format looks
int nField = pOp->p1;
unsigned char *zNewRecord;
unsigned char *zCsr;
+ char *zAffinity;
Mem *pRec;
int nBytes; /* Space required for this record */
Mem *pData0 = &pTos[1-nField];
assert( pData0>=p->aStack );
+ zAffinity = pOp->p3;
/* Loop through the elements that will make up the record to figure
** out how much space is required for the new record.
*/
nBytes = sqlite3VarintLen(nField);
for(pRec=pData0; pRec<=pTos; pRec++){
- u64 serial_type = sqlite3VdbeSerialType(pRec);
+ u64 serial_type;
+ if( zAffinity ){
+ applyAffinityByChar(pRec, zAffinity[pRec-pData0]);
+ }
+ serial_type = sqlite3VdbeSerialType(pRec);
nBytes += sqlite3VdbeSerialTypeLen(serial_type);
nBytes += sqlite3VarintLen(serial_type);
}
Stringify(pRec);
pRec->flags &= ~(MEM_Int|MEM_Real);
nByte += pRec->n+1;
- }else if( (flags & (MEM_Real|MEM_Int))!=0 || sqlite3IsNumber(pRec->z) ){
+ }else if( (flags & (MEM_Real|MEM_Int))!=0 || sqlite3IsNumber(pRec->z, 0) ){
if( (flags & (MEM_Real|MEM_Int))==MEM_Int ){
pRec->r = pRec->i;
}else if( (flags & (MEM_Real|MEM_Int))==0 ){
break;
}
-/* Opcode: MakeIdxKey3 P1 P2 *
+/* Opcode: MakeKey P1 P2 P3
+**
+** Convert the top P1 entries of the stack into a single entry suitable
+** for use as the key in an index. If P2 is not zero, then the original
+** entries are popped off the stack. If P2 is zero, the original entries
+** remain on the stack.
+**
+** P3 is interpreted in the same way as for MakeIdxKey.
+*/
+/* Opcode: MakeIdxKey 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.
+** pushed back.
+**
+** If P2 is not zero and one or more of the P1 entries that go into the
+** generated key is NULL, then jump to P2 after the new key has been
+** pushed on the stack. In other words, jump to P2 if the key is
+** guaranteed to be unique. This jump can be used to skip a subsequent
+** uniqueness test.
+**
+** P3 may be a string that is P1 characters long. The nth character of the
+** string indicates the column affinity that should be used for the nth
+** field of the index key (i.e. the first character of P3 corresponds to the
+** lowest element on the stack).
+**
+** Character Column affinity
+** ------------------------------
+** 'n' NUMERIC
+** 'i' INTEGER
+** 't' TEXT
+** 'o' NONE
+**
+** If P3 is NULL then all index fields have the affinity NUMERIC.
*/
case OP_MakeKey:
case OP_MakeIdxKey: {
int containsNull = 0;
char *zKey; /* The new key */
int offset = 0;
+ char *zAffinity = pOp->p3;
+ assert( zAffinity );
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.
+ /* Loop through the P1 elements that will make up the new index
+ ** key. Call applyAffinity() to perform any conversion required
+ ** the column affinity string P3 to modify stack elements in place.
+ ** Set containsNull to 1 if a NULL value is encountered.
+ **
+ ** Once the value has been coerced, figure out how much space is required
+ ** to store the coerced values serial-type and blob, and add this
+ ** quantity to nByte.
+ **
+ ** TODO: Figure out if the in-place coercion causes a problem for
+ ** OP_MakeKey when P2 is 0 (used by DISTINCT).
*/
for(pRec=pData0; pRec<=pTos; pRec++){
- u64 serial_type = sqlite3VdbeSerialType(pRec);
- if( serial_type==0 ){
+ u64 serial_type;
+ if( zAffinity ){
+ applyAffinityByChar(pRec, zAffinity[pRec-pData0]);
+ }else{
+ applyAffinity(pRec, SQLITE_SO_NUM);
+ }
+ if( pRec->flags&MEM_Null ){
containsNull = 1;
}
+ serial_type = sqlite3VdbeSerialType(pRec);
nByte += sqlite3VarintLen(serial_type);
nByte += sqlite3VdbeSerialTypeLen(serial_type);
}
+
+ /* If we have to append a varint rowid to this record, set 'rowid'
+ ** to the value of the rowid and increase nByte by the amount of space
+ ** required to store it and the 0x00 seperator byte.
+ */
if( addRowid ){
pRec = &pTos[0-nField];
assert( pRec>=p->aStack );
pTos->z = zKey;
pTos->n = nByte;
- if( pOp->p2 && containsNull ){
+ /* If P2 is non-zero, and if the key contains a NULL value, and if this
+ ** was an OP_MakeIdxKey instruction, not OP_MakeKey, jump to P2.
+ */
+ if( pOp->p2 && containsNull && addRowid ){
pc = pOp->p2 - 1;
}
break;
** byte of that key by one. This is used so that the MoveTo opcode
** will move to the first entry greater than the key rather than to
** the key itself.
+**
*/
case OP_IncrKey: {
assert( pTos>=p->aStack );
** are always free to modify the string in place.
*/
assert( pTos->flags & (MEM_Dyn|MEM_Short) );
+ /*
+ ** FIX ME: This technique is now broken due to manifest types in index
+ ** keys.
+ */
+ assert(0);
pTos->z[pTos->n-1]++;
break;
}
** 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,
+ rc = sqlite3BtreeCursor(pX, p2, wrFlag, sqlite3VdbeKeyCompare, pCur,
&pCur->pCursor);
switch( rc ){
case SQLITE_BUSY: {
** If there are no records greater than the key and P2 is not zero,
** then an immediate jump to P2 is made.
**
+** If P3 is not NULL, then the cursor is left pointing at the first
+** record that is greater than the key of which the key is not a prefix.
+** This is the same effect that executing OP_IncrKey on the key value
+** before OP_MoveTo used to have.
+**
** See also: Found, NotFound, Distinct, MoveLt
*/
/* Opcode: MoveLt P1 P2 *
** If there are no records less than than the key and P2
** is not zero then an immediate jump to P2 is made.
**
+** If P3 is not NULL, and keys exist in the index of which the stack key
+** is a prefix, leave the cursor pointing at the largest of these.
+** This is the same effect that executing OP_IncrKey on the key value
+** before OP_MoveLt used to have.
+**
** See also: MoveTo
*/
case OP_MoveLt:
pC->nullRow = 0;
if( pC->intKey ){
i64 iKey;
+ assert( !pOp->p3 );
Integerify(pTos);
iKey = intToKey(pTos->i);
if( pOp->p2==0 && pOp->opcode==OP_MoveTo ){
pC->lastRecno = pTos->i;
pC->recnoIsValid = res==0;
}else{
+ if( pOp->p3 ){
+ pC->incrKey = 1;
+ }
Stringify(pTos);
sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
+ pC->incrKey = 0;
pC->recnoIsValid = 0;
}
pC->deferredMoveto = 0;
+ pC->incrKey = 0;
sqlite3_search_count++;
oc = pOp->opcode;
if( oc==OP_MoveTo && res<0 ){
break;
}
}
- rc = sqlite3VdbeIdxKeyCompare(pCrsr, len, zKey, 0, &res);
+ rc = sqlite3VdbeIdxKeyCompare(pCx, len, zKey, 0, &res);
if( rc!=SQLITE_OK ) goto abort_due_to_error;
if( res>0 ){
pc = pOp->p2 - 1;
while( res!=0 ){
int c;
sqlite3BtreeKeySize(pCrsr, &n);
- if( n==nKey
- && sqlite3VdbeIdxKeyCompare(pCrsr, len, zKey, 0, &c)==SQLITE_OK
+ if( n==nKey &&
+ sqlite3VdbeIdxKeyCompare(&p->aCsr[i], len, zKey, 0, &c)==SQLITE_OK
&& c==0
){
rc = SQLITE_CONSTRAINT;
assert( i>=0 && i<p->nCursor );
pTos++;
if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
- u64 sz;
- int len;
- char buf[9];
+ i64 rowid;
assert( p->aCsr[i].deferredMoveto==0 );
assert( p->aCsr[i].intKey==0 );
+ rc = sqlite3VdbeIdxRowid(pCrsr, &rowid);
+ if( rc!=SQLITE_OK ){
+ goto abort_due_to_error;
+ }
+ pTos->flags = MEM_Int;
+ pTos->i = rowid;
+#if 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);
- len = ((sz>9)?9:sz);
+ len = ((sz>10)?10:sz);
rc = sqlite3BtreeKey(pCrsr, sz-len, len, buf);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
pTos->flags = MEM_Int;
pTos->i = sz;
}
+#endif
}else{
pTos->flags = MEM_Null;
}
assert( pTos>=p->aStack );
if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
int res, rc;
+ Cursor *pC = &p->aCsr[i];
Stringify(pTos);
assert( p->aCsr[i].deferredMoveto==0 );
- rc = sqlite3VdbeIdxKeyCompare(pCrsr, pTos->n, pTos->z, 0, &res);
+ if( pOp->p3 ){
+ pC->incrKey = 1;
+ }
+ rc = sqlite3VdbeIdxKeyCompare(pC, pTos->n, pTos->z, 0, &res);
+ pC->incrKey = 0;
if( rc!=SQLITE_OK ){
break;
}
z = pTos->z;
n = pTos->n;
for(k=0; k<n && i>0; i--){
- if( z[k]=='a' ){
+ u64 serial_type;
+ k += sqlite3GetVarint(&z[k], &serial_type);
+ if( serial_type==6 ){ /* Serial type 6 is a NULL */
pc = pOp->p2-1;
break;
}
- while( k<n && z[k] ){ k++; }
- k++;
+ k += sqlite3VdbeSerialTypeLen(serial_type);
}
Release(pTos);
pTos--;
aRoot = sqliteMallocRaw( sizeof(int)*(nRoot+1) );
if( aRoot==0 ) goto no_mem;
for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){
- toInt((char*)sqliteHashKey(i), &aRoot[j]);
+ i64 root64;
+ toInt((char*)sqliteHashKey(i), &root64);
+ aRoot[j] = root64;
}
aRoot[j] = 0;
sqlite3HashClear(&pSet->hash);
Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */
Bool intKey; /* True if the table requires integer keys */
Bool zeroData; /* True if table contains keys only - no data */
+ Bool incrKey; /* Searches on the table simulate OP_IncrKey */
i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */
Btree *pBt; /* Separate file holding temporary table */
int nData; /* Number of bytes in pData */
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 sqlite3VdbeIdxKeyCompare(Cursor*, int , const unsigned char*, int, int*);
int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
}else{
sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,sizeof(i64),&res);
}
+ p->incrKey = 0;
p->lastRecno = keyToInt(p->movetoTarget);
p->recnoIsValid = res==0;
if( res<0 ){
return 0;
}
- if( pMem1->i < pMem2->i ) return -1;
- if( pMem1->i > pMem2->i ) return 1;
- return 0;
+ return (pMem1->i - pMem2->i);
+ }
+
+ rc = (pMem2->flags&MEM_Null) - (pMem1->flags&MEM_Null);
+ if( rc ){
+ return rc;
}
/* Both values must be strings or blobs. If only one is a string, then
** 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;
+ return (pMem1->n - pMem2->n);
}
/*
** compared to.
*/
int sqlite3VdbeKeyCompare(
- void *userData, /* not used yet */
+ void *userData,
int nKey1, const void *pKey1,
int nKey2, const void *pKey2
){
+ Cursor *pC = (Cursor *)userData;
int offset1 = 0;
int offset2 = 0;
const unsigned char *aKey1 = (const unsigned char *)pKey1;
*/
if( !serial_type1 || !serial_type2 ){
assert( !serial_type1 && !serial_type2 );
+ assert( !pC || !pC->incrKey );
sqlite3GetVarint(&aKey1[offset1], &serial_type1);
sqlite3GetVarint(&aKey2[offset2], &serial_type2);
return ( (i64)serial_type1 - (i64)serial_type2 );
}
}
+ /* One of the keys ran out of fields, but all the fields up to that point
+ ** were equal. If the incrKey flag is true, then the second key is
+ ** treated as larger.
+ */
+ if( pC && pC->incrKey ){
+ assert( offset2==nKey2 );
+ return -1;
+ }
+
if( offset1<nKey1 ){
return 1;
}
if( offset2<nKey2 ){
return -1;
}
+
+return_result:
+
return 0;
}
int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){
i64 sz;
int rc;
- char buf[9];
+ char buf[10];
int len;
u64 r;
if( rc!=SQLITE_OK ){
return rc;
}
- len = ((sz>9)?9:sz);
- assert( len>=2 );
+ len = ((sz>10)?10:sz);
+
+ /* If there are less than 2 bytes in the key, this cannot be
+ ** a valid index entry. In practice this comes up for a query
+ ** of the sort "SELECT max(x) FROM t1;" when t1 is an empty table
+ ** with an index on x. In this case just call the rowid 0.
+ */
+ if( len<2 ){
+ *rowid = 0;
+ return SQLITE_OK;
+ }
rc = sqlite3BtreeKey(pCur, sz-len, len, buf);
if( rc!=SQLITE_OK ){
return rc;
}
- len = len - 2;
- while( buf[len] && --len );
+ len--;
+ while( buf[len-1] && --len );
- sqlite3GetVarint(buf, &r);
+ sqlite3GetVarint(&buf[len], &r);
*rowid = r;
return SQLITE_OK;
}
int sqlite3VdbeIdxKeyCompare(
- BtCursor *pCur,
+ Cursor *pC,
int nKey, const unsigned char *pKey,
int ignorerowid,
int *res
int freeCellKey = 0;
int rc;
int len;
+ BtCursor *pCur = pC->pCursor;
sqlite3BtreeKeySize(pCur, &nCellKey);
if( nCellKey<=0 ){
nKey--;
while( pKey[nKey] && --nKey );
}
- *res = sqlite3VdbeKeyCompare(0, len, pCellKey, nKey, pKey);
+ *res = sqlite3VdbeKeyCompare(pC, len, pCellKey, nKey, pKey);
if( freeCellKey ){
sqliteFree(pCellKey);
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.
**
-** $Id: where.c,v 1.91 2004/05/10 10:37:19 danielk1977 Exp $
+** $Id: where.c,v 1.92 2004/05/14 11:00:53 danielk1977 Exp $
*/
#include "sqliteInt.h"
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
sqlite3VdbeAddOp(v, OP_MakeKey, nColumn, 0);
sqlite3AddIdxKeyType(v, pIdx);
+ sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
if( nColumn==pIdx->nColumn || pLevel->bRev ){
- sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
testOp = OP_IdxGT;
}else{
+/*
sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
sqlite3VdbeAddOp(v, OP_IncrKey, 0, 0);
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
+*/
testOp = OP_IdxGE;
}
if( pLevel->bRev ){
/* Scan in reverse order */
- sqlite3VdbeAddOp(v, OP_IncrKey, 0, 0);
+ /* sqlite3VdbeAddOp(v, OP_IncrKey, 0, 0); */
sqlite3VdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
+ sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
sqlite3VdbeAddOp(v, OP_IdxLT, pLevel->iCur, brk);
pLevel->op = OP_Prev;
sqlite3VdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
sqlite3VdbeAddOp(v, testOp, pLevel->iCur, brk);
+ if( testOp==OP_IdxGE ){
+ sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
+ }
pLevel->op = OP_Next;
}
sqlite3VdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
sqlite3VdbeAddOp(v, OP_MakeKey, nCol, 0);
sqlite3AddIdxKeyType(v, pIdx);
+/*
if( leFlag ){
sqlite3VdbeAddOp(v, OP_IncrKey, 0, 0);
}
+*/
if( pLevel->bRev ){
sqlite3VdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
+ if( !geFlag ){
+ sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
+ }
}else{
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
}
sqlite3VdbeAddOp(v, OP_Goto, 0, brk);
sqlite3VdbeAddOp(v, OP_MakeKey, nCol, 0);
sqlite3AddIdxKeyType(v, pIdx);
+/*
if( !geFlag ){
sqlite3VdbeAddOp(v, OP_IncrKey, 0, 0);
}
+*/
if( pLevel->bRev ){
pLevel->iMem = pParse->nMem++;
sqlite3VdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
testOp = OP_IdxLT;
}else{
sqlite3VdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
+ if( !geFlag ){
+ sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
+ }
}
}else if( pLevel->bRev ){
testOp = OP_Noop;
if( testOp!=OP_Noop ){
sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
sqlite3VdbeAddOp(v, testOp, pLevel->iCur, brk);
+ if( (leFlag && !pLevel->bRev) || (!geFlag && pLevel->bRev) ){
+ sqlite3VdbeChangeP3(v, -1, "+", P3_STATIC);
+ }
}
sqlite3VdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
sqlite3VdbeAddOp(v, OP_IdxIsNull, nEqColumn + (score & 1), cont);
# This file implements regression tests for SQLite library. The
# focus of this file is testing built-in functions.
#
-# $Id: func.test,v 1.16 2002/11/04 19:32:26 drh Exp $
+# $Id: func.test,v 1.17 2004/05/14 11:00:53 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
} {0 {2 1.2345678901234 2}}
do_test func-4.4 {
catchsql {SELECT abs(c) FROM t1 ORDER BY a}
-} {0 {3 12345.67890 5}}
+} {0 {3 12345.6789 5}}
do_test func-4.4.1 {
execsql {SELECT abs(a) FROM t2}
} {1 {} 345 {} 67890}
# This file implements regression tests for SQLite library. The
# focus of this file is testing the CREATE INDEX statement.
#
-# $Id: index.test,v 1.24 2003/09/27 00:41:28 drh Exp $
+# $Id: index.test,v 1.25 2004/05/14 11:00:53 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
}
set sqlite_search_count 0
concat [execsql {SELECT c FROM t3 WHERE b==10}] $sqlite_search_count
-} {0.10 3}
+} {0.1 3}
integrity_check index-11.2
# same number they should compare equal to one another. Verify that this
# is true in indices.
#
+# Updated for sqlite v3: SQLite will now store these values as numbers
+# (because the affinity of column a is NUMERIC) so the quirky
+# representations are not retained. i.e. '+1.0' becomes '1'.
do_test index-12.1 {
execsql {
CREATE TABLE t4(a,b);
INSERT INTO t4 VALUES('00000',7);
SELECT a FROM t4 ORDER BY b;
}
-} {0.0 0.00 abc -1.0 +1.0 0 00000}
+} {0 0 abc -1 1 0 0}
do_test index-12.2 {
execsql {
SELECT a FROM t4 WHERE a==0 ORDER BY b
}
-} {0.0 0.00 0 00000}
+} {0 0 0 0}
do_test index-12.3 {
execsql {
SELECT a FROM t4 WHERE a<0.5 ORDER BY b
}
-} {0.0 0.00 -1.0 0 00000}
+} {0 0 -1 0 0}
do_test index-12.4 {
execsql {
SELECT a FROM t4 WHERE a>-0.5 ORDER BY b
}
-} {0.0 0.00 abc +1.0 0 00000}
+} {0 0 abc 1 0 0}
do_test index-12.5 {
execsql {
CREATE INDEX t4i1 ON t4(a);
SELECT a FROM t4 WHERE a==0 ORDER BY b
}
-} {0.0 0.00 0 00000}
+} {0 0 0 0}
do_test index-12.6 {
execsql {
SELECT a FROM t4 WHERE a<0.5 ORDER BY b
}
-} {0.0 0.00 -1.0 0 00000}
+} {0 0 -1 0 0}
do_test index-12.7 {
execsql {
SELECT a FROM t4 WHERE a>-0.5 ORDER BY b
}
-} {0.0 0.00 abc +1.0 0 00000}
+} {0 0 abc 1 0 0}
integrity_check index-12.8
# Make sure we cannot drop an automatically created index.
#***********************************************************************
# This file runs all tests.
#
-# $Id: quick.test,v 1.10 2004/05/13 13:38:52 danielk1977 Exp $
+# $Id: quick.test,v 1.11 2004/05/14 11:00:53 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
lappend EXCLUDE ioerr.test ;# seg-faults (?)
lappend EXCLUDE memdb.test ;# fails - malformed database
lappend EXCLUDE misc3.test ;# seg-faults (?)
-lappend EXCLUDE printf.test ;# sqlite3_XX vs sqlite_XX problem
lappend EXCLUDE table.test ;# assert() fails in pager
lappend EXCLUDE trans.test ;# assert() fails in pager
lappend EXCLUDE vacuum.test ;# seg-fault
+lappend EXCLUDE printf.test ;# sqlite3_XX vs sqlite_XX problem
lappend EXCLUDE auth.test ;# Cannot attach empty databases.
lappend EXCLUDE tableapi.test ;# sqlite3_XX vs sqlite_XX problem
lappend EXCLUDE version.test ;# uses the btree_meta API (not updated)
-# Some tests fail in these file, possibly because of the manifest
-# type-aware indices (or possibly not).
-lappend EXCLUDE delete.test
-lappend EXCLUDE update.test
+# Some tests fail in these file as a result of the partial manifest types
+# implementation.
lappend EXCLUDE misc1.test
-lappend EXCLUDE index.test
-lappend EXCLUDE copy.test
-lappend EXCLUDE conflict.test
lappend EXCLUDE capi2.test
-lappend EXCLUDE null.test
-lappend EXCLUDE trigger2.test
+lappend EXCLUDE sort.test
lappend EXCLUDE where.test
-lappend EXCLUDE unique.test
-lappend EXCLUDE limit.test
-lappend EXCLUDE intpkey.test
if {[sqlite -has-codec]} {
# This file implements regression tests for SQLite library. The
# focus of this file is testing the SELECT statement.
#
-# $Id: select2.test,v 1.19 2004/05/13 05:16:17 danielk1977 Exp $
+# $Id: select2.test,v 1.20 2004/05/14 11:00:53 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
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}
# focus of this file is testing UNION, INTERSECT and EXCEPT operators
# in SELECT statements.
#
-# $Id: select4.test,v 1.14 2004/05/13 05:16:17 danielk1977 Exp $
+# $Id: select4.test,v 1.15 2004/05/14 11:00:53 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
}
} {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;
} {n 1 log 0 n 2 log 1}
# 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 + 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');
+ 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');
COMMIT;
}
execsql {
# This file implements regression tests for SQLite library. The
# focus of this file is testing the CREATE TABLE statement.
#
-# $Id: sort.test,v 1.9 2003/04/18 17:45:15 drh Exp $
+# $Id: sort.test,v 1.10 2004/05/14 11:00:53 danielk1977 Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
} {2 3 6 7 1 4 5 8}
do_test sort-1.5 {
execsql {SELECT flt FROM t1 ORDER BY flt}
-} {-11 -1.6 -0.0013442 0.123 2.15 3.141592653 123.0 4221.0}
+} {-11 -1.6 -0.0013442 0.123 2.15 3.141592653 123 4221}
do_test sort-1.6 {
execsql {SELECT flt FROM t1 ORDER BY flt DESC}
-} {4221.0 123.0 3.141592653 2.15 0.123 -0.0013442 -1.6 -11}
+} {4221 123 3.141592653 2.15 0.123 -0.0013442 -1.6 -11}
do_test sort-1.7 {
execsql {SELECT roman FROM t1 ORDER BY roman}
} {I II III IV V VI VII VIII}
INSERT INTO t5 VALUES(100.0,'A2');
SELECT * FROM t5 ORDER BY a, b;
}
-} {100 A1 100.0 A2}
+} {100 A1 100 A2}
finish_test