/ Check-in [2821767b]
Login

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

Overview
Comment:Add some more elements of the new API. (CVS 1416)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:2821767b947ae1a70e98dd7f47d69e424c37947f
User & Date: danielk1977 2004-05-20 11:00:52
Context
2004-05-20
12:10
Default type affinity is now NUMERIC. The affinity.html file checked into the doc directory. (CVS 1417) check-in: 948307f0 user: drh tags: trunk
11:00
Add some more elements of the new API. (CVS 1416) check-in: 2821767b user: danielk1977 tags: trunk
03:30
Fix the misc3.test test file. (CVS 1415) check-in: 478836f4 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
500
501
502
503
504
505
506

507
508
509
510
511
512
513
....
1028
1029
1030
1031
1032
1033
1034






























































































































































1035
1036
1037
1038
1039
1040
1041
....
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.176 2004/05/20 01:40:19 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
    FuncDef *pFunc, *pNext;
    for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
      pNext = pFunc->pNext;
      sqliteFree(pFunc);
    }
  }
  sqlite3HashClear(&db->aFunc);

  sqliteFree(db);
}

/*
** Rollback all database files.
*/
void sqlite3RollbackAll(sqlite *db){
................................................................................
  }
  if( !zFilename ){
    btree_flags |= BTREE_MEMORY;
  }

  return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags);
}































































































































































#if 0

/*
** sqlite3_open
**
*/
................................................................................
int sqlite3_errcode(sqlite3 *db){
  assert(!"TODO");
}

struct sqlite_stmt {
};

/*
** sqlite3_prepare
**
** TODO: error message handling
*/
int sqlite3_prepare(
  sqlite3 *db, 
  const char *zSql, 
  sqlite3_stmt **ppStmt, 
  const char** pzTail
){
  int rc;
  rc = sqlite3_compile(db, zSql, pzTail, ppStmt, 0); 
  return rc;
}
int sqlite3_prepare16(
  sqlite3 *db, 
  const void *zSql, 
  sqlite3_stmt **ppStmt, 
  const void **pzTail
){
  int rc;
  char *sql8;

  sql8 = sqlite3utf16to8(zSql, -1);
  if( !sql8 ){
    return SQLITE_NOMEM;
  }

  /* TODO: Have to set *pzTail to point into the original UTF-16 string
  ** somehow.
  */
  rc = sqlite3_prepare(db, sql8, ppStmt, 0);
  sqliteFree(filename8);

  return rc;
}

/*
** sqlite3_finalize
*/
int sqlite3_finalize(sqlite3_stmt *stmt){
  return sqlite3_finalize(stmt, 0);
}








|







 







>







 







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







 







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







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
....
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
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
1151
1152
1153
1154
1155
1156
1157
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
1197
1198
1199
1200
....
1245
1246
1247
1248
1249
1250
1251






































1252
1253
1254
1255
1256
1257
1258
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.177 2004/05/20 11:00:52 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
    FuncDef *pFunc, *pNext;
    for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
      pNext = pFunc->pNext;
      sqliteFree(pFunc);
    }
  }
  sqlite3HashClear(&db->aFunc);
  sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
  sqliteFree(db);
}

/*
** Rollback all database files.
*/
void sqlite3RollbackAll(sqlite *db){
................................................................................
  }
  if( !zFilename ){
    btree_flags |= BTREE_MEMORY;
  }

  return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags);
}

const char *sqlite3_errmsg(sqlite3 *db){
  if( db->zErrMsg ){
    return db->zErrMsg;
  }
  return sqlite3_error_string(db->errCode);
}

const void *sqlite3_errmsg16(sqlite3 *db){
  if( !db->zErrMsg16 ){
    char const *zErr8 = sqlite3_errmsg(db);
    if( SQLITE3_BIGENDIAN ){
      db->zErrMsg16 = sqlite3utf8to16be(zErr8, -1);
    }else{
      db->zErrMsg16 = sqlite3utf8to16le(zErr8, -1);
    }
  }
  return db->zErrMsg16;
}

int sqlite3_errcode(sqlite3 *db){
  return db->errCode;
}

/*
** Compile the UTF-8 encoded SQL statement zSql into a statement handle.
*/
int sqlite3_prepare(
  sqlite3 *db,              /* Database handle. */
  const char *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const char** pzTail       /* OUT: End of parsed string */
){
  Parse sParse;
  char *zErrMsg = 0;
  int rc = SQLITE_OK;

  if( sqlite3SafetyOn(db) ){
    rc = SQLITE_MISUSE;
    goto prepare_out;
  }

  if( !db->init.busy ){
    if( (db->flags & SQLITE_Initialized)==0 ){
      int rc, cnt = 1;
      while( (rc = sqlite3Init(db, &zErrMsg))==SQLITE_BUSY
         && db->xBusyCallback
         && db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){}
      if( rc!=SQLITE_OK ){
        goto prepare_out;
      }
      if( zErrMsg ){
        sqliteFree(zErrMsg);
        zErrMsg = 0;
      }
    }
  }
  assert( (db->flags & SQLITE_Initialized)!=0 || db->init.busy );

  if( db->pVdbe==0 ){ db->nChange = 0; }
  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sqlite3RunParser(&sParse, zSql, &zErrMsg);

  if( db->xTrace && !db->init.busy ){
    /* Trace only the statment that was compiled.
    ** Make a copy of that part of the SQL string since zSQL is const
    ** and we must pass a zero terminated string to the trace function
    ** The copy is unnecessary if the tail pointer is pointing at the
    ** beginnig or end of the SQL string.
    */
    if( sParse.zTail && sParse.zTail!=zSql && *sParse.zTail ){
      char *tmpSql = sqliteStrNDup(zSql, sParse.zTail - zSql);
      if( tmpSql ){
        db->xTrace(db->pTraceArg, tmpSql);
        free(tmpSql);
      }else{
        /* If a memory error occurred during the copy,
        ** trace entire SQL string and fall through to the
        ** sqlite3_malloc_failed test to report the error.
        */
        db->xTrace(db->pTraceArg, zSql); 
      }
    }else{
      db->xTrace(db->pTraceArg, zSql); 
    }
  }

  if( sqlite3_malloc_failed ){
    rc = SQLITE_NOMEM;
    sqlite3RollbackAll(db);
    sqlite3ResetInternalSchema(db, 0);
    db->flags &= ~SQLITE_InTrans;
    goto prepare_out;
  }
  if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
  if( sParse.rc==SQLITE_SCHEMA ){
    sqlite3ResetInternalSchema(db, 0);
  }
  assert( ppStmt );
  *ppStmt = (sqlite3_stmt*)sParse.pVdbe;
  if( pzTail ) *pzTail = sParse.zTail;

  if( sqlite3SafetyOff(db) ){
    rc = SQLITE_MISUSE;
    goto prepare_out;
  }

  rc = sParse.rc;

prepare_out:
  if( zErrMsg ){
    sqlite3Error(db, rc, "%s", zErrMsg);
  }else{
    sqlite3Error(db, rc, 0);
  }
  return rc;
}

/*
** Compile the UTF-16 encoded SQL statement zSql into a statement handle.
*/
int sqlite3_prepare16(
  sqlite3 *db,              /* Database handle. */ 
  const void *zSql,         /* UTF-8 encoded SQL statement. */
  int nBytes,               /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,    /* OUT: A pointer to the prepared statement */
  const void **pzTail       /* OUT: End of parsed string */
){
  /* This function currently works by first transforming the UTF-16
  ** encoded string to UTF-8, then invoking sqlite3_prepare(). The
  ** tricky bit is figuring out the pointer to return in *pzTail.
  */
  char *zSql8 = 0;
  char const *zTail8 = 0;
  int rc;

  zSql8 = sqlite3utf16to8(zSql, nBytes);
  if( !zSql8 ){
    sqlite3Error(db, SQLITE_NOMEM, 0);
    return SQLITE_NOMEM;
  }
  rc = sqlite3_prepare(db, zSql8, -1, ppStmt, &zTail8);

  if( zTail8 && pzTail ){
    /* If sqlite3_prepare returns a tail pointer, we calculate the
    ** equivalent pointer into the UTF-16 string by counting the unicode
    ** characters between zSql8 and zTail8, and then returning a pointer
    ** the same number of characters into the UTF-16 string.
    */
    int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8);
    *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed);
  }
 
  return rc;
}


#if 0

/*
** sqlite3_open
**
*/
................................................................................
int sqlite3_errcode(sqlite3 *db){
  assert(!"TODO");
}

struct sqlite_stmt {
};







































/*
** sqlite3_finalize
*/
int sqlite3_finalize(sqlite3_stmt *stmt){
  return sqlite3_finalize(stmt, 0);
}

Changes to src/os.h.

157
158
159
160
161
162
163








164
165
166
167
168
169
170
# else
    typedef SInt32 off_t;
# endif
# define SQLITE_TEMPNAME_SIZE _MAX_PATH
# define SQLITE_MIN_SLEEP_MS 17
#endif









int sqlite3OsDelete(const char*);
int sqlite3OsFileExists(const char*);
int sqliteOsFileRename(const char*, const char*);
int sqlite3OsOpenReadWrite(const char*, OsFile*, int*);
int sqlite3OsOpenExclusive(const char*, OsFile*, int);
int sqlite3OsOpenReadOnly(const char*, OsFile*);
int sqlite3OsOpenDirectory(const char*, OsFile*);







>
>
>
>
>
>
>
>







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# else
    typedef SInt32 off_t;
# endif
# define SQLITE_TEMPNAME_SIZE _MAX_PATH
# define SQLITE_MIN_SLEEP_MS 17
#endif

/*
** Macros to determine whether the machine is big or little endian,
** evaluated at runtime.
*/
static const int sqlite3_one = 1;
#define SQLITE3_BIGENDIAN (*(char *)(&sqlite3_one)==0)
#define SQLITE3_LITTLEENDIAN (*(char *)(&sqlite3_one)==1)

int sqlite3OsDelete(const char*);
int sqlite3OsFileExists(const char*);
int sqliteOsFileRename(const char*, const char*);
int sqlite3OsOpenReadWrite(const char*, OsFile*, int*);
int sqlite3OsOpenExclusive(const char*, OsFile*, int);
int sqlite3OsOpenReadOnly(const char*, OsFile*);
int sqlite3OsOpenDirectory(const char*, OsFile*);

Changes to src/sqlite.h.in.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
857
858
859
860
861
862
863


864

865
866
867
868
869
870
871
...
972
973
974
975
976
977
978

























979
980









981
982
983
984
985
986






987

988
989

















990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.65 2004/05/20 01:40:19 danielk1977 Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** encoding, -1 is returned.
**
** The "in" and "out" parameters may point to the same buffer in order
** to decode a string in place.
*/
int sqlite_decode_binary(const unsigned char *in, unsigned char *out);



typedef sqlite_vm sqlite3_stmt;


/*
** This routine is used to bind a 32-bit integer value to a variable
** in an SQL statement compiled by sqlite3_compile(). See comments for
** sqlite3_compile() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously
................................................................................
** pointed to by "z". If "eCopy" is false, then SQLite stores a pointer to
** the original blob data. In this case the caller must ensure that the
** blob data remains stable until after the SQL statement has been
** finalised or another value bound to variable "i".
*/
int sqlite3_bind_blob(sqlite3_stmt*, int i, const void *z, int n, int eCopy);



























#if 0










/*
** Below this point are the new sqlite3 APIs. At present these are
** implemented in terms of the sqlite2 API above. This is to get the TCL
** interface and other testing infrastructure in place for when
** functionality starts getting added.






*/


typedef struct sqlite sqlite3;


















int sqlite3_open(const char*, sqlite3**, const char**);
int sqlite3_open16(const void*, sqlite3**, const char**);
int sqlite3_close(sqlite3*);

const char *sqlite3_errmsg(sqlite3*);
const void *sqlite3_errmsg16(sqlite3*);
int sqlite3_errcode(sqlite3*);

typedef struct sqlite3_vm sqlite3_stmt;

int sqlite3_prepare(sqlite3*, const char*, sqlite3_stmt**, const char**);
int sqlite3_prepare16(sqlite3*, const void*, sqlite3_stmt**, const void**);
int sqlite3_finalize(sqlite3_stmt*);
int sqlite3_reset(sqlite3_stmt*);

int sqlite3_step(sqlite3_stmt*);

#define SQLITE3_INTEGER  1
#define SQLITE3_FLOAT    2







|







 







>
>

>







 







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

<
>
>
>
>
>
>
>
>
>


<
<
<
<
>
>
>
>
>
>

>

<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>





<
<
<
<
<
<
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
...
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018




1019
1020
1021
1022
1023
1024
1025
1026
1027

1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049








1050
1051
1052
1053
1054
1055
1056
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.66 2004/05/20 11:00:52 danielk1977 Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
** encoding, -1 is returned.
**
** The "in" and "out" parameters may point to the same buffer in order
** to decode a string in place.
*/
int sqlite_decode_binary(const unsigned char *in, unsigned char *out);


/* FIX ME */
typedef sqlite_vm sqlite3_stmt;
typedef sqlite sqlite3;

/*
** This routine is used to bind a 32-bit integer value to a variable
** in an SQL statement compiled by sqlite3_compile(). See comments for
** sqlite3_compile() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously
................................................................................
** pointed to by "z". If "eCopy" is false, then SQLite stores a pointer to
** the original blob data. In this case the caller must ensure that the
** blob data remains stable until after the SQL statement has been
** finalised or another value bound to variable "i".
*/
int sqlite3_bind_blob(sqlite3_stmt*, int i, const void *z, int n, int eCopy);

/*
** Return the error code for the most recent sqlite3_* API call associated
** with sqlite3 handle 'db'. SQLITE_OK is returned if the most recent 
** API call was successful.
**
** Calls to many sqlite3_* functions set the error code and string returned
** by sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16()
** (overwriting the previous values). A complete list of functions that set
** the error code and string returned by these functions follows. Note that
** calls to sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16()
** themselves do not affect the results of future invocations.
**
** sqlite3_bind_int32
** sqlite3_bind_int64
** sqlite3_bind_double
** sqlite3_bind_null
** sqlite3_bind_text
** sqlite3_bind_text16
** sqlite3_bind_blob
**
** Assuming no other intervening sqlite3_* API calls are made, the error
** code returned by this function is associated with the same error as
** the strings  returned by sqlite3_errmsg() and sqlite3_errmsg16().
*/
int sqlite3_errcode(sqlite3 *db);


/*
** Return a pointer to a UTF-8 encoded string describing in english the
** error condition for the most recent sqlite3_* API call. The returned
** string is always terminated by an 0x00 byte.
**
** The string "not an error" is returned when the most recent API call was
** successful.
*/
const char *sqlite3_errmsg(sqlite3*);

/*




** Return a pointer to a UTF-16 native byte order encoded string describing
** in english the error condition for the most recent sqlite3_* API call.
** The returned string is always terminated by a pair of 0x00 bytes.
**
** The string "not an error" is returned when the most recent API call was
** successful.
*/
const void *sqlite3_errmsg16(sqlite3*);


int sqlite3_prepare(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nBytes,             /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);

int sqlite3_prepare16(
  sqlite3 *db,            /* Database handle */
  const void *zSql,       /* SQL statement, UTF-16 encoded */
  int nBytes,             /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
);

#if 0

int sqlite3_open(const char*, sqlite3**, const char**);
int sqlite3_open16(const void*, sqlite3**, const char**);
int sqlite3_close(sqlite3*);









int sqlite3_finalize(sqlite3_stmt*);
int sqlite3_reset(sqlite3_stmt*);

int sqlite3_step(sqlite3_stmt*);

#define SQLITE3_INTEGER  1
#define SQLITE3_FLOAT    2

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
347
348
349
350
351
352
353





354
355
356
357
358
359
360
...
393
394
395
396
397
398
399

400

401
402
403
404
405
406
407
....
1317
1318
1319
1320
1321
1322
1323
1324

1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336


**    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.239 2004/05/20 01:12:34 danielk1977 Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
** insert, update, or delete statement.  It remains constant throughout the
** length of a statement and is then updated by OP_SetCounts.  It keeps a
** context stack just like lastRowid so that the count of changes
** within a trigger is not seen outside the trigger.  Changes to views do not
** affect the value of lsChange.
** The sqlite.csChange keeps track of the number of current changes (since
** the last statement) and is used to update sqlite_lsChange.





*/
struct sqlite {
  int nDb;                      /* Number of backends currently in use */
  Db *aDb;                      /* All backends */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
  int flags;                    /* Miscellanous flags. See below */
  u8 file_format;               /* What file format version is this database? */
................................................................................
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int (*xProgress)(void *);     /* The progress callback */
  void *pProgressArg;           /* Argument to the progress callback */
  int nProgressOps;             /* Number of opcodes for progress callback */
#endif


  char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */

};

/*
** Possible values for the sqlite.flags and or Db.flags fields.
**
** On sqlite.flags, the SQLITE_InTrans value means that we have
** executed a BEGIN.  On Db.flags, SQLITE_InTrans means a statement
................................................................................
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 sqlite3utf16ByteLen(const void *pData);

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*);









|







 







>
>
>
>
>







 







>

>







 







|
>












>
>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
...
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
....
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
**    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.240 2004/05/20 11:00:52 danielk1977 Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
** insert, update, or delete statement.  It remains constant throughout the
** length of a statement and is then updated by OP_SetCounts.  It keeps a
** context stack just like lastRowid so that the count of changes
** within a trigger is not seen outside the trigger.  Changes to views do not
** affect the value of lsChange.
** The sqlite.csChange keeps track of the number of current changes (since
** the last statement) and is used to update sqlite_lsChange.
**
** The member variables sqlite.errCode, sqlite.zErrMsg and sqlite.zErrMsg16
** store the most recent error code and, if applicable, string. The
** internal function sqlite3Error() is used to set these variables
** consistently.
*/
struct sqlite {
  int nDb;                      /* Number of backends currently in use */
  Db *aDb;                      /* All backends */
  Db aDbStatic[2];              /* Static space for the 2 default backends */
  int flags;                    /* Miscellanous flags. See below */
  u8 file_format;               /* What file format version is this database? */
................................................................................
#endif
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  int (*xProgress)(void *);     /* The progress callback */
  void *pProgressArg;           /* Argument to the progress callback */
  int nProgressOps;             /* Number of opcodes for progress callback */
#endif

  int errCode;                  /* Most recent error code (SQLITE_*) */
  char *zErrMsg;                /* Most recent error message (UTF-8 encoded) */
  void *zErrMsg16;              /* Most recent error message (UTF-16 encoded) */
};

/*
** Possible values for the sqlite.flags and or Db.flags fields.
**
** On sqlite.flags, the SQLITE_InTrans value means that we have
** executed a BEGIN.  On Db.flags, SQLITE_InTrans means a statement
................................................................................
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 sqlite3utf16ByteLen(const void *pData, int nChar);
int sqlite3utf8CharLen(const char *pData, int nByte);
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*);
void sqlite3Error(sqlite *, int, const char*,...);

Changes to src/test1.c.

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
....
1187
1188
1189
1190
1191
1192
1193



















































































































































































1194
1195
1196
1197
1198
1199
1200
....
1237
1238
1239
1240
1241
1242
1243





1244
1245
1246
1247
1248
1249
1250
....
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.41 2004/05/20 01:12:35 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

#if OS_WIN
# define PTR_FMT "%x"
#else
# define PTR_FMT "%p"
#endif





































/*
** Decode a pointer to an sqlite object.
*/
static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite **ppDb){
  if( sscanf(zA, PTR_FMT, (void**)ppDb)!=1 && 
      (zA[0]!='0' || zA[1]!='x' || sscanf(&zA[2], PTR_FMT, (void**)ppDb)!=1)
................................................................................
  rc = sqlite3_bind_blob(pStmt, idx, value, bytes, 1);
  if( rc!=SQLITE_OK ){
    return TCL_ERROR;
  }

  return TCL_OK;
}




















































































































































































/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest1_Init(Tcl_Interp *interp){
  extern int sqlite3_search_count;
  extern int sqlite3_interrupt_count;
................................................................................
     { "sqlite3_bind_int32",            (Tcl_ObjCmdProc*)test_bind_int32    },
     { "sqlite3_bind_int64",            (Tcl_ObjCmdProc*)test_bind_int64    },
     { "sqlite3_bind_double",           (Tcl_ObjCmdProc*)test_bind_double   },
     { "sqlite3_bind_null",             (Tcl_ObjCmdProc*)test_bind_null     },
     { "sqlite3_bind_text",             (Tcl_ObjCmdProc*)test_bind_text     },
     { "sqlite3_bind_text16",           (Tcl_ObjCmdProc*)test_bind_text16   },
     { "sqlite3_bind_blob",             (Tcl_ObjCmdProc*)test_bind_blob     },





  };
  int i;

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
................................................................................
      (char*)&sqlite3_open_file_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_current_time", 
      (char*)&sqlite3_current_time, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_static_bind_value",
      (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
  return TCL_OK;
}










|












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







 







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







 







>
>
>
>
>







 









<
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
....
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
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
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
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
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
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
....
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
....
1478
1479
1480
1481
1482
1483
1484
1485
1486

**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.42 2004/05/20 11:00:52 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

#if OS_WIN
# define PTR_FMT "%x"
#else
# define PTR_FMT "%p"
#endif

static const char * errorName(int rc){
  const char *zName = 0;
  switch( rc ){
    case SQLITE_OK:         zName = "SQLITE_OK";          break;
    case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;
    case SQLITE_INTERNAL:   zName = "SQLITE_INTERNAL";    break;
    case SQLITE_PERM:       zName = "SQLITE_PERM";        break;
    case SQLITE_ABORT:      zName = "SQLITE_ABORT";       break;
    case SQLITE_BUSY:       zName = "SQLITE_BUSY";        break;
    case SQLITE_LOCKED:     zName = "SQLITE_LOCKED";      break;
    case SQLITE_NOMEM:      zName = "SQLITE_NOMEM";       break;
    case SQLITE_READONLY:   zName = "SQLITE_READONLY";    break;
    case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
    case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
    case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
    case SQLITE_NOTFOUND:   zName = "SQLITE_NOTFOUND";    break;
    case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
    case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
    case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;
    case SQLITE_EMPTY:      zName = "SQLITE_EMPTY";       break;
    case SQLITE_SCHEMA:     zName = "SQLITE_SCHEMA";      break;
    case SQLITE_TOOBIG:     zName = "SQLITE_TOOBIG";      break;
    case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT";  break;
    case SQLITE_MISMATCH:   zName = "SQLITE_MISMATCH";    break;
    case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
    case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;
    case SQLITE_AUTH:       zName = "SQLITE_AUTH";        break;
    case SQLITE_FORMAT:     zName = "SQLITE_FORMAT";      break;
    case SQLITE_RANGE:      zName = "SQLITE_RANGE";       break;
    case SQLITE_ROW:        zName = "SQLITE_ROW";         break;
    case SQLITE_DONE:       zName = "SQLITE_DONE";        break;
    default:                zName = "SQLITE_Unknown";     break;
  }
  return zName;
}

/*
** Decode a pointer to an sqlite object.
*/
static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite **ppDb){
  if( sscanf(zA, PTR_FMT, (void**)ppDb)!=1 && 
      (zA[0]!='0' || zA[1]!='x' || sscanf(&zA[2], PTR_FMT, (void**)ppDb)!=1)
................................................................................
  rc = sqlite3_bind_blob(pStmt, idx, value, bytes, 1);
  if( rc!=SQLITE_OK ){
    return TCL_ERROR;
  }

  return TCL_OK;
}

/*
** Usage: sqlite3_errcode DB
**
** Return the string representation of the most recent sqlite3_* API
** error code. e.g. "SQLITE_ERROR".
*/
static int test_errcode(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3 *db;

  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", 
       Tcl_GetString(objv[0]), " DB", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  Tcl_SetResult(interp, (char *)errorName(sqlite3_errcode(db)), 0);
  return TCL_OK;
}

/*
** Usage:   test_errmsg DB
**
** Returns the UTF-8 representation of the error message string for the
** most recent sqlite3_* API call.
*/
static int test_errmsg(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite *db;
  const char *zErr;

  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", 
       Tcl_GetString(objv[0]), " DB", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;

  zErr = sqlite3_errmsg(db);
  Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
  return TCL_OK;
}

/*
** Usage:   test_errmsg16 DB
**
** Returns the UTF-16 representation of the error message string for the
** most recent sqlite3_* API call. This is a byte array object at the TCL 
** level, and it includes the 0x00 0x00 terminator bytes at the end of the
** UTF-16 string.
*/
static int test_errmsg16(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite *db;
  const void *zErr;
  int bytes;

  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", 
       Tcl_GetString(objv[0]), " DB", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;

  zErr = sqlite3_errmsg16(db);
  bytes = sqlite3utf16ByteLen(zErr, -1);
  Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes));
  return TCL_OK;
}

/*
** Usage: sqlite3_prepare DB sql bytes tailvar
**
** Compile up to <bytes> bytes of the supplied SQL string <sql> using
** database handle <DB>. The parameter <tailval> is the name of a global
** variable that is set to the unused portion of <sql> (if any). A
** STMT handle is returned.
*/
static int test_prepare(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3 *db;
  const char *zSql;
  int bytes;
  const char *zTail = 0;
  sqlite3_stmt *pStmt = 0;
  char zBuf[50];

  if( objc!=5 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", 
       Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  zSql = Tcl_GetString(objv[2]);
  if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;

  if( SQLITE_OK!=sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail) ){
    return TCL_ERROR;
  }

  if( zTail ){
    if( bytes>=0 ){
      bytes = bytes - (zTail-zSql);
    }
    Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
  }

  if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}

/*
** Usage: sqlite3_prepare DB sql bytes tailvar
**
** Compile up to <bytes> bytes of the supplied SQL string <sql> using
** database handle <DB>. The parameter <tailval> is the name of a global
** variable that is set to the unused portion of <sql> (if any). A
** STMT handle is returned.
*/
static int test_prepare16(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3 *db;
  const void *zSql;
  const void *zTail = 0;
  Tcl_Obj *pTail = 0;
  sqlite3_stmt *pStmt = 0;
  char zBuf[50];
  int bytes;                /* The integer specified as arg 3 */
  int objlen;               /* The byte-array length of arg 2 */

  if( objc!=5 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", 
       Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen);
  if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;

  if( SQLITE_OK!=sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail) ){
    return TCL_ERROR;
  }

  if( zTail ){
    objlen = objlen - ((u8 *)zTail-(u8 *)zSql);
  }else{
    objlen = 0;
  }
  pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
  Tcl_IncrRefCount(pTail);
  Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
  // Tcl_DecrRefCount(pTail);

  if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}

/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest1_Init(Tcl_Interp *interp){
  extern int sqlite3_search_count;
  extern int sqlite3_interrupt_count;
................................................................................
     { "sqlite3_bind_int32",            (Tcl_ObjCmdProc*)test_bind_int32    },
     { "sqlite3_bind_int64",            (Tcl_ObjCmdProc*)test_bind_int64    },
     { "sqlite3_bind_double",           (Tcl_ObjCmdProc*)test_bind_double   },
     { "sqlite3_bind_null",             (Tcl_ObjCmdProc*)test_bind_null     },
     { "sqlite3_bind_text",             (Tcl_ObjCmdProc*)test_bind_text     },
     { "sqlite3_bind_text16",           (Tcl_ObjCmdProc*)test_bind_text16   },
     { "sqlite3_bind_blob",             (Tcl_ObjCmdProc*)test_bind_blob     },
     { "sqlite3_errcode",               (Tcl_ObjCmdProc*)test_errcode       },
     { "sqlite3_errmsg",                (Tcl_ObjCmdProc*)test_errmsg        },
     { "sqlite3_errmsg16",              (Tcl_ObjCmdProc*)test_errmsg16      },
     { "sqlite3_prepare",               (Tcl_ObjCmdProc*)test_prepare       },
     { "sqlite3_prepare16",             (Tcl_ObjCmdProc*)test_prepare16     },
  };
  int i;

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
................................................................................
      (char*)&sqlite3_open_file_count, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_current_time", 
      (char*)&sqlite3_current_time, TCL_LINK_INT);
  Tcl_LinkVar(interp, "sqlite_static_bind_value",
      (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
  return TCL_OK;
}



Changes to src/utf.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
...
320
321
322
323
324
325
326


























327
328



329
330

331
332
333
334
335
336
337
























338
339
340
341
342
343
344
...
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
...
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.5 2004/05/20 01:12:35 danielk1977 Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
................................................................................
  static const struct Utf8WriteTblRow utf8tbl[] = {
    {0x0000007F, 0, 0x7F, 0x00},
    {0x000007FF, 1, 0xDF, 0xC0},
    {0x0000FFFF, 2, 0xEF, 0xE0},
    {0x0010FFFF, 3, 0xF7, 0xF0},
    {0x00000000, 0, 0x00, 0x00}
  };
  struct Utf8WriteTblRow *pRow = &utf8tbl[0];

  while( code>pRow->max_code ){
    assert( pRow->max_code );
    pRow++;
  }

  /* Ensure there is enough room left in the output buffer to write
................................................................................

  pStr->c += bytes;
  
  return 0;
}

/*


























** Return the number of bytes up to (but not including) the first \u0000
** character in *pStr.



*/
int sqlite3utf16ByteLen(const void *pZ){

  const unsigned char *pC1 = pZ;
  const unsigned char *pC2 = pZ+1;
  while( *pC1 || *pC2 ){
    pC1 += 2;
    pC2 += 2;
  }
  return pC1-(unsigned char *)pZ;
























}

/*
** Convert a string in UTF-16 native byte (or with a Byte-order-mark or
** "BOM") into a UTF-8 string.  The UTF-8 string is written into space 
** obtained from sqlite3Malloc() and must be released by the calling function.
**
................................................................................
  out.pZ = 0;

  in.pZ = (unsigned char *)pData;
  in.n = N;
  in.c = 0;

  if( in.n<0 ){
    in.n = sqlite3utf16ByteLen(in.pZ);
  }

  /* A UTF-8 encoding of a unicode string can require at most 1.5 times as
  ** much space to store as the same string encoded using UTF-16. Allocate
  ** this now.
  */
  out.n = (in.n*1.5) + 1;
................................................................................
static void utf16to16(void *pData, int N, int big_endian){
  UtfString inout;
  inout.pZ = (unsigned char *)pData;
  inout.c = 0;
  inout.n = N;

  if( inout.n<0 ){
    inout.n = sqlite3utf16ByteLen(inout.pZ);
  }

  if( readUtf16Bom(&inout)!=big_endian ){
    /* swab(&inout.pZ[inout.c], inout.pZ, inout.n-inout.c); */
    int i;
    for(i=0; i<(inout.n-inout.c); i += 2){
      char c1 = inout.pZ[i+inout.c];







|







 







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
<
>
>
>

|
>
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
...
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
...
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
...
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.6 2004/05/20 11:00:52 danielk1977 Exp $
**
** Notes on UTF-8:
**
**   Byte-0    Byte-1    Byte-2    Byte-3    Value
**  0xxxxxxx                                 00000000 00000000 0xxxxxxx
**  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
**  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
................................................................................
  static const struct Utf8WriteTblRow utf8tbl[] = {
    {0x0000007F, 0, 0x7F, 0x00},
    {0x000007FF, 1, 0xDF, 0xC0},
    {0x0000FFFF, 2, 0xEF, 0xE0},
    {0x0010FFFF, 3, 0xF7, 0xF0},
    {0x00000000, 0, 0x00, 0x00}
  };
  const struct Utf8WriteTblRow *pRow = &utf8tbl[0];

  while( code>pRow->max_code ){
    assert( pRow->max_code );
    pRow++;
  }

  /* Ensure there is enough room left in the output buffer to write
................................................................................

  pStr->c += bytes;
  
  return 0;
}

/*
** pZ is a UTF-8 encoded unicode string. If nByte is less than zero,
** return the number of unicode characters in pZ up to (but not including)
** the first 0x00 byte. If nByte is not less than zero, return the
** number of unicode characters in the first nByte of pZ (or up to 
** the first 0x00, whichever comes first).
*/
int sqlite3utf8CharLen(const char *pZ, int nByte){
  UtfString str;
  int ret = 0;
  u32 code = 1;

  str.pZ = (char *)pZ;
  str.n = nByte;
  str.c = 0;

  while( (nByte<0 || str.c<str.n) && code!=0 ){
    code = readUtf8(&str);
    ret++;
  }
  if( code==0 ) ret--;

  return ret;
}

/*
** pZ is a UTF-16 encoded unicode string. If nChar is less than zero,
** return the number of bytes up to (but not including), the first pair

** of consecutive 0x00 bytes in pZ. If nChar is not less than zero,
** then return the number of bytes in the first nChar unicode characters
** in pZ (or up until the first pair of 0x00 bytes, whichever comes first).
*/
int sqlite3utf16ByteLen(const void *pZ, int nChar){
  if( nChar<0 ){
    const unsigned char *pC1 = pZ;
    const unsigned char *pC2 = pZ+1;
    while( *pC1 || *pC2 ){
      pC1 += 2;
      pC2 += 2;
    }
    return pC1-(unsigned char *)pZ;
  }else{
    UtfString str;
    u32 code = 1;
    int big_endian;
    int nRead = 0;
    int ret;

    str.pZ = (char *)pZ;
    str.c = 0;
    str.n = -1;

    /* Check for a BOM */
    big_endian = readUtf16Bom(&str);
    ret = 0-str.c;

    while( code!=0 && nRead<nChar ){
      code = readUtf16(&str, big_endian);
      nRead++;
    }
    if( code==0 ){
      ret -= 2;
    }
    return str.c + ret;
  }
}

/*
** Convert a string in UTF-16 native byte (or with a Byte-order-mark or
** "BOM") into a UTF-8 string.  The UTF-8 string is written into space 
** obtained from sqlite3Malloc() and must be released by the calling function.
**
................................................................................
  out.pZ = 0;

  in.pZ = (unsigned char *)pData;
  in.n = N;
  in.c = 0;

  if( in.n<0 ){
    in.n = sqlite3utf16ByteLen(in.pZ, -1);
  }

  /* A UTF-8 encoding of a unicode string can require at most 1.5 times as
  ** much space to store as the same string encoded using UTF-16. Allocate
  ** this now.
  */
  out.n = (in.n*1.5) + 1;
................................................................................
static void utf16to16(void *pData, int N, int big_endian){
  UtfString inout;
  inout.pZ = (unsigned char *)pData;
  inout.c = 0;
  inout.n = N;

  if( inout.n<0 ){
    inout.n = sqlite3utf16ByteLen(inout.pZ, -1);
  }

  if( readUtf16Bom(&inout)!=big_endian ){
    /* swab(&inout.pZ[inout.c], inout.pZ, inout.n-inout.c); */
    int i;
    for(i=0; i<(inout.n-inout.c); i += 2){
      char c1 = inout.pZ[i+inout.c];

Changes to src/util.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
400
401
402
403
404
405
406










































407
408
409
410
411
412
413
**
*************************************************************************
** 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.
................................................................................
#ifdef MEMORY_DEBUG
#if MEMORY_DEBUG>1
  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
#endif
#endif
  va_end(ap);
}











































/*
** Add an error message to pParse->zErrMsg and increment pParse->nErr.
** The following formatting characters are allowed:
**
**      %s      Insert a string
**      %z      A string that should be freed after use







|







 







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







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
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
443
444
445
446
447
448
449
450
451
452
453
454
455
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.87 2004/05/20 11:00:52 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
................................................................................
#ifdef MEMORY_DEBUG
#if MEMORY_DEBUG>1
  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
#endif
#endif
  va_end(ap);
}

/*
** Set the most recent error code and error string for the sqlite
** handle "db". The error code is set to "err_code".
**
** If it is not NULL, string zFormat specifies the format of the
** error string in the style of the printf functions: The following
** format characters are allowed:
**
**      %s      Insert a string
**      %z      A string that should be freed after use
**      %d      Insert an integer
**      %T      Insert a token
**      %S      Insert the first element of a SrcList
**
** zFormat and any string tokens that follow it are assumed to be
** encoded in UTF-8.
**
** To clear the most recent error for slqite handle "db", sqlite3Error
** should be called with err_code set to SQLITE_OK and zFormat set
** to NULL.
*/
void sqlite3Error(sqlite *db, int err_code, const char *zFormat, ...){
  /* Free any existing error message. */
  if( db->zErrMsg ){
    sqliteFree(db->zErrMsg);
    db->zErrMsg = 0;
  }
  if( db->zErrMsg16 ){
    sqliteFree(db->zErrMsg16);
    db->zErrMsg16 = 0;
  }

  /* Set the new error code and error message. */
  db->errCode = err_code;
  if( zFormat ){
    va_list ap;
    va_start(ap, zFormat);
    db->zErrMsg = sqlite3VMPrintf(zFormat, ap);
    va_end(ap);
  }
}

/*
** Add an error message to pParse->zErrMsg and increment pParse->nErr.
** The following formatting characters are allowed:
**
**      %s      Insert a string
**      %z      A string that should be freed after use

Changes to src/vdbeaux.c.

940
941
942
943
944
945
946
947




948
949
950
951

952
953
954

955
956
957
958
959
960
961
962

963
964
965
966
967
968




969
970
971
972
973
974
975
976
977
978

979
980



981
982
983
984
985
986
987
988
989
990
991
992

993
994
995
996
997
998
999
....
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
    sqlite3ResetInternalSchema(db, 0);
  }
  return rc;
}

/*
** Unbind the value bound to variable $i in virtual machine p. This is the 
** the same as binding a NULL value to the column.




*/
static int vdbeUnbind(Vdbe *p, int i){
  Mem *pVar;
  if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 ){

    return SQLITE_MISUSE;
  }
  if( i<1 || i>p->nVar ){

    return SQLITE_RANGE;
  }
  i--;
  pVar = &p->apVar[i];
  if( pVar->flags&MEM_Dyn ){
    sqliteFree(pVar->z);
  }
  pVar->flags = MEM_Null;

  return SQLITE_OK;
}

/*
** This routine is used to bind text or blob data to an SQL variable (a ?).
** It may also be used to bind a NULL value, by setting zVal to 0.




*/
static int vdbeBindBlob(
  Vdbe *p,           /* Virtual machine */
  int i,             /* Var number to bind (numbered from 1 upward) */
  const char *zVal,  /* Pointer to blob of data */
  int bytes,         /* Number of bytes to copy */
  int copy,          /* True to copy the memory, false to copy a pointer */
  int flags          /* Valid combination of MEM_Blob, MEM_Str, MEM_UtfXX */
){
  Mem *pVar;


  vdbeUnbind(p, i);



  pVar = &p->apVar[i-1];

  if( zVal ){
    pVar->n = bytes;
    pVar->flags = flags;
    if( !copy ){
      pVar->z = (char *)zVal;
      pVar->flags |= MEM_Static;
    }else{
      if( bytes>NBFS ){
        pVar->z = (char *)sqliteMalloc(bytes);
        if( !pVar->z ){

          return SQLITE_NOMEM;
        }
        pVar->flags |= MEM_Dyn;
      }else{
        pVar->z = pVar->zShort;
        pVar->flags |= MEM_Short;
      }
................................................................................
  int flags = MEM_Str|MEM_Utf16le|MEM_Utf16be;

  if( zData ){
    /* If nData is less than zero, measure the length of the string. 
    ** manually. In this case the variable will always be null terminated.
    */
    if( nData<0 ){
      nData = sqlite3utf16ByteLen(zData) + 2;
      flags |= MEM_Term;
    }else{
      /* If nData is greater than zero, check if the final character appears
      ** to be a terminator.
      */
      if( !(((u8 *)zData)[nData-1]) && !(((u8 *)zData)[nData-2]) ){
        flags |= MEM_Term;







|
>
>
>
>




>



>








>





|
>
>
>
>










>

|
>
>
>












>







 







|







940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
....
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
    sqlite3ResetInternalSchema(db, 0);
  }
  return rc;
}

/*
** Unbind the value bound to variable $i in virtual machine p. This is the 
** the same as binding a NULL value to the column. If the "i" parameter is
** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK.
**
** The error code stored in database p->db is overwritten with the return
** value in any case.
*/
static int vdbeUnbind(Vdbe *p, int i){
  Mem *pVar;
  if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 ){
    sqlite3Error(p->db, SQLITE_MISUSE, 0);
    return SQLITE_MISUSE;
  }
  if( i<1 || i>p->nVar ){
    sqlite3Error(p->db, SQLITE_RANGE, 0);
    return SQLITE_RANGE;
  }
  i--;
  pVar = &p->apVar[i];
  if( pVar->flags&MEM_Dyn ){
    sqliteFree(pVar->z);
  }
  pVar->flags = MEM_Null;
  sqlite3Error(p->db, SQLITE_OK, 0);
  return SQLITE_OK;
}

/*
** This routine is used to bind text or blob data to an SQL variable (a ?).
** It may also be used to bind a NULL value, by setting zVal to 0. Any
** existing value is unbound.
**
** The error code stored in p->db is overwritten with the return value in
** all cases.
*/
static int vdbeBindBlob(
  Vdbe *p,           /* Virtual machine */
  int i,             /* Var number to bind (numbered from 1 upward) */
  const char *zVal,  /* Pointer to blob of data */
  int bytes,         /* Number of bytes to copy */
  int copy,          /* True to copy the memory, false to copy a pointer */
  int flags          /* Valid combination of MEM_Blob, MEM_Str, MEM_UtfXX */
){
  Mem *pVar;
  int rc;

  rc = vdbeUnbind(p, i);
  if( rc!=SQLITE_OK ){
    return rc;
  }
  pVar = &p->apVar[i-1];

  if( zVal ){
    pVar->n = bytes;
    pVar->flags = flags;
    if( !copy ){
      pVar->z = (char *)zVal;
      pVar->flags |= MEM_Static;
    }else{
      if( bytes>NBFS ){
        pVar->z = (char *)sqliteMalloc(bytes);
        if( !pVar->z ){
          sqlite3Error(p->db, SQLITE_NOMEM, 0);
          return SQLITE_NOMEM;
        }
        pVar->flags |= MEM_Dyn;
      }else{
        pVar->z = pVar->zShort;
        pVar->flags |= MEM_Short;
      }
................................................................................
  int flags = MEM_Str|MEM_Utf16le|MEM_Utf16be;

  if( zData ){
    /* If nData is less than zero, measure the length of the string. 
    ** manually. In this case the variable will always be null terminated.
    */
    if( nData<0 ){
      nData = sqlite3utf16ByteLen(zData, -1) + 2;
      flags |= MEM_Term;
    }else{
      /* If nData is greater than zero, check if the final character appears
      ** to be a terminator.
      */
      if( !(((u8 *)zData)[nData-1]) && !(((u8 *)zData)[nData-2]) ){
        flags |= MEM_Term;

Changes to test/bind.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
186
187
188
189
190
191
192

193
























194
195
196
197
198
199
#    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.2 2004/05/20 01:12:35 danielk1977 Exp $
#

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

do_test bind-1.1 {
  db close
................................................................................
} {TEXT TEXT TEXT}
do_test bind-7.3 {
  execsql {
    DELETE FROM t1;
  }
} {}


do_test bind-8.99 {
























  sqlite_finalize $VM
} {}



finish_test







|







 







>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#    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.3 2004/05/20 11:00:53 danielk1977 Exp $
#

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

do_test bind-1.1 {
  db close
................................................................................
} {TEXT TEXT TEXT}
do_test bind-7.3 {
  execsql {
    DELETE FROM t1;
  }
} {}

# Test that the 'out of range' error works.
do_test bind-8.1 {
  catch { sqlite3_bind_null $VM 0 }
} {1}
do_test bind-8.2 {
  sqlite3_errmsg $DB
} {bind index out of range}
do_test bind-8.3 {
  encoding convertfrom unicode [sqlite3_errmsg16 $DB]
} {bind index out of range}
do_test bind-8.4 {
  sqlite3_bind_null $VM 1 
  sqlite3_errmsg $DB
} {not an error}
do_test bind-8.5 {
  catch { sqlite3_bind_null $VM 4 }
} {1}
do_test bind-8.6 {
  sqlite3_errmsg $DB
} {bind index out of range}
do_test bind-8.7 {
  encoding convertfrom unicode [sqlite3_errmsg16 $DB]
} {bind index out of range}


do_test bind-9.99 {
  sqlite_finalize $VM
} {}



finish_test

Added test/capi3.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
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# 2003 January 29
#
# 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 callback-free C/C++ API.
#
# $Id: capi3.test,v 1.1 2004/05/20 11:00:53 danielk1977 Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
proc utf16 {str {nt 1}} {
  set r [encoding convertto unicode $str]
  if {$nt} {
    append r "\x00\x00"
  }
  return $r
}

# Return the UTF-8 representation of the supplied UTF-16 string $str. 
proc utf8 {str} {
  # If $str ends in two 0x00 0x00 bytes, knock these off before
  # converting to UTF-8 using TCL.
  binary scan $str \c* vals
  if {[lindex $vals end]==0 && [lindex $vals end-1]==0} {
    set str [binary format \c* [lrange $vals 0 end-2]]
  }

  set r [encoding convertfrom unicode $str]
  return $r
}

# These tests complement those in capi2.test. They are organized
# as follows:
#
# capi3-1.*: Test sqlite3_prepare 
# capi3-2.*: Test sqlite3_prepare16
#

db close
set DB [sqlite db test.db]

do_test capi3-1.1 {
  set STMT [sqlite3_prepare $DB {SELECT name FROM sqlite_master} -1 TAIL]
  sqlite_finalize $STMT
  set TAIL
} {}
do_test capi3-1.2 {
  sqlite3_errcode $DB
} {SQLITE_OK}
do_test capi3-1.3 {
  sqlite3_errmsg $DB
} {not an error}
do_test capi3-1.4 {
  set sql {SELECT name FROM sqlite_master;SELECT 10}
  set STMT [sqlite3_prepare $DB $sql -1 TAIL]
  sqlite_finalize $STMT
  set TAIL
} {SELECT 10}
do_test capi3-1.5 {
  set sql {SELECT namex FROM sqlite_master}
  catch {
    set STMT [sqlite3_prepare $DB $sql -1 TAIL]
  }
} {1}
do_test capi3-1.6 {
  sqlite3_errcode $DB
} {SQLITE_ERROR}
do_test capi3-1.7 {
  sqlite3_errmsg $DB
} {no such column: namex}

do_test capi3-2.1 {
  set sql16 [utf16 {SELECT name FROM sqlite_master}]
  set STMT [sqlite3_prepare16 $DB $sql16 -1 ::TAIL]
  sqlite_finalize $STMT
  utf8 $::TAIL
} {}
do_test capi3-2.2 {
  set sql [utf16 {SELECT name FROM sqlite_master;SELECT 10}]
  set STMT [sqlite3_prepare16 $DB $sql -1 TAIL]
  sqlite_finalize $STMT
  utf8 $TAIL
} {SELECT 10}
do_test capi3-2.3 {
  set sql [utf16 {SELECT namex FROM sqlite_master}]
  catch {
    set STMT [sqlite3_prepare16 $DB $sql -1 TAIL]
  }
} {1}
do_test capi3-2.4 {
  sqlite3_errcode $DB
} {SQLITE_ERROR}
do_test capi3-2.5 {
  sqlite3_errmsg $DB
} {no such column: namex}

finish_test