/ Check-in [fe80aa58]
Login

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

Overview
Comment:Testing coverage enhancements. (CVS 5358)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fe80aa58a4ac12db5a92d25d28165f5159f04533
User & Date: drh 2008-07-08 00:06:50
Context
2008-07-08
02:12
Add tests to verify correct behavior when mutex initialization fails. (CVS 5359) check-in: 65875005 user: drh tags: trunk
00:06
Testing coverage enhancements. (CVS 5358) check-in: fe80aa58 user: drh tags: trunk
2008-07-07
19:52
Make check-in (5356) compatible with builds that do not enable memory management. Remove unnecessary code from main.c. Add out-of-memory tests for sqlite3_complete16(). (CVS 5357) check-in: 28f8b6bf user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
234
235
236
237
238
239
240

241
242
243
244
245
246
247
...
249
250
251
252
253
254
255
256

257
258
259
260
261
262
263
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.485 2008/06/15 02:51:47 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
** Not everything is nestable.  This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use
** care if you decide to try to use this routine for some other purposes.
*/
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;

# define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))
  char saveBuf[SAVE_SZ];

  if( pParse->nErr ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(pParse->db, zFormat, ap);
................................................................................
  if( zSql==0 ){
    pParse->db->mallocFailed = 1;
    return;   /* A malloc must have failed */
  }
  pParse->nested++;
  memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
  memset(&pParse->nVar, 0, SAVE_SZ);
  sqlite3RunParser(pParse, zSql, 0);

  sqlite3_free(zSql);
  memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
  pParse->nested--;
}

/*
** Locate the in-memory structure that describes a particular database







|







 







>







 







|
>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
...
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.486 2008/07/08 00:06:50 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
** Not everything is nestable.  This facility is designed to permit
** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER.  Use
** care if you decide to try to use this routine for some other purposes.
*/
void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
  va_list ap;
  char *zSql;
  char *zErrMsg = 0;
# define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))
  char saveBuf[SAVE_SZ];

  if( pParse->nErr ) return;
  assert( pParse->nested<10 );  /* Nesting should only be of limited depth */
  va_start(ap, zFormat);
  zSql = sqlite3VMPrintf(pParse->db, zFormat, ap);
................................................................................
  if( zSql==0 ){
    pParse->db->mallocFailed = 1;
    return;   /* A malloc must have failed */
  }
  pParse->nested++;
  memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
  memset(&pParse->nVar, 0, SAVE_SZ);
  sqlite3RunParser(pParse, zSql, &zErrMsg);
  sqlite3_free(zErrMsg);
  sqlite3_free(zSql);
  memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
  pParse->nested--;
}

/*
** Locate the in-memory structure that describes a particular database

Changes to src/test_mutex.c.

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

22
23

24
25
26
27
28

29
30


31
32
33
34
35

36
37
38
39

40
41
42
43





44


45


46
47



48


49
50
51



52
53
54
55

56
57
58
59
60
61
62
..
65
66
67
68
69
70
71



72

73
74
75
76
77
78



79

80
81
82
83



84

85
86
87
88


89

90
91
92
93
94
95
96
...
297
298
299
300
301
302
303



304
305
**
**    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.
**
*************************************************************************
** 
** $Id: test_mutex.c,v 1.4 2008/06/22 12:37:58 drh Exp $
*/

#include "tcl.h"
#include "sqlite3.h"
#include <stdlib.h>
#include <assert.h>
#include <string.h>


const char *sqlite3TestErrorName(int);


struct sqlite3_mutex {
  sqlite3_mutex *pReal;
  int eType;
};


static struct test_mutex_globals {
  int isInstalled;


  sqlite3_mutex_methods m;          /* Interface to "real" mutex system */
  int aCounter[8];                  /* Number of grabs of each type of mutex */
  sqlite3_mutex aStatic[6];         /* The six static mutexes */
} g;


static int counterMutexHeld(sqlite3_mutex *p){
  return g.m.xMutexHeld(p->pReal);
}


static int counterMutexNotheld(sqlite3_mutex *p){
  return g.m.xMutexNotheld(p->pReal);
}






static int counterMutexInit(void){ 


  return g.m.xMutexInit();


}




static int counterMutexEnd(void){ 


  return g.m.xMutexEnd();
}




static sqlite3_mutex *counterMutexAlloc(int eType){
  sqlite3_mutex *pReal;
  sqlite3_mutex *pRet = 0;


  assert(eType<8 && eType>=0);

  pReal = g.m.xMutexAlloc(eType);
  if( !pReal ) return 0;

  if( eType==0 || eType==1 ){
    pRet = (sqlite3_mutex *)malloc(sizeof(sqlite3_mutex));
................................................................................
  }

  pRet->eType = eType;
  pRet->pReal = pReal;
  return pRet;
}




static void counterMutexFree(sqlite3_mutex *p){

  g.m.xMutexFree(p->pReal);
  if( p->eType==0 || p->eType==1 ){
    free(p);
  }
}




static void counterMutexEnter(sqlite3_mutex *p){

  g.aCounter[p->eType]++;
  g.m.xMutexEnter(p->pReal);
}




static int counterMutexTry(sqlite3_mutex *p){

  g.aCounter[p->eType]++;
  return g.m.xMutexTry(p->pReal);
}



static void counterMutexLeave(sqlite3_mutex *p){

  g.m.xMutexLeave(p->pReal);
}

/*
** sqlite3_shutdown
*/
static int test_shutdown(
................................................................................
    { "clear_mutex_counters",    (Tcl_ObjCmdProc*)test_clear_mutex_counters },
  };
  int i;
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  memset(&g, 0, sizeof(g));



  return SQLITE_OK;
}







|








>


>





>

|
>
>
|
|
|


>




>




>
>
>
>
>

>
>
|
>
>


>
>
>

>
>



>
>
>




>







 







>
>
>

>






>
>
>

>




>
>
>

>




>
>

>







 







>
>
>


6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
..
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
337
338
339
340
341
342
343
344
345
346
347
348
**
**    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.
**
*************************************************************************
** 
** $Id: test_mutex.c,v 1.5 2008/07/08 00:06:50 drh Exp $
*/

#include "tcl.h"
#include "sqlite3.h"
#include <stdlib.h>
#include <assert.h>
#include <string.h>

/* defined in test1.c */
const char *sqlite3TestErrorName(int);

/* A countable mutex */
struct sqlite3_mutex {
  sqlite3_mutex *pReal;
  int eType;
};

/* State variables */
static struct test_mutex_globals {
  int isInstalled;              /* True if installed */
  int disableInit;              /* True to cause sqlite3_initalize() to fail */
  int isInit;                   /* True if initialized */
  sqlite3_mutex_methods m;      /* Interface to "real" mutex system */
  int aCounter[8];              /* Number of grabs of each type of mutex */
  sqlite3_mutex aStatic[6];     /* The six static mutexes */
} g;

/* Return true if the countable mutex is currently held */
static int counterMutexHeld(sqlite3_mutex *p){
  return g.m.xMutexHeld(p->pReal);
}

/* Return true if the countable mutex is not currently held */
static int counterMutexNotheld(sqlite3_mutex *p){
  return g.m.xMutexNotheld(p->pReal);
}

/* Initialize the countable mutex interface
** Or, if g.disableInit is non-zero, then do not initialize but instead
** return the value of g.disableInit as the result code.  This can be used
** to simulate an initialization failure.
*/
static int counterMutexInit(void){ 
  int rc;
  if( g.disableInit ) return g.disableInit;
  rc = g.m.xMutexInit();
  g.isInit = 1;
  return rc;
}

/*
** Uninitialize the mutex subsystem
*/
static int counterMutexEnd(void){ 
  assert( g.isInit );
  g.isInit = 0;
  return g.m.xMutexEnd();
}

/*
** Allocate a countable mutex
*/
static sqlite3_mutex *counterMutexAlloc(int eType){
  sqlite3_mutex *pReal;
  sqlite3_mutex *pRet = 0;

  assert( g.isInit );
  assert(eType<8 && eType>=0);

  pReal = g.m.xMutexAlloc(eType);
  if( !pReal ) return 0;

  if( eType==0 || eType==1 ){
    pRet = (sqlite3_mutex *)malloc(sizeof(sqlite3_mutex));
................................................................................
  }

  pRet->eType = eType;
  pRet->pReal = pReal;
  return pRet;
}

/*
** Free a countable mutex
*/
static void counterMutexFree(sqlite3_mutex *p){
  assert( g.isInit );
  g.m.xMutexFree(p->pReal);
  if( p->eType==0 || p->eType==1 ){
    free(p);
  }
}

/*
** Enter a countable mutex.  Block until entry is safe.
*/
static void counterMutexEnter(sqlite3_mutex *p){
  assert( g.isInit );
  g.aCounter[p->eType]++;
  g.m.xMutexEnter(p->pReal);
}

/*
** Try to enter a mutex.  Return true on success.
*/
static int counterMutexTry(sqlite3_mutex *p){
  assert( g.isInit );
  g.aCounter[p->eType]++;
  return g.m.xMutexTry(p->pReal);
}

/* Leave a mutex
*/
static void counterMutexLeave(sqlite3_mutex *p){
  assert( g.isInit );
  g.m.xMutexLeave(p->pReal);
}

/*
** sqlite3_shutdown
*/
static int test_shutdown(
................................................................................
    { "clear_mutex_counters",    (Tcl_ObjCmdProc*)test_clear_mutex_counters },
  };
  int i;
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  memset(&g, 0, sizeof(g));

  Tcl_LinkVar(interp, "disable_mutex_init", 
              (char*)&g.disableInit, TCL_LINK_INT);
  return SQLITE_OK;
}

Changes to src/tokenize.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
...
389
390
391
392
393
394
395

396
397
398
399
400
401
402
...
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
...
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.144 2008/06/15 02:51:48 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>

/*
** The charMap() macro maps alphabetic characters into their
................................................................................
  *tokenType = TK_ILLEGAL;
  return 1;
}

/*
** Run the parser on the given SQL string.  The parser structure is
** passed in.  An SQLITE_ status code is returned.  If an error occurs
** and pzErrMsg!=NULL then an error message might be written into 
** memory obtained from sqlite3_malloc() and *pzErrMsg made to point to that
** error message.  Or maybe not.
*/
int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
  int nErr = 0;
  int i;
  void *pEngine;
  int tokenType;
  int lastTokenParsed = -1;
................................................................................

  if( db->activeVdbeCnt==0 ){
    db->u1.isInterrupted = 0;
  }
  pParse->rc = SQLITE_OK;
  pParse->zTail = pParse->zSql = zSql;
  i = 0;

  pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc);
  if( pEngine==0 ){
    db->mallocFailed = 1;
    return SQLITE_NOMEM;
  }
  assert( pParse->sLastToken.dyn==0 );
  assert( pParse->pNewTable==0 );
................................................................................
      break;
    }
    switch( tokenType ){
      case TK_SPACE:
      case TK_COMMENT: {
        if( db->u1.isInterrupted ){
          pParse->rc = SQLITE_INTERRUPT;
          if( pzErrMsg ){
            sqlite3SetString(pzErrMsg, "interrupt", (char*)0);
          }
          goto abort_parse;
        }
        break;
      }
      case TK_ILLEGAL: {
        if( pzErrMsg ){
          sqlite3_free(*pzErrMsg);
          *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
                          &pParse->sLastToken);
        }
        nErr++;
        goto abort_parse;
      }
      case TK_SEMI: {
        pParse->zTail = &zSql[i];
        /* Fall thru into the default case */
      }
................................................................................
  if( db->mallocFailed ){
    pParse->rc = SQLITE_NOMEM;
  }
  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
    sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0);
  }
  if( pParse->zErrMsg ){
    if( pzErrMsg && *pzErrMsg==0 ){
      *pzErrMsg = pParse->zErrMsg;
    }else{
      sqlite3_free(pParse->zErrMsg);
    }
    pParse->zErrMsg = 0;
    nErr++;
  }







|







 







|
|
|







 







>







 







<
|
<





<
|
|
|
<







 







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
...
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
...
417
418
419
420
421
422
423

424

425
426
427
428
429

430
431
432

433
434
435
436
437
438
439
...
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.145 2008/07/08 00:06:50 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>

/*
** The charMap() macro maps alphabetic characters into their
................................................................................
  *tokenType = TK_ILLEGAL;
  return 1;
}

/*
** Run the parser on the given SQL string.  The parser structure is
** passed in.  An SQLITE_ status code is returned.  If an error occurs
** then an and attempt is made to write an error message into 
** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that
** error message.
*/
int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
  int nErr = 0;
  int i;
  void *pEngine;
  int tokenType;
  int lastTokenParsed = -1;
................................................................................

  if( db->activeVdbeCnt==0 ){
    db->u1.isInterrupted = 0;
  }
  pParse->rc = SQLITE_OK;
  pParse->zTail = pParse->zSql = zSql;
  i = 0;
  assert( pzErrMsg!=0 );
  pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc);
  if( pEngine==0 ){
    db->mallocFailed = 1;
    return SQLITE_NOMEM;
  }
  assert( pParse->sLastToken.dyn==0 );
  assert( pParse->pNewTable==0 );
................................................................................
      break;
    }
    switch( tokenType ){
      case TK_SPACE:
      case TK_COMMENT: {
        if( db->u1.isInterrupted ){
          pParse->rc = SQLITE_INTERRUPT;

          sqlite3SetString(pzErrMsg, "interrupt", (char*)0);

          goto abort_parse;
        }
        break;
      }
      case TK_ILLEGAL: {

        sqlite3_free(*pzErrMsg);
        *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
                        &pParse->sLastToken);

        nErr++;
        goto abort_parse;
      }
      case TK_SEMI: {
        pParse->zTail = &zSql[i];
        /* Fall thru into the default case */
      }
................................................................................
  if( db->mallocFailed ){
    pParse->rc = SQLITE_NOMEM;
  }
  if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
    sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0);
  }
  if( pParse->zErrMsg ){
    if( *pzErrMsg==0 ){
      *pzErrMsg = pParse->zErrMsg;
    }else{
      sqlite3_free(pParse->zErrMsg);
    }
    pParse->zErrMsg = 0;
    nErr++;
  }

Changes to test/bind.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
87
88
89
90
91
92
93













94
95
96
97
98
99
100
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the sqlite_bind API.
#
# $Id: bind.test,v 1.42 2008/04/16 16:11:49 drh Exp $
#

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

proc sqlite_step {stmt N VALS COLS} {
  upvar VALS vals
................................................................................
do_test bind-1.9 {
  sqlite3_reset $VM
  sqlite_bind $VM 1 {456} normal
  sqlite_step $VM N VALUES COLNAMES
  execsql {SELECT rowid, * FROM t1}
} {1 123 abcdefg {} 2 456 abcdefg {}}














do_test bind-1.99 {
  sqlite3_finalize $VM
} SQLITE_OK

# Prepare the statement in different ways depending on whether or not
# the $var processing is compiled into the library.
#







|







 







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







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the sqlite_bind API.
#
# $Id: bind.test,v 1.43 2008/07/08 00:06:51 drh Exp $
#

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

proc sqlite_step {stmt N VALS COLS} {
  upvar VALS vals
................................................................................
do_test bind-1.9 {
  sqlite3_reset $VM
  sqlite_bind $VM 1 {456} normal
  sqlite_step $VM N VALUES COLNAMES
  execsql {SELECT rowid, * FROM t1}
} {1 123 abcdefg {} 2 456 abcdefg {}}

do_test bind-1.10 {
   set rc [catch {
     sqlite3_prepare db {INSERT INTO t1 VALUES($abc:123,?,:abc)} -1 TAIL
   } msg]
   lappend rc $msg
} {1 {(1) near ":123": syntax error}}
do_test bind-1.11 {
   set rc [catch {
     sqlite3_prepare db {INSERT INTO t1 VALUES(@abc:xyz,?,:abc)} -1 TAIL
   } msg]
   lappend rc $msg
} {1 {(1) near ":xyz": syntax error}}

do_test bind-1.99 {
  sqlite3_finalize $VM
} SQLITE_OK

# Prepare the statement in different ways depending on whether or not
# the $var processing is compiled into the library.
#

Added test/tokenize.test.



































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# 2008 July 7
#
# 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 implements regression tests for SQLite library.  The
# focus of this script testing the tokenizer
#
# $Id: tokenize.test,v 1.1 2008/07/08 00:06:51 drh Exp $
#

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

do_test tokenize-1.1 {
  catchsql {SELECT 1.0e+}
} {1 {unrecognized token: "1.0e"}}
do_test tokenize-1.2 {
  catchsql {SELECT 1.0E+}
} {1 {unrecognized token: "1.0E"}}
do_test tokenize-1.3 {
  catchsql {SELECT 1.0e-}
} {1 {unrecognized token: "1.0e"}}
do_test tokenize-1.4 {
  catchsql {SELECT 1.0E-}
} {1 {unrecognized token: "1.0E"}}
do_test tokenize-1.5 {
  catchsql {SELECT 1.0e+/}
} {1 {unrecognized token: "1.0e"}}
do_test tokenize-1.6 {
  catchsql {SELECT 1.0E+:}
} {1 {unrecognized token: "1.0E"}}
do_test tokenize-1.7 {
  catchsql {SELECT 1.0e-:}
} {1 {unrecognized token: "1.0e"}}
do_test tokenize-1.8 {
  catchsql {SELECT 1.0E-/}
} {1 {unrecognized token: "1.0E"}}
do_test tokenize-1.9 {
  catchsql {SELECT 1.0F+5}
} {1 {unrecognized token: "1.0F"}}
do_test tokenize-1.10 {
  catchsql {SELECT 1.0d-10}
} {1 {unrecognized token: "1.0d"}}
do_test tokenize-1.11 {
  catchsql {SELECT 1.0e,5}
} {1 {unrecognized token: "1.0e"}}
do_test tokenize-1.12 {
  catchsql {SELECT 1.0E.10}
} {1 {unrecognized token: "1.0E"}}

do_test tokenize-2.1 {
  catchsql {SELECT 1, 2 /*}
} {1 {near "*": syntax error}}
do_test tokenize-2.2 {
  catchsql {SELECT 1, 2 /* }
} {0 {1 2}}


finish_test