SQLite

Check-in [34f03ba6a9]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Correctly handle 64-bit integers in SQL statements. (CVS 1408)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 34f03ba6a9d6e2144d0c6cbbbeb37b4c69705f1f
User & Date: drh 2004-05-19 20:41:03.000
Context
2004-05-19
21:09
Get more tests running. (CVS 1409) (check-in: 7eb3f29e30 user: drh tags: trunk)
20:41
Correctly handle 64-bit integers in SQL statements. (CVS 1408) (check-in: 34f03ba6a9 user: drh tags: trunk)
14:56
Change opcode names and comments to better describe the operation of the incrKey flag. OP_MoveTo becomes OP_MoveGe. (CVS 1407) (check-in: 8f249c45cb user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/expr.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.122 2004/05/18 10:06:25 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

char const *sqlite3AffinityString(char affinity){
  switch( affinity ){
    case SQLITE_AFF_INTEGER: return "i";







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.123 2004/05/19 20:41:03 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

char const *sqlite3AffinityString(char affinity){
  switch( affinity ){
    case SQLITE_AFF_INTEGER: return "i";
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue.  If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
*/
int sqlite3ExprIsInteger(Expr *p, int *pValue){
  switch( p->op ){
    case TK_INTEGER: {
      if( sqlite3FitsIn32Bits(p->token.z) ){
        *pValue = atoi(p->token.z);
        return 1;
      }
      break;
    }
    case TK_STRING: {
      const char *z = p->token.z;
      int n = p->token.n;
      if( n>0 && z[0]=='-' ){ z++; n--; }
      while( n>0 && *z && isdigit(*z) ){ z++; n--; }
      if( n==0 && sqlite3FitsIn32Bits(p->token.z) ){
        *pValue = atoi(p->token.z);
        return 1;
      }
      break;
    }
    case TK_UPLUS: {
      return sqlite3ExprIsInteger(p->pLeft, pValue);
    }







<
|









|
<







438
439
440
441
442
443
444

445
446
447
448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue.  If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
*/
int sqlite3ExprIsInteger(Expr *p, int *pValue){
  switch( p->op ){
    case TK_INTEGER: {

      if( sqlite3GetInt32(p->token.z, pValue) ){
        return 1;
      }
      break;
    }
    case TK_STRING: {
      const char *z = p->token.z;
      int n = p->token.n;
      if( n>0 && z[0]=='-' ){ z++; n--; }
      while( n>0 && *z && isdigit(*z) ){ z++; n--; }
      if( n==0 && sqlite3GetInt32(p->token.z, pValue) ){

        return 1;
      }
      break;
    }
    case TK_UPLUS: {
      return sqlite3ExprIsInteger(p->pLeft, pValue);
    }
1126
1127
1128
1129
1130
1131
1132













1133
1134
1135
1136
1137
1138
1139

    default:
      assert( p->op==TK_ABORT );  /* Can't Happen */
      break;
  }
  return SQLITE_SO_NUM;
}














/*
** Generate code into the current Vdbe to evaluate the given
** expression and leave the result on the top of stack.
*/
void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
  Vdbe *v = pParse->pVdbe;







>
>
>
>
>
>
>
>
>
>
>
>
>







1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150

    default:
      assert( p->op==TK_ABORT );  /* Can't Happen */
      break;
  }
  return SQLITE_SO_NUM;
}

/*
** Generate an instruction that will put the integer describe by
** text z[0..n-1] on the stack.
*/
static void codeInteger(Vdbe *v, const char *z, int n){
  int i;
  if( sqlite3GetInt32(z, &i) || (i=0, sqlite3FitsIn64Bits(z))!=0 ){
    sqlite3VdbeOp3(v, OP_Integer, i, 0, z, n);
  }else{
    sqlite3VdbeOp3(v, OP_Real, 0, 0, z, n);
  }
}

/*
** Generate code into the current Vdbe to evaluate the given
** expression and leave the result on the top of stack.
*/
void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
  Vdbe *v = pParse->pVdbe;
1158
1159
1160
1161
1162
1163
1164


1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188

1189
1190
1191
1192
1193
1194
1195
1196
    case TK_UMINUS:   op = OP_Negative; break;
    case TK_BITAND:   op = OP_BitAnd;   break;
    case TK_BITOR:    op = OP_BitOr;    break;
    case TK_BITNOT:   op = OP_BitNot;   break;
    case TK_LSHIFT:   op = OP_ShiftLeft;  break;
    case TK_RSHIFT:   op = OP_ShiftRight; break;
    case TK_REM:      op = OP_Remainder;  break;


    default: break;
  }
  switch( pExpr->op ){
    case TK_COLUMN: {
      if( pParse->useAgg ){
        sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
      }else if( pExpr->iColumn>=0 ){
        sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
      }else{
        sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
      }
      break;
    }
    case TK_STRING:
    case TK_FLOAT:
    case TK_INTEGER: {
      if( pExpr->op==TK_INTEGER && sqlite3FitsIn32Bits(pExpr->token.z) ){
        sqlite3VdbeAddOp(v, OP_Integer, atoi(pExpr->token.z), 0);
      }else if( pExpr->op==TK_FLOAT || pExpr->op==TK_INTEGER ){
        sqlite3VdbeAddOp(v, OP_Real, 0, 0);
      }else{
        sqlite3VdbeAddOp(v, OP_String, 0, 0);
      }
      assert( pExpr->token.z );

      sqlite3VdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);
      sqlite3VdbeDequoteP3(v, -1);
      break;
    }
    case TK_NULL: {
      sqlite3VdbeAddOp(v, OP_String, 0, 0);
      break;
    }







>
>













<
<

<
|
<
<
|
<
|
|
>
|







1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190


1191

1192


1193

1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
    case TK_UMINUS:   op = OP_Negative; break;
    case TK_BITAND:   op = OP_BitAnd;   break;
    case TK_BITOR:    op = OP_BitOr;    break;
    case TK_BITNOT:   op = OP_BitNot;   break;
    case TK_LSHIFT:   op = OP_ShiftLeft;  break;
    case TK_RSHIFT:   op = OP_ShiftRight; break;
    case TK_REM:      op = OP_Remainder;  break;
    case TK_FLOAT:    op = OP_Real;       break;
    case TK_STRING:   op = OP_String;     break;
    default: break;
  }
  switch( pExpr->op ){
    case TK_COLUMN: {
      if( pParse->useAgg ){
        sqlite3VdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
      }else if( pExpr->iColumn>=0 ){
        sqlite3VdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
      }else{
        sqlite3VdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
      }
      break;
    }


    case TK_INTEGER: {

      codeInteger(v, pExpr->token.z, pExpr->token.n);


      break;

    }
    case TK_FLOAT:
    case TK_STRING: {
      sqlite3VdbeOp3(v, op, 0, 0, pExpr->token.z, pExpr->token.n);
      sqlite3VdbeDequoteP3(v, -1);
      break;
    }
    case TK_NULL: {
      sqlite3VdbeAddOp(v, OP_String, 0, 0);
      break;
    }
1234
1235
1236
1237
1238
1239
1240

1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
    case TK_CONCAT: {
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      sqlite3VdbeAddOp(v, OP_Concat, 2, 0);
      break;
    }
    case TK_UMINUS: {

      assert( pExpr->pLeft );
      if( pExpr->pLeft->op==TK_FLOAT || pExpr->pLeft->op==TK_INTEGER ){
        Token *p = &pExpr->pLeft->token;
        char *z = sqliteMalloc( p->n + 2 );
        sprintf(z, "-%.*s", p->n, p->z);
        if( pExpr->pLeft->op==TK_INTEGER && sqlite3FitsIn32Bits(z) ){
          sqlite3VdbeAddOp(v, OP_Integer, atoi(z), 0);
        }else{
          sqlite3VdbeAddOp(v, OP_Real, 0, 0);
        }
        sqlite3VdbeChangeP3(v, -1, z, p->n+1);
        sqliteFree(z);
        break;
      }
      /* Fall through into TK_NOT */
    }
    case TK_BITNOT:
    case TK_NOT: {







>
|
|
|


|
|

|

<







1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259

1260
1261
1262
1263
1264
1265
1266
    case TK_CONCAT: {
      sqlite3ExprCode(pParse, pExpr->pLeft);
      sqlite3ExprCode(pParse, pExpr->pRight);
      sqlite3VdbeAddOp(v, OP_Concat, 2, 0);
      break;
    }
    case TK_UMINUS: {
      Expr *pLeft = pExpr->pLeft;
      assert( pLeft );
      if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
        Token *p = &pLeft->token;
        char *z = sqliteMalloc( p->n + 2 );
        sprintf(z, "-%.*s", p->n, p->z);
        if( pLeft->op==TK_FLOAT ){
          sqlite3VdbeOp3(v, OP_Real, 0, 0, z, p->n+1);
        }else{
          codeInteger(v, z, p->n+1);
        }

        sqliteFree(z);
        break;
      }
      /* Fall through into TK_NOT */
    }
    case TK_BITNOT:
    case TK_NOT: {
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
      getFunctionName(pExpr, &zId, &nId);
      pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, 0);
      assert( pDef!=0 );
      nExpr = sqlite3ExprCodeExprList(pParse, pList, pDef->includeTypes);
      /* FIX ME: The following is a temporary hack. */
      if( 0==sqlite3StrNICmp(zId, "classof", nId) ){
        assert( nExpr==1 );
        sqlite3VdbeOp3(v, OP_Class, nExpr, 0, 0, 0);
      }else{
        sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER);
      }
      break;
    }
    case TK_SELECT: {
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);







|







1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
      getFunctionName(pExpr, &zId, &nId);
      pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, 0);
      assert( pDef!=0 );
      nExpr = sqlite3ExprCodeExprList(pParse, pList, pDef->includeTypes);
      /* FIX ME: The following is a temporary hack. */
      if( 0==sqlite3StrNICmp(zId, "classof", nId) ){
        assert( nExpr==1 );
        sqlite3VdbeAddOp(v, OP_Class, nExpr, 0);
      }else{
        sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER);
      }
      break;
    }
    case TK_SELECT: {
      sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
    p->nArg = nArg;
    p->pNext = pFirst;
    p->dataType = pFirst ? pFirst->dataType : SQLITE_NUMERIC;
    sqlite3HashInsert(&db->aFunc, zName, nName, (void*)p);
  }
  return p;
}










<
<
<
1804
1805
1806
1807
1808
1809
1810



    p->nArg = nArg;
    p->pNext = pFirst;
    p->dataType = pFirst ? pFirst->dataType : SQLITE_NUMERIC;
    sqlite3HashInsert(&db->aFunc, zName, nName, (void*)p);
  }
  return p;
}



Changes to src/sqliteInt.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.237 2004/05/18 23:21:36 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
** 2001 September 15
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.238 2004/05/19 20:41:03 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
474
475
476
477
478
479
480

481
482
483
484
485
486
487
**
** If CollSeq.xCmp is NULL, it means that the collating sequence is
** undefined.  Indices built on an undefined collating sequence may
** not be read or written.
*/
struct CollSeq {
  char *zName;         /* Name of the collating sequence */

  void *pUser;         /* First argument to xCmp() */
  int (*xCmp)(void*,int,const void*,int,const void*); /* Comparison function */
};

/*
** The allowed sort orders.
**







>







474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
**
** If CollSeq.xCmp is NULL, it means that the collating sequence is
** undefined.  Indices built on an undefined collating sequence may
** not be read or written.
*/
struct CollSeq {
  char *zName;         /* Name of the collating sequence */
  u8 reverseOrder;     /* Compare in reverse order.  Used by OP_Sort only */
  void *pUser;         /* First argument to xCmp() */
  int (*xCmp)(void*,int,const void*,int,const void*); /* Comparison function */
};

/*
** The allowed sort orders.
**
1308
1309
1310
1311
1312
1313
1314
1315
1316

1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332

int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);
int sqlite3FixExprList(DbFixer*, ExprList*);
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
double sqlite3AtoF(const char *z, const char **);
char *sqlite3_snprintf(int,char*,const char*,...);
int sqlite3FitsIn32Bits(const char *);


unsigned char *sqlite3utf16to8(const void *pData, int N);
void *sqlite3utf8to16be(const unsigned char *pIn, int N);
void *sqlite3utf8to16le(const unsigned char *pIn, int N);
void sqlite3utf16to16le(void *pData, int N);
void sqlite3utf16to16be(void *pData, int N);
int sqlite3PutVarint(unsigned char *, u64);
int sqlite3GetVarint(const unsigned char *, u64 *);
int sqlite3GetVarint32(const unsigned char *, u32 *);
int sqlite3VarintLen(u64 v);
char sqlite3AffinityType(const char *, int);
void sqlite3IndexAffinityStr(Vdbe *, Index *);
void sqlite3TableAffinityStr(Vdbe *, Table *);
char sqlite3CompareAffinity(Expr *pExpr, char aff2);
char const *sqlite3AffinityString(char affinity);
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
char sqlite3ExprAffinity(Expr *pExpr);








|
|
>
















>
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
int sqlite3FixSrcList(DbFixer*, SrcList*);
int sqlite3FixSelect(DbFixer*, Select*);
int sqlite3FixExpr(DbFixer*, Expr*);
int sqlite3FixExprList(DbFixer*, ExprList*);
int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
double sqlite3AtoF(const char *z, const char **);
char *sqlite3_snprintf(int,char*,const char*,...);
int sqlite3GetInt32(const char *, int*);
int sqlite3GetInt64(const char *, i64*);
int sqlite3FitsIn64Bits(const char *);
unsigned char *sqlite3utf16to8(const void *pData, int N);
void *sqlite3utf8to16be(const unsigned char *pIn, int N);
void *sqlite3utf8to16le(const unsigned char *pIn, int N);
void sqlite3utf16to16le(void *pData, int N);
void sqlite3utf16to16be(void *pData, int N);
int sqlite3PutVarint(unsigned char *, u64);
int sqlite3GetVarint(const unsigned char *, u64 *);
int sqlite3GetVarint32(const unsigned char *, u32 *);
int sqlite3VarintLen(u64 v);
char sqlite3AffinityType(const char *, int);
void sqlite3IndexAffinityStr(Vdbe *, Index *);
void sqlite3TableAffinityStr(Vdbe *, Table *);
char sqlite3CompareAffinity(Expr *pExpr, char aff2);
char const *sqlite3AffinityString(char affinity);
int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
char sqlite3ExprAffinity(Expr *pExpr);
int sqlite3atoi64(const char*, i64*);
Changes to src/util.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.85 2004/05/19 10:34:57 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.86 2004/05/19 20:41:03 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
605
606
607
608
609
610
611
































612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629










































630
631
632
633
634
635
636
    }else{
      v1 *= scale;
    }
  }
  if( pzEnd ) *pzEnd = z;
  return sign<0 ? -v1 : v1;
}

































/*
** The string zNum represents an integer.  There might be some other
** information following the integer too, but that part is ignored.
** If the integer that the prefix of zNum represents will fit in a
** 32-bit signed integer, return TRUE.  Otherwise return FALSE.
**
** This routine returns FALSE for the string -2147483648 even that
** that number will, in theory fit in a 32-bit integer.  But positive
** 2147483648 will not fit in 32 bits.  So it seems safer to return
** false.
*/
int sqlite3FitsIn32Bits(const char *zNum){
  int i, c;
  if( *zNum=='-' || *zNum=='+' ) zNum++;
  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
  return i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0);
}











































/* This comparison routine is what we use for comparison operations
** between numeric values in an SQL expression.  "Numeric" is a little
** bit misleading here.  What we mean is that the strings have a
** type of "numeric" from the point of view of SQL.  The strings
** do not necessarily contain numbers.  They could contain text.
**







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












|





>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
    }else{
      v1 *= scale;
    }
  }
  if( pzEnd ) *pzEnd = z;
  return sign<0 ? -v1 : v1;
}

/*
** Return TRUE if zNum is a 64-bit signed integer and write
** the value of the integer into *pNum.  If zNum is not an integer
** or is an integer that is too large to be expressed with 64 bits,
** then return false.  If n>0 and the integer is string is not
** exactly n bytes long, return false.
**
** When this routine was originally written it dealt with only
** 32-bit numbers.  At that time, it was much faster than the
** atoi() library routine in RedHat 7.2.
*/
int sqlite3atoi64(const char *zNum, i64 *pNum){
  i64 v = 0;
  int neg;
  int i, c;
  if( *zNum=='-' ){
    neg = 1;
    zNum++;
  }else if( *zNum=='+' ){
    neg = 0;
    zNum++;
  }else{
    neg = 0;
  }
  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
    v = v*10 + c - '0';
  }
  *pNum = neg ? -v : v;
  return c==0 && i>0 && 
      (i<19 || (i==19 && memcmp(zNum,"9223372036854775807",19)<=0));
}

/*
** The string zNum represents an integer.  There might be some other
** information following the integer too, but that part is ignored.
** If the integer that the prefix of zNum represents will fit in a
** 32-bit signed integer, return TRUE.  Otherwise return FALSE.
**
** This routine returns FALSE for the string -2147483648 even that
** that number will, in theory fit in a 32-bit integer.  But positive
** 2147483648 will not fit in 32 bits.  So it seems safer to return
** false.
*/
static int sqlite3FitsIn32Bits(const char *zNum){
  int i, c;
  if( *zNum=='-' || *zNum=='+' ) zNum++;
  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
  return i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0);
}

/*
** If zNum represents an integer that will fit in 32-bits, then set
** *pValue to that integer and return true.  Otherwise return false.
*/
int sqlite3GetInt32(const char *zNum, int *pValue){
  if( sqlite3FitsIn32Bits(zNum) ){
    *pValue = atoi(zNum);
    return 1;
  }
  return 0;
}

/*
** The string zNum represents an integer.  There might be some other
** information following the integer too, but that part is ignored.
** If the integer that the prefix of zNum represents will fit in a
** 64-bit signed integer, return TRUE.  Otherwise return FALSE.
**
** This routine returns FALSE for the string -9223372036854775808 even that
** that number will, in theory fit in a 64-bit integer.  Positive
** 9223373036854775808 will not fit in 64 bits.  So it seems safer to return
** false.
*/
int sqlite3FitsIn64Bits(const char *zNum){
  int i, c;
  if( *zNum=='-' || *zNum=='+' ) zNum++;
  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
  return i<19 || (i==19 && memcmp(zNum,"9223372036854775807",19)<=0);
}

/*
** If zNum represents an integer that will fit in 64-bits, then set
** *pValue to that integer and return true.  Otherwise return false.
*/
int sqlite3GetInt64(const char *zNum, i64 *pValue){
  if( sqlite3FitsIn64Bits(zNum) ){
    sqlite3atoi64(zNum, pValue);
    return 1;
  }
  return 0;
}

/* This comparison routine is what we use for comparison operations
** between numeric values in an SQL expression.  "Numeric" is a little
** bit misleading here.  What we mean is that the strings have a
** type of "numeric" from the point of view of SQL.  The strings
** do not necessarily contain numbers.  They could contain text.
**
1176
1177
1178
1179
1180
1181
1182
1183
  int i = 0;
  do{
    i++;
    v >>= 7;
  }while( v!=0 && i<9 );
  return i;
}








<
1250
1251
1252
1253
1254
1255
1256

  int i = 0;
  do{
    i++;
    v >>= 7;
  }while( v!=0 && i<9 );
  return i;
}

Changes to src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** 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.304 2004/05/19 14:56:57 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** 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.305 2004/05/19 20:41:03 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
    N--;
    Release(pTos);
    pTos--;
  }
  *ppTos = pTos;
}

/*
** Return TRUE if zNum is a 32-bit signed integer and write
** the value of the integer into *pNum.  If zNum is not an integer
** or is an integer that is too large to be expressed with just 32
** bits, then return false.
**
** Under Linux (RedHat 7.2) this routine is much faster than atoi()
** for converting strings into integers.
*/
static int toInt(const char *zNum, i64 *pNum){
  i64 v = 0;
  int neg;
  int i, c;
  if( *zNum=='-' ){
    neg = 1;
    zNum++;
  }else if( *zNum=='+' ){
    neg = 0;
    zNum++;
  }else{
    neg = 0;
  }
  for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
    v = v*10 + c - '0';
  }
  *pNum = neg ? -v : v;
  return c==0 && i>0 && 
      (i<10 || (i==19 && memcmp(zNum,"9223372036854775807",19)<=0));
}

/*
** Convert the given stack entity into a integer if it isn't one
** already.
**
** Any prior string or real representation is invalidated.  
** NULLs are converted into 0.
*/
#define Integerify(P) if(((P)->flags&MEM_Int)==0){ hardIntegerify(P); }
static void hardIntegerify(Mem *pStack){
  if( pStack->flags & MEM_Real ){
    pStack->i = (int)pStack->r;
    Release(pStack);
  }else if( pStack->flags & MEM_Str ){
    toInt(pStack->z, &pStack->i);
    Release(pStack);
  }else{
    pStack->i = 0;
  }
  pStack->flags = MEM_Int;
}








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<













|







272
273
274
275
276
277
278






























279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
    N--;
    Release(pTos);
    pTos--;
  }
  *ppTos = pTos;
}































/*
** Convert the given stack entity into a integer if it isn't one
** already.
**
** Any prior string or real representation is invalidated.  
** NULLs are converted into 0.
*/
#define Integerify(P) if(((P)->flags&MEM_Int)==0){ hardIntegerify(P); }
static void hardIntegerify(Mem *pStack){
  if( pStack->flags & MEM_Real ){
    pStack->i = (int)pStack->r;
    Release(pStack);
  }else if( pStack->flags & MEM_Str ){
    sqlite3atoi64(pStack->z, &pStack->i);
    Release(pStack);
  }else{
    pStack->i = 0;
  }
  pStack->flags = MEM_Int;
}

788
789
790
791
792
793
794

795
796
797
798
799
800
801
802
803



804
805
806
807
808
809
810
  }
}

/* Opcode: Integer P1 * P3
**
** The integer value P1 is pushed onto the stack.  If P3 is not zero
** then it is assumed to be a string representation of the same integer.

*/
case OP_Integer: {
  pTos++;
  pTos->i = pOp->p1;
  pTos->flags = MEM_Int;
  if( pOp->p3 ){
    pTos->z = pOp->p3;
    pTos->flags |= MEM_Str | MEM_Static;
    pTos->n = strlen(pOp->p3)+1;



  }
  break;
}

/* Opcode: String * * P3
**
** The string value P3 is pushed onto the stack.  If P3==0 then a







>









>
>
>







758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
  }
}

/* Opcode: Integer P1 * P3
**
** The integer value P1 is pushed onto the stack.  If P3 is not zero
** then it is assumed to be a string representation of the same integer.
** If P1 is zero and P3 is not zero, then the value is derived from P3.
*/
case OP_Integer: {
  pTos++;
  pTos->i = pOp->p1;
  pTos->flags = MEM_Int;
  if( pOp->p3 ){
    pTos->z = pOp->p3;
    pTos->flags |= MEM_Str | MEM_Static;
    pTos->n = strlen(pOp->p3)+1;
    if( pTos->i==0 ){
      sqlite3GetInt64(pTos->z, &pTos->i);
    }
  }
  break;
}

/* Opcode: String * * P3
**
** The string value P3 is pushed onto the stack.  If P3==0 then a
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
    double r = (double)i;
    if( r!=pTos->r ){
      goto mismatch;
    }
    pTos->i = i;
  }else if( pTos->flags & MEM_Str ){
    i64 v;
    if( !toInt(pTos->z, &v) ){
      double r;
      if( !sqlite3IsNumber(pTos->z, 0) ){
        goto mismatch;
      }
      Realify(pTos);
      v = (int)pTos->r;
      r = (double)v;







|







1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
    double r = (double)i;
    if( r!=pTos->r ){
      goto mismatch;
    }
    pTos->i = i;
  }else if( pTos->flags & MEM_Str ){
    i64 v;
    if( !sqlite3atoi64(pTos->z, &v) ){
      double r;
      if( !sqlite3IsNumber(pTos->z, 0) ){
        goto mismatch;
      }
      Realify(pTos);
      v = (int)pTos->r;
      r = (double)v;
3330
3331
3332
3333
3334
3335
3336

3337

3338
3339
3340
3341
3342
3343
3344
3345
3346
**
** This opcode also instructs the cursor that the keys used will be
** serialized in the record format usually used for table data, not
** the usual index key format.
*/
case OP_KeyAsData: {
  int i = pOp->p1;

  assert( i>=0 && i<p->nCursor );

  p->apCsr[i]->keyAsData = pOp->p2;
  sqlite3BtreeSetCompare(p->apCsr[i]->pCursor, sqlite3VdbeRowCompare, p->apCsr[i]);
  break;
}

/* Opcode: RowData P1 * *
**
** Push onto the stack the complete row data for cursor P1.
** There is no interpretation of the data.  It is just copied







>

>
|
|







3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
**
** This opcode also instructs the cursor that the keys used will be
** serialized in the record format usually used for table data, not
** the usual index key format.
*/
case OP_KeyAsData: {
  int i = pOp->p1;
  Cursor *pC;
  assert( i>=0 && i<p->nCursor );
  pC = p->apCsr[i];
  pC->keyAsData = pOp->p2;
  sqlite3BtreeSetCompare(pC->pCursor, sqlite3VdbeRowCompare, pC);
  break;
}

/* Opcode: RowData P1 * *
**
** Push onto the stack the complete row data for cursor P1.
** There is no interpretation of the data.  It is just copied
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
  pTos++;
  pSet = &p->aSet[iSet];
  nRoot = sqliteHashCount(&pSet->hash);
  aRoot = sqliteMallocRaw( sizeof(int)*(nRoot+1) );
  if( aRoot==0 ) goto no_mem;
  for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){
    i64 root64;
    toInt((char*)sqliteHashKey(i), &root64);
    aRoot[j] = root64;
  }
  aRoot[j] = 0;
  sqlite3HashClear(&pSet->hash);
  pSet->prev = 0;
  z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
  if( z==0 || z[0]==0 ){







|







4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
  pTos++;
  pSet = &p->aSet[iSet];
  nRoot = sqliteHashCount(&pSet->hash);
  aRoot = sqliteMallocRaw( sizeof(int)*(nRoot+1) );
  if( aRoot==0 ) goto no_mem;
  for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){
    i64 root64;
    sqlite3atoi64((char*)sqliteHashKey(i), &root64);
    aRoot[j] = root64;
  }
  aRoot[j] = 0;
  sqlite3HashClear(&pSet->hash);
  pSet->prev = 0;
  z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
  if( z==0 || z[0]==0 ){
Changes to src/vdbeaux.c.
1383
1384
1385
1386
1387
1388
1389

1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409

1410
1411
1412
1413
1414
1415
1416
  }

  /* If one value is a number and the other is not, the number is less.
  ** If both are numbers, compare as reals if one is a real, or as integers
  ** if both values are integers.
  */
  if( combined_flags&(MEM_Int|MEM_Real) ){

    if( !(pMem1->flags&(MEM_Int|MEM_Real)) ){
      return 1;
    }
    if( !(pMem2->flags&(MEM_Int|MEM_Real)) ){
      return -1;
    }

    if( combined_flags&MEM_Real ){
      if( pMem1->flags&MEM_Int ){
        pMem1->r = pMem1->i;
      }
      if( pMem2->flags&MEM_Int ){
        pMem2->r = pMem2->i;
      }
      if( pMem1->r < pMem2->r ) return -1;
      if( pMem1->r > pMem2->r ) return 1;
      return 0;
    }

    return (pMem1->i - pMem2->i);

  }

  rc = (pMem2->flags&MEM_Null) - (pMem1->flags&MEM_Null);
  if( rc ){
    return rc;
  }








>






<











<
|
>







1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396

1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407

1408
1409
1410
1411
1412
1413
1414
1415
1416
  }

  /* If one value is a number and the other is not, the number is less.
  ** If both are numbers, compare as reals if one is a real, or as integers
  ** if both values are integers.
  */
  if( combined_flags&(MEM_Int|MEM_Real) ){
    i64 diff;
    if( !(pMem1->flags&(MEM_Int|MEM_Real)) ){
      return 1;
    }
    if( !(pMem2->flags&(MEM_Int|MEM_Real)) ){
      return -1;
    }

    if( combined_flags&MEM_Real ){
      if( pMem1->flags&MEM_Int ){
        pMem1->r = pMem1->i;
      }
      if( pMem2->flags&MEM_Int ){
        pMem2->r = pMem2->i;
      }
      if( pMem1->r < pMem2->r ) return -1;
      if( pMem1->r > pMem2->r ) return 1;
      return 0;
    }

    diff = pMem1->i - pMem2->i;
    return diff<0 ? -1 : diff==0 ? 0 : +1;
  }

  rc = (pMem2->flags&MEM_Null) - (pMem1->flags&MEM_Null);
  if( rc ){
    return rc;
  }

1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
      return rc;
    }
  }
 
  len = nCellKey-2;
  while( pCellKey[len] && --len );

#if 0
  if( ignorerowid ){
    nKey--;
    while( pKey[nKey] && --nKey );
  }
#endif
  *res = sqlite3VdbeKeyCompare(pC, len, pCellKey, nKey, pKey);
  
  if( freeCellKey ){
    sqliteFree(pCellKey);
  }
  return SQLITE_OK;
}







<
<
<
<
<
<







1663
1664
1665
1666
1667
1668
1669






1670
1671
1672
1673
1674
1675
1676
      return rc;
    }
  }
 
  len = nCellKey-2;
  while( pCellKey[len] && --len );







  *res = sqlite3VdbeKeyCompare(pC, len, pCellKey, nKey, pKey);
  
  if( freeCellKey ){
    sqliteFree(pCellKey);
  }
  return SQLITE_OK;
}
Changes to src/where.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.
**
** $Id: where.c,v 1.98 2004/05/19 14:56:57 drh Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.
**
** $Id: where.c,v 1.99 2004/05/19 20:41:04 drh Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
      sqlite3VdbeAddOp(v, OP_NotExists, iCur, brk);
      pLevel->op = OP_Noop;
    }else if( pIdx!=0 && pLevel->score>0 && pLevel->score%4==0 ){
      /* Case 2:  There is an index and all terms of the WHERE clause that
      **          refer to the index use the "==" or "IN" operators.
      */
      int start;
      int testOp;
      int nColumn = (pLevel->score+4)/8;
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);

      /* For each column of the index, find the term of the WHERE clause that
      ** constraints that column.  If the WHERE clause term is X=expr, then
      ** evaluation expr and leave the result on the stack */
      for(j=0; j<nColumn; j++){







<







742
743
744
745
746
747
748

749
750
751
752
753
754
755
      sqlite3VdbeAddOp(v, OP_NotExists, iCur, brk);
      pLevel->op = OP_Noop;
    }else if( pIdx!=0 && pLevel->score>0 && pLevel->score%4==0 ){
      /* Case 2:  There is an index and all terms of the WHERE clause that
      **          refer to the index use the "==" or "IN" operators.
      */
      int start;

      int nColumn = (pLevel->score+4)/8;
      brk = pLevel->brk = sqlite3VdbeMakeLabel(v);

      /* For each column of the index, find the term of the WHERE clause that
      ** constraints that column.  If the WHERE clause term is X=expr, then
      ** evaluation expr and leave the result on the stack */
      for(j=0; j<nColumn; j++){
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
        start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeAddOp(v, OP_IdxLT, pLevel->iCur, brk);
        pLevel->op = OP_Prev;
      }else{
        /* Scan in the forward order */
        sqlite3VdbeAddOp(v, OP_MoveGe, pLevel->iCur, brk);
        start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        if( nColumn==pIdx->nColumn || 0 ){
          sqlite3VdbeAddOp(v, OP_IdxGT, pLevel->iCur, brk);
        }else{
          sqlite3VdbeOp3(v, OP_IdxGE, pLevel->iCur, brk, "+", P3_STATIC);
        }
        pLevel->op = OP_Next;
      }
      sqlite3VdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
      sqlite3VdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
      sqlite3VdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
      if( i==pTabList->nSrc-1 && pushKey ){
        haveKey = 1;







<
<
<
|
<







819
820
821
822
823
824
825



826

827
828
829
830
831
832
833
        start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
        sqlite3VdbeAddOp(v, OP_IdxLT, pLevel->iCur, brk);
        pLevel->op = OP_Prev;
      }else{
        /* Scan in the forward order */
        sqlite3VdbeAddOp(v, OP_MoveGe, pLevel->iCur, brk);
        start = sqlite3VdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);



        sqlite3VdbeOp3(v, OP_IdxGE, pLevel->iCur, brk, "+", P3_STATIC);

        pLevel->op = OP_Next;
      }
      sqlite3VdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
      sqlite3VdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
      sqlite3VdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
      if( i==pTabList->nSrc-1 && pushKey ){
        haveKey = 1;
Changes to test/misc1.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc1.test,v 1.23 2003/08/05 13:13:39 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Test the creation and use of tables that have a large number
# of columns.
#







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for miscellanous features that were
# left out of other test files.
#
# $Id: misc1.test,v 1.24 2004/05/19 20:41:04 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Test the creation and use of tables that have a large number
# of columns.
#
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
execsql {
  DROP TABLE t1;
  DROP TABLE t2;
  DROP TABLE t3;
  DROP TABLE t4;
}

# If an integer is too big to be represented as a 32-bit machine integer,
# then treat it as a string.
#
do_test misc1-9.1 {
  catchsql {
    CREATE TABLE t1(a unique not null, b unique not null);
    INSERT INTO t1 VALUES('a',12345678901234567890);
    INSERT INTO t1 VALUES('b',12345678911234567890);
    INSERT INTO t1 VALUES('c',12345678921234567890);
    SELECT * FROM t1;
  }
} {0 {a 12345678901234567890 b 12345678911234567890 c 12345678921234567890}}

# A WHERE clause is not allowed to contain more than 99 terms.  Check to
# make sure this limit is enforced.
#
do_test misc1-10.0 {
  execsql {SELECT count(*) FROM manycol}
} {9}







|
<




|
|
|


|







248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
execsql {
  DROP TABLE t1;
  DROP TABLE t2;
  DROP TABLE t3;
  DROP TABLE t4;
}

# 64-bit integers are represented exactly.

#
do_test misc1-9.1 {
  catchsql {
    CREATE TABLE t1(a unique not null, b unique not null);
    INSERT INTO t1 VALUES('a',1234567890123456789);
    INSERT INTO t1 VALUES('b',1234567891123456789);
    INSERT INTO t1 VALUES('c',1234567892123456789);
    SELECT * FROM t1;
  }
} {0 {a 1234567890123456789 b 1234567891123456789 c 1234567892123456789}}

# A WHERE clause is not allowed to contain more than 99 terms.  Check to
# make sure this limit is enforced.
#
do_test misc1-10.0 {
  execsql {SELECT count(*) FROM manycol}
} {9}
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

# Make sure string comparisons really do compare strings in format4+.
# Similar tests in the format3.test file show that for format3 and earlier
# all comparisions where numeric if either operand looked like a number.
#
do_test misc1-12.1 {
  execsql {SELECT '0'=='0.0'}
} {0}
do_test misc1-12.2 {
  execsql {SELECT '0'==0.0}
} {1}
do_test misc1-12.3 {
  execsql {SELECT '12345678901234567890'=='12345678901234567891'}
} {0}
do_test misc1-12.4 {







|







325
326
327
328
329
330
331
332
333
334
335
336
337
338
339

# Make sure string comparisons really do compare strings in format4+.
# Similar tests in the format3.test file show that for format3 and earlier
# all comparisions where numeric if either operand looked like a number.
#
do_test misc1-12.1 {
  execsql {SELECT '0'=='0.0'}
} {1}
do_test misc1-12.2 {
  execsql {SELECT '0'==0.0}
} {1}
do_test misc1-12.3 {
  execsql {SELECT '12345678901234567890'=='12345678901234567891'}
} {0}
do_test misc1-12.4 {
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
    CREATE TABLE t8(x TEXT COLLATE numeric, y INTEGER COLLATE text, z);
    INSERT INTO t8 VALUES(0,0,1);
    INSERT INTO t8 VALUES(0.0,0,2);
    INSERT INTO t8 VALUES(0,0.0,3);
    INSERT INTO t8 VALUES(0.0,0.0,4);
    SELECT DISTINCT x, y FROM t8 ORDER BY z;
  }
} {0 0 0 0.0}
do_test misc1-12.12 {
  execsql {
    SELECT min(z), max(z), count(z) FROM t8 GROUP BY x ORDER BY 1;
  }
} {1 4 4}
do_test misc1-12.13 {
  execsql {
    SELECT min(z), max(z), count(z) FROM t8 GROUP BY y ORDER BY 1;
  }
} {1 2 2 3 4 2}

# There was a problem with realloc() in the OP_MemStore operation of
# the VDBE.  A buffer was being reallocated but some pointers into 
# the old copy of the buffer were not being moved over to the new copy.
# The following code tests for the problem.
#
do_test misc1-13.1 {







|




|




|







390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
    CREATE TABLE t8(x TEXT COLLATE numeric, y INTEGER COLLATE text, z);
    INSERT INTO t8 VALUES(0,0,1);
    INSERT INTO t8 VALUES(0.0,0,2);
    INSERT INTO t8 VALUES(0,0.0,3);
    INSERT INTO t8 VALUES(0.0,0.0,4);
    SELECT DISTINCT x, y FROM t8 ORDER BY z;
  }
} {0 0 0.0 0}
do_test misc1-12.12 {
  execsql {
    SELECT min(z), max(z), count(z) FROM t8 GROUP BY x ORDER BY 1;
  }
} {1 3 2 2 4 2}
do_test misc1-12.13 {
  execsql {
    SELECT min(z), max(z), count(z) FROM t8 GROUP BY y ORDER BY 1;
  }
} {1 4 4}

# There was a problem with realloc() in the OP_MemStore operation of
# the VDBE.  A buffer was being reallocated but some pointers into 
# the old copy of the buffer were not being moved over to the new copy.
# The following code tests for the problem.
#
do_test misc1-13.1 {
Changes to test/quick.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: quick.test,v 1.13 2004/05/19 13:13:08 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {}
set ISQUICK 1













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file runs all tests.
#
# $Id: quick.test,v 1.14 2004/05/19 20:41:04 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {}
set ISQUICK 1

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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 as a result of the partial manifest types
# implementation.
lappend EXCLUDE misc1.test 
lappend EXCLUDE capi2.test 


if {[sqlite -has-codec]} {
  lappend EXCLUDE \
    attach.test \
    attach2.test \







<







39
40
41
42
43
44
45

46
47
48
49
50
51
52
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 as a result of the partial manifest types
# implementation.

lappend EXCLUDE capi2.test 


if {[sqlite -has-codec]} {
  lappend EXCLUDE \
    attach.test \
    attach2.test \