SQLite

Check-in [4e602bb473]
Login

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

Overview
Comment:Tests for text encoding conversion functions. Also new sqlite3_bindXX APIs. (CVS 1400)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 4e602bb473e22cc45de2f5788c035d18586cb836
User & Date: danielk1977 2004-05-19 10:34:52.000
Context
2004-05-19
10:34
Tests for text encoding conversion functions. Also new sqlite3_bindXX APIs. (CVS 1401) (check-in: 33293ae184 user: danielk1977 tags: trunk)
10:34
Tests for text encoding conversion functions. Also new sqlite3_bindXX APIs. (CVS 1400) (check-in: 4e602bb473 user: danielk1977 tags: trunk)
2004-05-18
23:21
Add definitions of the CollSeq and KeyInfo structures. (CVS 1399) (check-in: cd1be81569 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/sqlite.h.in.
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 header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.63 2004/05/10 16:18:48 drh 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++.







|







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 header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.64 2004/05/19 10:34: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++.
857
858
859
860
861
862
863










864
865
866
867
868
869
870
** 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);











#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.







>
>
>
>
>
>
>
>
>
>







857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
** 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;

int sqlite3_bind_int32(sqlite3_stmt*, int i, int iValue);
int sqlite3_bind_int64(sqlite3_stmt*, int i, long long int iValue);
int sqlite3_bind_double(sqlite3_stmt*, int i, double iValue);
int sqlite3_bind_null(sqlite3_stmt*, int i);
int sqlite3_bind_text(sqlite3_stmt*, int i, const char*, int n, int eCopy);
int sqlite3_bind_text16(sqlite3_stmt*, int i, const void*, int, int eCopy);
int sqlite3_bind_blob(sqlite3_stmt*, int i, const void*, 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.
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
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_bind_int32(sqlite3_stmt*, int iParm, int iValue);
int sqlite3_bind_int64(sqlite3_stmt*, int iParm, long long int iValue);
int sqlite3_bind_double(sqlite3_stmt*, int iParm, double iValue);
int sqlite3_bind_null(sqlite3_stmt*, int iParm);
int sqlite3_bind_text(sqlite3_stmt*, int i, const char*, int n, int eCopy);
int sqlite3_bind_text16(sqlite3_stmt*, int i, const void*, int, int eCopy);
int sqlite3_bind_blob(sqlite3_stmt*, int i, const void*, int n, int eCopy);

int sqlite3_step(sqlite3_stmt*);

#define SQLITE3_INTEGER  1
#define SQLITE3_FLOAT    2
#define SQLITE3_TEXT     3
#define SQLITE3_BLOB     4
#define SQLITE3_NULL     5







<
<
<
<
<
<
<
<







893
894
895
896
897
898
899








900
901
902
903
904
905
906
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
#define SQLITE3_TEXT     3
#define SQLITE3_BLOB     4
#define SQLITE3_NULL     5
Changes to src/test5.c.
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
/*
** 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.
**
*************************************************************************
** Code for testing the utf.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.


**
** $Id: 
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
** Return the number of bytes up to and including the first \u0000 
** character in *pStr.
*/
static int utf16_length(const unsigned char *pZ){
  const unsigned char *pC1 = pZ;
  const unsigned char *pC2 = pZ+1;
  while( *pC1 || *pC2 ){
    pC1 += 2;
    pC2 += 2;













|
>
>

|







|
|







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
/*
** 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.
**
*************************************************************************
** Code for testing the utf.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library. Specifically, the code in this file
** is used for testing the SQLite routines for converting between
** the various supported unicode encodings.
**
** $Id: test5.c,v 1.4 2004/05/19 10:34:53 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
** Return the number of bytes up to and including the first pair of
** 0x00 bytes in *pStr.
*/
static int utf16_length(const unsigned char *pZ){
  const unsigned char *pC1 = pZ;
  const unsigned char *pC2 = pZ+1;
  while( *pC1 || *pC2 ){
    pC1 += 2;
    pC2 += 2;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
        Tcl_GetStringFromObj(objv[0], 0), "<utf-8 encoded-string>", 0);
    return TCL_ERROR;
  }

  in = Tcl_GetByteArrayFromObj(objv[1], 0);
  out = (unsigned char *)sqlite3utf8to16le(in, -1);
  res = Tcl_NewByteArrayObj(out, utf16_length(out));
  sqliteFree(out);

  Tcl_SetObjResult(interp, res);

  return TCL_OK;
}

static int sqlite_utf8to16be(







|


|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
        Tcl_GetStringFromObj(objv[0], 0), "<utf-8 encoded-string>", 0);
    return TCL_ERROR;
  }

  in = Tcl_GetString(objv[1]);
  out = (unsigned char *)sqlite3utf8to16le(in, -1);
  res = Tcl_NewByteArrayObj(out, utf16_length(out));
  sqliteFree(out); 

  Tcl_SetObjResult(interp, res);

  return TCL_OK;
}

static int sqlite_utf8to16be(
73
74
75
76
77
78
79

80
81
82
83
84
85
86
  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
        Tcl_GetStringFromObj(objv[0], 0), "<utf-8 encoded-string>", 0);
    return TCL_ERROR;
  }

  in = Tcl_GetByteArrayFromObj(objv[1], 0);

  out = (unsigned char *)sqlite3utf8to16be(in, -1);
  res = Tcl_NewByteArrayObj(out, utf16_length(out));
  sqliteFree(out);

  Tcl_SetObjResult(interp, res);

  return TCL_OK;







>







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
        Tcl_GetStringFromObj(objv[0], 0), "<utf-8 encoded-string>", 0);
    return TCL_ERROR;
  }

  in = Tcl_GetByteArrayFromObj(objv[1], 0);
  in = Tcl_GetString(objv[1]);
  out = (unsigned char *)sqlite3utf8to16be(in, -1);
  res = Tcl_NewByteArrayObj(out, utf16_length(out));
  sqliteFree(out);

  Tcl_SetObjResult(interp, res);

  return TCL_OK;
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173






















174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198
199
){
  unsigned char *out;
  unsigned char *in;
  Tcl_Obj *res;

  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
        Tcl_GetStringFromObj(objv[0], 0), "<utf-16 encoded-string>", 0);
    return TCL_ERROR;
  }

  in = Tcl_GetByteArrayFromObj(objv[1], 0);
  out = sqlite3utf16to8(in, -1);
  res = Tcl_NewByteArrayObj(out, strlen(out));
  sqliteFree(out);

  Tcl_SetObjResult(interp, res);

  return TCL_OK;
}
























/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest5_Init(Tcl_Interp *interp){
  static struct {
    char *zName;
    Tcl_CmdProc *xProc;
  } aCmd[] = {
    { "sqlite_utf16to8",         (Tcl_CmdProc*)sqlite_utf16to8    },
    { "sqlite_utf8to16le",       (Tcl_CmdProc*)sqlite_utf8to16le  },
    { "sqlite_utf8to16be",       (Tcl_CmdProc*)sqlite_utf8to16be  },
    { "sqlite_utf16to16le",      (Tcl_CmdProc*)sqlite_utf16to16le },
    { "sqlite_utf16to16be",      (Tcl_CmdProc*)sqlite_utf16to16be }

  };
  int i;
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }

  return TCL_OK;
}










|





|






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








|

|
|
|
|
|
>



|







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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
225
){
  unsigned char *out;
  unsigned char *in;
  Tcl_Obj *res;

  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
        Tcl_GetStringFromObj(objv[0], 0), " <utf-16 encoded-string>", 0);
    return TCL_ERROR;
  }

  in = Tcl_GetByteArrayFromObj(objv[1], 0);
  out = sqlite3utf16to8(in, -1);
  res = Tcl_NewByteArrayObj(out, strlen(out)+1);
  sqliteFree(out);

  Tcl_SetObjResult(interp, res);

  return TCL_OK;
}

/*
** The first argument is a TCL UTF-8 string. Return the byte array
** object with the encoded representation of the string, including
** the NULL terminator.
*/
static int binarize(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int len;
  char *bytes;
  Tcl_Obj *pRet;
  assert(objc==2);

  bytes = Tcl_GetStringFromObj(objv[1], &len);
  pRet = Tcl_NewByteArrayObj(bytes, len+1);
  Tcl_SetObjResult(interp, pRet);
  return TCL_OK;
}


/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest5_Init(Tcl_Interp *interp){
  static struct {
    char *zName;
    Tcl_ObjCmdProc *xProc;
  } aCmd[] = {
    { "sqlite_utf16to8",         (Tcl_ObjCmdProc*)sqlite_utf16to8    },
    { "sqlite_utf8to16le",       (Tcl_ObjCmdProc*)sqlite_utf8to16le  },
    { "sqlite_utf8to16be",       (Tcl_ObjCmdProc*)sqlite_utf8to16be  },
    { "sqlite_utf16to16le",      (Tcl_ObjCmdProc*)sqlite_utf16to16le },
    { "sqlite_utf16to16be",      (Tcl_ObjCmdProc*)sqlite_utf16to16be },
    { "binarize",                (Tcl_ObjCmdProc*)binarize }
  };
  int i;
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }

  return TCL_OK;
}



Changes to src/utf.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 to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.3 2004/05/08 08:23:40 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







|







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 to translate between UTF-8, 
** UTF-16, UTF-16BE, and UTF-16LE.
**
** $Id: utf.c,v 1.4 2004/05/19 10:34:57 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
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
  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}
  };
  static 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
  ** this UTF-8 character. 
  */







|

|







188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
  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
  ** this UTF-8 character. 
  */
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
  }

  /* 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;
  out.pZ = sqliteMalloc(in.n);
  if( !out.pZ ){
    return 0;
  }
  out.c = 0;

  big_endian = readUtf16Bom(&in);
  while( in.c<in.n ){







|







363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
  }

  /* 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;
  out.pZ = sqliteMalloc(out.n);
  if( !out.pZ ){
    return 0;
  }
  out.c = 0;

  big_endian = readUtf16Bom(&in);
  while( in.c<in.n ){
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
  }

  /* A UTF-16 encoding of a unicode string can require at most twice as
  ** much space to store as the same string encoded using UTF-8. Allocate
  ** this now.
  */
  out.n = (in.n*2) + 2;
  out.pZ = sqliteMalloc(in.n);
  if( !out.pZ ){
    return 0;
  }
  out.c = 0;

  while( in.c<in.n ){
    writeUtf16(&out, readUtf8(&in), big_endian);







|







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
  }

  /* A UTF-16 encoding of a unicode string can require at most twice as
  ** much space to store as the same string encoded using UTF-8. Allocate
  ** this now.
  */
  out.n = (in.n*2) + 2;
  out.pZ = sqliteMalloc(out.n);
  if( !out.pZ ){
    return 0;
  }
  out.c = 0;

  while( in.c<in.n ){
    writeUtf16(&out, readUtf8(&in), big_endian);
447
448
449
450
451
452
453
454







455
456
457



458
459
460
461
462
463
464
  inout.n = N;

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

  if( readUtf16Bom(&inout)!=big_endian ){
    swab(&inout.pZ[inout.c], inout.pZ, inout.n-inout.c);







  }else if( inout.c ){
    memmove(inout.pZ, &inout.pZ[inout.c], inout.n-inout.c);
  }



}

/*
** Convert a string in UTF-16 native byte or with a BOM into a UTF-16LE
** string.  The conversion occurs in-place.  The output overwrites the
** input.  N bytes are converted.  If N is negative everything is converted
** up to the first \u0000 character.







|
>
>
>
>
>
>
>



>
>
>







447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
  inout.n = N;

  if( inout.n<0 ){
    inout.n = utf16Bytelen(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];
      char c2 = inout.pZ[i+inout.c+1];
      inout.pZ[i] = c2;
      inout.pZ[i+1] = c1;
    }
  }else if( inout.c ){
    memmove(inout.pZ, &inout.pZ[inout.c], inout.n-inout.c);
  }

  inout.pZ[inout.n-inout.c] = 0x00;
  inout.pZ[inout.n-inout.c+1] = 0x00;
}

/*
** Convert a string in UTF-16 native byte or with a BOM into a UTF-16LE
** string.  The conversion occurs in-place.  The output overwrites the
** input.  N bytes are converted.  If N is negative everything is converted
** up to the first \u0000 character.
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.84 2004/05/18 22:03:43 drh 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.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.
1176
1177
1178
1179
1180
1181
1182

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








>
1176
1177
1178
1179
1180
1181
1182
1183
  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.299 2004/05/18 22:17:46 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.300 2004/05/19 10:35:01 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
848
849
850
851
852
853
854
855
856









857









858
859

860







861
862

863
864
865
866
867
868
869
** Any occurance of the '?' character in the original SQL is considered
** a variable.  Variables in the SQL string are number from left to
** right beginning with 1.  The values of variables are set using the
** sqlite3_bind() API.
*/
case OP_Variable: {
  int j = pOp->p1 - 1;
  pTos++;
  if( j>=0 && j<p->nVar && p->azVar[j]!=0 ){









    pTos->z = p->azVar[j];









    pTos->n = p->anVar[j];
    pTos->flags = MEM_Str | MEM_Static;

  }else{







    pTos->flags = MEM_Null;
  }

  break;
}

/* Opcode: Pop P1 * *
**
** P1 elements are popped off of the top of stack and discarded.
*/







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

>







848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
** Any occurance of the '?' character in the original SQL is considered
** a variable.  Variables in the SQL string are number from left to
** right beginning with 1.  The values of variables are set using the
** sqlite3_bind() API.
*/
case OP_Variable: {
  int j = pOp->p1 - 1;
  Mem *pVar;
  assert( j>=0 && j<p->nVar );

  /* If we need to translate between text encodings, do it now. If this is
  ** required, then put the new string in p->azVar. This way, if the
  ** variable is used again, even after the virtual machine is reset, the
  ** conversion won't have to be done again.
  **
  ** TODO: This is where we need to support databases that use other than
  ** UTF-8 on disk.
  */
  pVar = &p->azVar[j];
  if( pVar->flags&MEM_Str && !(pVar->flags&MEM_Utf8) ){
    char *zUtf8;
    assert( pVar->flags&(MEM_Utf16le|MEM_Utf16be) );
    zUtf8 = sqlite3utf16to8(pVar->z, pVar->n);
    if( !zUtf8 ){
      goto no_mem;
    }
    Release(pVar);
    pVar->z = zUtf8;
    pVar->n = strlen(zUtf8)+1;
    pVar->flags = MEM_Str|MEM_Dyn;
  }

  /* Copy the value in pVar to the top of the stack. If pVar is a string or
  ** a blob just store a pointer to the same memory, do not make a copy.
  */
  pTos++;
  memcpy(pTos, pVar, sizeof(*pVar)-NBFS);
  if( pTos->flags&(MEM_Str|MEM_Blob) ){
    pTos->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Short);
    pTos->flags |= MEM_Static;
  }

  break;
}

/* Opcode: Pop P1 * *
**
** P1 elements are popped off of the top of stack and discarded.
*/
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
    ** On the other hand, it does burn CPU cycles every time through
    ** the evaluator loop.  So we can leave it out when NDEBUG is defined.
    */
#ifndef NDEBUG
    /* Sanity checking on the top element of the stack */
    if( pTos>=p->aStack ){
      assert( pTos->flags!=0 );  /* Must define some type */
      if( pTos->flags & MEM_Str ){
        int x = pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
        assert( x!=0 );            /* Strings must define a string subtype */
        assert( (x & (x-1))==0 );  /* Only one string subtype can be defined */
        assert( pTos->z!=0 );      /* Strings must have a value */
        /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
        assert( (pTos->flags & MEM_Short)==0 || pTos->z==pTos->zShort );
        assert( (pTos->flags & MEM_Short)!=0 || pTos->z!=pTos->zShort );







|







5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
    ** On the other hand, it does burn CPU cycles every time through
    ** the evaluator loop.  So we can leave it out when NDEBUG is defined.
    */
#ifndef NDEBUG
    /* Sanity checking on the top element of the stack */
    if( pTos>=p->aStack ){
      assert( pTos->flags!=0 );  /* Must define some type */
      if( pTos->flags & (MEM_Str|MEM_Blob) ){
        int x = pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
        assert( x!=0 );            /* Strings must define a string subtype */
        assert( (x & (x-1))==0 );  /* Only one string subtype can be defined */
        assert( pTos->z!=0 );      /* Strings must have a value */
        /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
        assert( (pTos->flags & MEM_Short)==0 || pTos->z==pTos->zShort );
        assert( (pTos->flags & MEM_Short)!=0 || pTos->z!=pTos->zShort );