SQLite4
Check-in [d1966c57fa]
Not logged in

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

Overview
Comment:Modify sqlite4_column_text() and sqlite4_value_text() to return (const char *) instead of (const unsigned char *).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d1966c57fa393bd1d3dc647b1ae00ef2e2f82d49
User & Date: dan 2013-05-08 17:24:34
Context
2013-05-09
18:11
Have sqlite4_column_text() and other functions return the size of the returned buffer in bytes via an optional output parameter. Remove sqlite4_column_bytes() and similar. check-in: 51c6f56d73 user: dan tags: trunk
2013-05-08
17:24
Modify sqlite4_column_text() and sqlite4_value_text() to return (const char *) instead of (const unsigned char *). check-in: d1966c57fa user: dan tags: trunk
14:37
Add tests for authorizer_push() and authorizer_pop(). check-in: 0263259ac4 user: dan tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/alter.c.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
..
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
...
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
137
138
139
140
141
...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
...
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
**     -> 'CREATE INDEX i ON def(a, b, c)'
*/
static void renameTableFunc(
  sqlite4_context *context,
  int NotUsed,
  sqlite4_value **argv
){
  unsigned char const *zSql = sqlite4_value_text(argv[0]);
  unsigned char const *zTableName = sqlite4_value_text(argv[1]);

  int token;
  Token tname;
  unsigned char const *zCsr = zSql;
  int len = 0;
  char *zRet;

  sqlite4 *db = sqlite4_context_db_handle(context);

  UNUSED_PARAMETER(NotUsed);

................................................................................
      tname.n = len;

      /* Advance zCsr to the next token. Store that token type in 'token',
      ** and its length in 'len' (to be used next iteration of this loop).
      */
      do {
        zCsr += len;
        len = sqlite4GetToken(zCsr, &token);
      } while( token==TK_SPACE );
      assert( len>0 );
    } while( token!=TK_LP && token!=TK_USING );

    zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, 
       zTableName, tname.z+tname.n);
    sqlite4_result_text(context, zRet, -1, SQLITE4_TRANSIENT, 0);
    sqlite4DbFree(db, zRet);
  }
}

/*
................................................................................
  sqlite4_context *context,
  int NotUsed,
  sqlite4_value **argv
){
  sqlite4 *db = sqlite4_context_db_handle(context);
  char *zOutput = 0;
  char *zResult;
  unsigned char const *zInput = sqlite4_value_text(argv[0]);
  unsigned char const *zOld = sqlite4_value_text(argv[1]);
  unsigned char const *zNew = sqlite4_value_text(argv[2]);

  unsigned const char *z;         /* Pointer to token */
  int n;                          /* Length of token z */
  int token;                      /* Type of token */

  UNUSED_PARAMETER(NotUsed);
  for(z=zInput; *z; z=z+n){
    n = sqlite4GetToken(z, &token);
    if( token==TK_REFERENCES ){
      char *zParent;
      do {
        z += n;
        n = sqlite4GetToken(z, &token);
      }while( token==TK_SPACE );

      zParent = sqlite4DbStrNDup(db, (const char *)z, n);
      if( zParent==0 ) break;
      sqlite4Dequote(zParent);
      if( 0==sqlite4_stricmp((const char *)zOld, zParent) ){
        char *zOut = sqlite4MPrintf(db, "%s%.*s\"%w\"", 
            (zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew
        );
        sqlite4DbFree(db, zOutput);
        zOutput = zOut;
        zInput = &z[n];
      }
      sqlite4DbFree(db, zParent);
    }
................................................................................
** TRIGGER, not CREATE INDEX and CREATE TABLE.
*/
static void renameTriggerFunc(
  sqlite4_context *context,
  int NotUsed,
  sqlite4_value **argv
){
  unsigned char const *zSql = sqlite4_value_text(argv[0]);
  unsigned char const *zTableName = sqlite4_value_text(argv[1]);

  int token;
  Token tname;
  int dist = 3;
  unsigned char const *zCsr = zSql;
  int len = 0;
  char *zRet;
  sqlite4 *db = sqlite4_context_db_handle(context);

  UNUSED_PARAMETER(NotUsed);

  /* The principle used to locate the table name in the CREATE TRIGGER 
................................................................................
      tname.n = len;

      /* Advance zCsr to the next token. Store that token type in 'token',
      ** and its length in 'len' (to be used next iteration of this loop).
      */
      do {
        zCsr += len;
        len = sqlite4GetToken(zCsr, &token);
      }while( token==TK_SPACE );
      assert( len>0 );

      /* Variable 'dist' stores the number of tokens read since the most
      ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN 
      ** token is read and 'dist' equals 2, the condition stated above
      ** to be met.
................................................................................
        dist = 0;
      }
    } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );

    /* Variable tname now contains the token that is the old table-name
    ** in the CREATE TRIGGER statement.
    */
    zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, 
       zTableName, tname.z+tname.n);
    sqlite4_result_text(context, zRet, -1, SQLITE4_TRANSIENT, 0);
    sqlite4DbFree(db, zRet);
  }
}
#endif   /* !SQLITE4_OMIT_TRIGGER */








|
|



|







 







|




|







 







|
|
|

|





|




|





|

|







 







|
|




|







 







|







 







|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
..
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
...
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
137
138
139
140
141
...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
...
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
**     -> 'CREATE INDEX i ON def(a, b, c)'
*/
static void renameTableFunc(
  sqlite4_context *context,
  int NotUsed,
  sqlite4_value **argv
){
  char const *zSql = sqlite4_value_text(argv[0]);
  char const *zTableName = sqlite4_value_text(argv[1]);

  int token;
  Token tname;
  char const *zCsr = zSql;
  int len = 0;
  char *zRet;

  sqlite4 *db = sqlite4_context_db_handle(context);

  UNUSED_PARAMETER(NotUsed);

................................................................................
      tname.n = len;

      /* Advance zCsr to the next token. Store that token type in 'token',
      ** and its length in 'len' (to be used next iteration of this loop).
      */
      do {
        zCsr += len;
        len = sqlite4GetToken((u8*)zCsr, &token);
      } while( token==TK_SPACE );
      assert( len>0 );
    } while( token!=TK_LP && token!=TK_USING );

    zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql, 
       zTableName, tname.z+tname.n);
    sqlite4_result_text(context, zRet, -1, SQLITE4_TRANSIENT, 0);
    sqlite4DbFree(db, zRet);
  }
}

/*
................................................................................
  sqlite4_context *context,
  int NotUsed,
  sqlite4_value **argv
){
  sqlite4 *db = sqlite4_context_db_handle(context);
  char *zOutput = 0;
  char *zResult;
  char const *zInput = sqlite4_value_text(argv[0]);
  char const *zOld = sqlite4_value_text(argv[1]);
  char const *zNew = sqlite4_value_text(argv[2]);

  const char *z;                  /* Pointer to token */
  int n;                          /* Length of token z */
  int token;                      /* Type of token */

  UNUSED_PARAMETER(NotUsed);
  for(z=zInput; *z; z=z+n){
    n = sqlite4GetToken((u8*)z, &token);
    if( token==TK_REFERENCES ){
      char *zParent;
      do {
        z += n;
        n = sqlite4GetToken((u8*)z, &token);
      }while( token==TK_SPACE );

      zParent = sqlite4DbStrNDup(db, (const char *)z, n);
      if( zParent==0 ) break;
      sqlite4Dequote(zParent);
      if( 0==sqlite4_stricmp(zOld, zParent) ){
        char *zOut = sqlite4MPrintf(db, "%s%.*s\"%w\"", 
            (zOutput?zOutput:""), z-zInput, zInput, zNew
        );
        sqlite4DbFree(db, zOutput);
        zOutput = zOut;
        zInput = &z[n];
      }
      sqlite4DbFree(db, zParent);
    }
................................................................................
** TRIGGER, not CREATE INDEX and CREATE TABLE.
*/
static void renameTriggerFunc(
  sqlite4_context *context,
  int NotUsed,
  sqlite4_value **argv
){
  char const *zSql = sqlite4_value_text(argv[0]);
  char const *zTableName = sqlite4_value_text(argv[1]);

  int token;
  Token tname;
  int dist = 3;
  char const *zCsr = zSql;
  int len = 0;
  char *zRet;
  sqlite4 *db = sqlite4_context_db_handle(context);

  UNUSED_PARAMETER(NotUsed);

  /* The principle used to locate the table name in the CREATE TRIGGER 
................................................................................
      tname.n = len;

      /* Advance zCsr to the next token. Store that token type in 'token',
      ** and its length in 'len' (to be used next iteration of this loop).
      */
      do {
        zCsr += len;
        len = sqlite4GetToken((u8*)zCsr, &token);
      }while( token==TK_SPACE );
      assert( len>0 );

      /* Variable 'dist' stores the number of tokens read since the most
      ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN 
      ** token is read and 'dist' equals 2, the condition stated above
      ** to be met.
................................................................................
        dist = 0;
      }
    } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );

    /* Variable tname now contains the token that is the old table-name
    ** in the CREATE TRIGGER statement.
    */
    zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", tname.z - zSql, zSql, 
       zTableName, tname.z+tname.n);
    sqlite4_result_text(context, zRet, -1, SQLITE4_TRANSIENT, 0);
    sqlite4DbFree(db, zRet);
  }
}
#endif   /* !SQLITE4_OMIT_TRIGGER */

Changes to src/date.c.

748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
static int isDate(
  sqlite4_context *context, 
  int argc, 
  sqlite4_value **argv, 
  DateTime *p
){
  int i;
  const unsigned char *z;
  int eType;
  memset(p, 0, sizeof(*p));
  if( argc==0 ){
    return setDateTimeToCurrent(context, p);
  }
  if( (eType = sqlite4_value_type(argv[0]))==SQLITE4_FLOAT
                   || eType==SQLITE4_INTEGER ){
    p->iJD = (sqlite4_int64)(sqlite4_value_double(argv[0])*86400000.0 + 0.5);
    p->validJD = 1;
  }else{
    z = sqlite4_value_text(argv[0]);
    if( !z || parseDateOrTime(context, (char*)z, p) ){
      return 1;
    }
  }
  for(i=1; i<argc; i++){
    z = sqlite4_value_text(argv[i]);
    if( z==0 || parseModifier(context, (char*)z, p) ) return 1;
  }
  return 0;
}


/*
** The following routines implement the various date and time functions







|











|





|







748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
static int isDate(
  sqlite4_context *context, 
  int argc, 
  sqlite4_value **argv, 
  DateTime *p
){
  int i;
  const char *z;
  int eType;
  memset(p, 0, sizeof(*p));
  if( argc==0 ){
    return setDateTimeToCurrent(context, p);
  }
  if( (eType = sqlite4_value_type(argv[0]))==SQLITE4_FLOAT
                   || eType==SQLITE4_INTEGER ){
    p->iJD = (sqlite4_int64)(sqlite4_value_double(argv[0])*86400000.0 + 0.5);
    p->validJD = 1;
  }else{
    z = sqlite4_value_text(argv[0]);
    if( !z || parseDateOrTime(context, z, p) ){
      return 1;
    }
  }
  for(i=1; i<argc; i++){
    z = sqlite4_value_text(argv[i]);
    if( z==0 || parseModifier(context, z, p) ) return 1;
  }
  return 0;
}


/*
** The following routines implement the various date and time functions

Changes to src/func.c.

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
...
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
...
685
686
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701
702
703
...
762
763
764
765
766
767
768
769
770
771

772
773
774
775
776
777
778
...
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
...
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
...
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
...
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
....
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
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
....
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
    case SQLITE4_BLOB:
    case SQLITE4_INTEGER:
    case SQLITE4_FLOAT: {
      sqlite4_result_int(context, sqlite4_value_bytes(argv[0]));
      break;
    }
    case SQLITE4_TEXT: {
      const unsigned char *z = sqlite4_value_text(argv[0]);
      if( z==0 ) return;
      len = 0;
      while( *z ){
        len++;
        SQLITE4_SKIP_UTF8(z);
      }
      sqlite4_result_int(context, len);
................................................................................
** If p2 is negative, return the p2 characters preceeding p1.
*/
static void substrFunc(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  const unsigned char *z;
  const unsigned char *z2;
  int len;
  int p0type;
  i64 p1, p2;
  int negP2 = 0;

  assert( argc==3 || argc==2 );
  if( sqlite4_value_type(argv[1])==SQLITE4_NULL
................................................................................
** Implementation of the upper() and lower() SQL functions.
*/
static void upperFunc(sqlite4_context *context, int argc, sqlite4_value **argv){
  char *z1;
  const char *z2;
  int i, n;
  UNUSED_PARAMETER(argc);
  z2 = (char*)sqlite4_value_text(argv[0]);
  n = sqlite4_value_bytes(argv[0]);
  /* Verify that the call to _bytes() does not invalidate the _text() pointer */
  assert( z2==(char*)sqlite4_value_text(argv[0]) );
  if( z2 ){
    z1 = contextMalloc(context, ((i64)n)+1);
    if( z1 ){
      for(i=0; i<n; i++){
        z1[i] = (char)sqlite4Toupper(z2[i]);
      }
      sqlite4_result_text(context, z1, n, SQLITE4_DYNAMIC, 0);
................................................................................
  }
}
static void lowerFunc(sqlite4_context *context, int argc, sqlite4_value **argv){
  char *z1;
  const char *z2;
  int i, n;
  UNUSED_PARAMETER(argc);
  z2 = (char*)sqlite4_value_text(argv[0]);
  n = sqlite4_value_bytes(argv[0]);
  /* Verify that the call to _bytes() does not invalidate the _text() pointer */
  assert( z2==(char*)sqlite4_value_text(argv[0]) );
  if( z2 ){
    z1 = contextMalloc(context, ((i64)n)+1);
    if( z1 ){
      for(i=0; i<n; i++){
        z1[i] = sqlite4Tolower(z2[i]);
      }
      sqlite4_result_text(context, z1, n, SQLITE4_DYNAMIC, 0);
................................................................................
** This routine is usually quick, but can be N**2 in the worst case.
**
** Hints: to match '*' or '?', put them in "[]".  Like this:
**
**         abc[*]xyz        Matches "abc*xyz" only
*/
static int patternCompare(
  const u8 *zPattern,              /* The glob pattern */
  const u8 *zString,               /* The string to compare against the glob */
  const struct compareInfo *pInfo, /* Information about how to do the compare */
  u32 esc                          /* The escape character */
){
  u32 c, c2;
  int invert;
  int seen;
  u8 matchOne = pInfo->matchOne;
................................................................................
** the GLOB operator.
*/
static void likeFunc(
  sqlite4_context *context, 
  int argc, 
  sqlite4_value **argv
){
  const unsigned char *zA, *zB;
  u32 escape = 0;
  int nPat;
  sqlite4 *db = sqlite4_context_db_handle(context);

  zB = sqlite4_value_text(argv[0]);
  zA = sqlite4_value_text(argv[1]);

................................................................................
  }
  assert( zB==sqlite4_value_text(argv[0]) );  /* Encoding did not change */

  if( argc==3 ){
    /* The escape character string must consist of a single UTF-8 character.
    ** Otherwise, return an error.
    */
    const unsigned char *zEsc = sqlite4_value_text(argv[2]);
    if( zEsc==0 ) return;
    if( sqlite4Utf8CharLen((char*)zEsc, -1)!=1 ){

      sqlite4_result_error(context, 
          "ESCAPE expression must be a single character", -1);
      return;
    }
    escape = sqlite4Utf8Read(zEsc, &zEsc);
  }
  if( zA && zB ){
    struct compareInfo *pInfo = sqlite4_user_data(context);
#ifdef SQLITE4_TEST
................................................................................
** its side-effects.
*/
static void errlogFunc(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  UNUSED_PARAMETER(argc);
  sqlite4_log(sqlite4_context_env(context),
              sqlite4_value_int(argv[0]), "%s", sqlite4_value_text(argv[1]));

}

/*
** Implementation of the sqlite_compileoption_used() function.
** The result is an integer that identifies if the compiler option
** was used to build SQLite.
*/
................................................................................
  const char *zOptName;
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL
  ** function is a wrapper around the sqlite4_compileoption_used() C/C++
  ** function.
  */
  if( (zOptName = (const char*)sqlite4_value_text(argv[0]))!=0 ){
    sqlite4_result_int(context, sqlite4_compileoption_used(zOptName));
  }
}
#endif /* SQLITE4_OMIT_COMPILEOPTION_DIAGS */

/*
** Implementation of the sqlite_compileoption_get() function. 
................................................................................
        sqlite4_free(sqlite4_context_env(context), zText);
      }
      break;
    }
    case SQLITE4_TEXT: {
      int i,j;
      u64 n;
      const unsigned char *zArg = sqlite4_value_text(argv[0]);
      char *z;

      if( zArg==0 ) return;
      for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
      z = contextMalloc(context, ((i64)i)+((i64)n)+3);
      if( z ){
        z[0] = '\'';
................................................................................
** must be exact.  Collating sequences are not used.
*/
static void replaceFunc(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  const unsigned char *zStr;        /* The input string A */
  const unsigned char *zPattern;    /* The pattern string B */
  const unsigned char *zRep;        /* The replacement string C */
  unsigned char *zOut;              /* The output */
  int nStr;                /* Size of zStr */
  int nPattern;            /* Size of zPattern */
  int nRep;                /* Size of zRep */
  i64 nOut;                /* Maximum size of zOut */
  int loopLimit;           /* Last zStr[] that might match zPattern[] */
  int i, j;                /* Loop counters */

................................................................................
    return;
  }
  loopLimit = nStr - nPattern;  
  for(i=j=0; i<=loopLimit; i++){
    if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
      zOut[j++] = zStr[i];
    }else{
      u8 *zOld;
      sqlite4 *db = sqlite4_context_db_handle(context);
      nOut += nRep - nPattern;
      testcase( nOut-1==db->aLimit[SQLITE4_LIMIT_LENGTH] );
      testcase( nOut-2==db->aLimit[SQLITE4_LIMIT_LENGTH] );
      if( nOut-1>db->aLimit[SQLITE4_LIMIT_LENGTH] ){
        sqlite4_result_error_toobig(context);
        sqlite4_free(db->pEnv, zOut);
................................................................................
    }
  }
  assert( j+nStr-i+1==nOut );
  memcpy(&zOut[j], &zStr[i], nStr-i);
  j += nStr - i;
  assert( j<=nOut );
  zOut[j] = 0;
  sqlite4_result_text(context, (char*)zOut, j, SQLITE4_DYNAMIC, 0);
}

/*
** Implementation of the TRIM(), LTRIM(), and RTRIM() functions.
** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both.
*/
static void trimFunc(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  const unsigned char *zIn;         /* Input string */
  const unsigned char *zCharSet;    /* Set of characters to trim */
  int nIn;                          /* Number of bytes in input */
  int flags;                        /* 1: trimleft  2: trimright  3: trim */
  int i;                            /* Loop counter */
  unsigned char *aLen = 0;          /* Length of each character in zCharSet */
  unsigned char **azChar = 0;       /* Individual characters in zCharSet */
  int nChar;                        /* Number of characters in zCharSet */

  if( sqlite4_value_type(argv[0])==SQLITE4_NULL ){
    return;
  }
  zIn = sqlite4_value_text(argv[0]);
  if( zIn==0 ) return;
  nIn = sqlite4_value_bytes(argv[0]);
  assert( zIn==sqlite4_value_text(argv[0]) );
  if( argc==1 ){
    static const unsigned char lenOne[] = { 1 };
    static unsigned char * const azOne[] = { (u8*)" " };
    nChar = 1;
    aLen = (u8*)lenOne;
    azChar = (unsigned char **)azOne;
    zCharSet = 0;
  }else if( (zCharSet = sqlite4_value_text(argv[1]))==0 ){
    return;
  }else{
    const unsigned char *z;
    for(z=zCharSet, nChar=0; *z; nChar++){
      SQLITE4_SKIP_UTF8(z);
    }
    if( nChar>0 ){
      azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1));
      if( azChar==0 ){
        return;
      }
      aLen = (unsigned char*)&azChar[nChar];
      for(z=zCharSet, nChar=0; *z; nChar++){
        azChar[nChar] = (unsigned char *)z;
        SQLITE4_SKIP_UTF8(z);
        aLen[nChar] = (u8)(z - azChar[nChar]);
      }
    }
  }
  if( nChar>0 ){
    flags = SQLITE4_PTR_TO_INT(sqlite4_user_data(context));
................................................................................
        nIn -= len;
      }
    }
    if( zCharSet ){
      sqlite4_free(sqlite4_context_env(context), azChar);
    }
  }
  sqlite4_result_text(context, (char*)zIn, nIn, SQLITE4_TRANSIENT, 0);
}


/* IMP: R-25361-16150 This function is omitted from SQLite by default. It
** is only available if the SQLITE4_SOUNDEX compile-time option is used
** when SQLite is built.
*/







|







 







|
|







 







|


|







 







|


|







 







|
|







 







|







 







|

|
>
|
<







 







|
|
|
>







 







|







 







|







 







|
|
|
|







 







|







 







|











|
|
|
|
|
|
|
|










|


|




|










|







 







|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
...
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
...
685
686
687
688
689
690
691
692
693
694
695
696

697
698
699
700
701
702
703
...
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
...
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
...
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
...
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
...
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
....
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
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
....
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
    case SQLITE4_BLOB:
    case SQLITE4_INTEGER:
    case SQLITE4_FLOAT: {
      sqlite4_result_int(context, sqlite4_value_bytes(argv[0]));
      break;
    }
    case SQLITE4_TEXT: {
      const char *z = sqlite4_value_text(argv[0]);
      if( z==0 ) return;
      len = 0;
      while( *z ){
        len++;
        SQLITE4_SKIP_UTF8(z);
      }
      sqlite4_result_int(context, len);
................................................................................
** If p2 is negative, return the p2 characters preceeding p1.
*/
static void substrFunc(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  const char *z;
  const char *z2;
  int len;
  int p0type;
  i64 p1, p2;
  int negP2 = 0;

  assert( argc==3 || argc==2 );
  if( sqlite4_value_type(argv[1])==SQLITE4_NULL
................................................................................
** Implementation of the upper() and lower() SQL functions.
*/
static void upperFunc(sqlite4_context *context, int argc, sqlite4_value **argv){
  char *z1;
  const char *z2;
  int i, n;
  UNUSED_PARAMETER(argc);
  z2 = sqlite4_value_text(argv[0]);
  n = sqlite4_value_bytes(argv[0]);
  /* Verify that the call to _bytes() does not invalidate the _text() pointer */
  assert( z2==sqlite4_value_text(argv[0]) );
  if( z2 ){
    z1 = contextMalloc(context, ((i64)n)+1);
    if( z1 ){
      for(i=0; i<n; i++){
        z1[i] = (char)sqlite4Toupper(z2[i]);
      }
      sqlite4_result_text(context, z1, n, SQLITE4_DYNAMIC, 0);
................................................................................
  }
}
static void lowerFunc(sqlite4_context *context, int argc, sqlite4_value **argv){
  char *z1;
  const char *z2;
  int i, n;
  UNUSED_PARAMETER(argc);
  z2 = sqlite4_value_text(argv[0]);
  n = sqlite4_value_bytes(argv[0]);
  /* Verify that the call to _bytes() does not invalidate the _text() pointer */
  assert( z2==sqlite4_value_text(argv[0]) );
  if( z2 ){
    z1 = contextMalloc(context, ((i64)n)+1);
    if( z1 ){
      for(i=0; i<n; i++){
        z1[i] = sqlite4Tolower(z2[i]);
      }
      sqlite4_result_text(context, z1, n, SQLITE4_DYNAMIC, 0);
................................................................................
** This routine is usually quick, but can be N**2 in the worst case.
**
** Hints: to match '*' or '?', put them in "[]".  Like this:
**
**         abc[*]xyz        Matches "abc*xyz" only
*/
static int patternCompare(
  const char *zPattern,            /* The glob pattern */
  const char *zString,             /* The string to compare against the glob */
  const struct compareInfo *pInfo, /* Information about how to do the compare */
  u32 esc                          /* The escape character */
){
  u32 c, c2;
  int invert;
  int seen;
  u8 matchOne = pInfo->matchOne;
................................................................................
** the GLOB operator.
*/
static void likeFunc(
  sqlite4_context *context, 
  int argc, 
  sqlite4_value **argv
){
  const char *zA, *zB;
  u32 escape = 0;
  int nPat;
  sqlite4 *db = sqlite4_context_db_handle(context);

  zB = sqlite4_value_text(argv[0]);
  zA = sqlite4_value_text(argv[1]);

................................................................................
  }
  assert( zB==sqlite4_value_text(argv[0]) );  /* Encoding did not change */

  if( argc==3 ){
    /* The escape character string must consist of a single UTF-8 character.
    ** Otherwise, return an error.
    */
    const char *zEsc = sqlite4_value_text(argv[2]);
    if( zEsc==0 ) return;
    if( sqlite4Utf8CharLen(zEsc, -1)!=1 ){
      static const char *zErr = "ESCAPE expression must be a single character";
      sqlite4_result_error(context, zErr, -1);

      return;
    }
    escape = sqlite4Utf8Read(zEsc, &zEsc);
  }
  if( zA && zB ){
    struct compareInfo *pInfo = sqlite4_user_data(context);
#ifdef SQLITE4_TEST
................................................................................
** its side-effects.
*/
static void errlogFunc(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  int rclog = sqlite4_value_int(argv[0]);
  sqlite4_env *pEnv = sqlite4_context_env(context);
  sqlite4_log(pEnv, rclog, "%s", sqlite4_value_text(argv[1]));
  UNUSED_PARAMETER(argc);
}

/*
** Implementation of the sqlite_compileoption_used() function.
** The result is an integer that identifies if the compiler option
** was used to build SQLite.
*/
................................................................................
  const char *zOptName;
  assert( argc==1 );
  UNUSED_PARAMETER(argc);
  /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL
  ** function is a wrapper around the sqlite4_compileoption_used() C/C++
  ** function.
  */
  if( (zOptName = sqlite4_value_text(argv[0]))!=0 ){
    sqlite4_result_int(context, sqlite4_compileoption_used(zOptName));
  }
}
#endif /* SQLITE4_OMIT_COMPILEOPTION_DIAGS */

/*
** Implementation of the sqlite_compileoption_get() function. 
................................................................................
        sqlite4_free(sqlite4_context_env(context), zText);
      }
      break;
    }
    case SQLITE4_TEXT: {
      int i,j;
      u64 n;
      const char *zArg = sqlite4_value_text(argv[0]);
      char *z;

      if( zArg==0 ) return;
      for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
      z = contextMalloc(context, ((i64)i)+((i64)n)+3);
      if( z ){
        z[0] = '\'';
................................................................................
** must be exact.  Collating sequences are not used.
*/
static void replaceFunc(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  const char *zStr;        /* The input string A */
  const char *zPattern;    /* The pattern string B */
  const char *zRep;        /* The replacement string C */
  char *zOut;              /* The output */
  int nStr;                /* Size of zStr */
  int nPattern;            /* Size of zPattern */
  int nRep;                /* Size of zRep */
  i64 nOut;                /* Maximum size of zOut */
  int loopLimit;           /* Last zStr[] that might match zPattern[] */
  int i, j;                /* Loop counters */

................................................................................
    return;
  }
  loopLimit = nStr - nPattern;  
  for(i=j=0; i<=loopLimit; i++){
    if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){
      zOut[j++] = zStr[i];
    }else{
      char *zOld;
      sqlite4 *db = sqlite4_context_db_handle(context);
      nOut += nRep - nPattern;
      testcase( nOut-1==db->aLimit[SQLITE4_LIMIT_LENGTH] );
      testcase( nOut-2==db->aLimit[SQLITE4_LIMIT_LENGTH] );
      if( nOut-1>db->aLimit[SQLITE4_LIMIT_LENGTH] ){
        sqlite4_result_error_toobig(context);
        sqlite4_free(db->pEnv, zOut);
................................................................................
    }
  }
  assert( j+nStr-i+1==nOut );
  memcpy(&zOut[j], &zStr[i], nStr-i);
  j += nStr - i;
  assert( j<=nOut );
  zOut[j] = 0;
  sqlite4_result_text(context, zOut, j, SQLITE4_DYNAMIC, 0);
}

/*
** Implementation of the TRIM(), LTRIM(), and RTRIM() functions.
** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both.
*/
static void trimFunc(
  sqlite4_context *context,
  int argc,
  sqlite4_value **argv
){
  const char *zIn;                /* Input string */
  const char *zCharSet;           /* Set of characters to trim */
  int nIn;                        /* Number of bytes in input */
  int flags;                      /* 1: trimleft  2: trimright  3: trim */
  int i;                          /* Loop counter */
  u8 *aLen = 0;                   /* Length of each character in zCharSet */
  char **azChar = 0;              /* Individual characters in zCharSet */
  int nChar;                      /* Number of characters in zCharSet */

  if( sqlite4_value_type(argv[0])==SQLITE4_NULL ){
    return;
  }
  zIn = sqlite4_value_text(argv[0]);
  if( zIn==0 ) return;
  nIn = sqlite4_value_bytes(argv[0]);
  assert( zIn==sqlite4_value_text(argv[0]) );
  if( argc==1 ){
    static const unsigned char lenOne[] = { 1 };
    static char * const azOne[] = { " " };
    nChar = 1;
    aLen = (u8*)lenOne;
    azChar = (char**)azOne;
    zCharSet = 0;
  }else if( (zCharSet = sqlite4_value_text(argv[1]))==0 ){
    return;
  }else{
    const char *z;
    for(z=zCharSet, nChar=0; *z; nChar++){
      SQLITE4_SKIP_UTF8(z);
    }
    if( nChar>0 ){
      azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+1));
      if( azChar==0 ){
        return;
      }
      aLen = (unsigned char*)&azChar[nChar];
      for(z=zCharSet, nChar=0; *z; nChar++){
        azChar[nChar] = (char*)z;
        SQLITE4_SKIP_UTF8(z);
        aLen[nChar] = (u8)(z - azChar[nChar]);
      }
    }
  }
  if( nChar>0 ){
    flags = SQLITE4_PTR_TO_INT(sqlite4_user_data(context));
................................................................................
        nIn -= len;
      }
    }
    if( zCharSet ){
      sqlite4_free(sqlite4_context_env(context), azChar);
    }
  }
  sqlite4_result_text(context, zIn, nIn, SQLITE4_TRANSIENT, 0);
}


/* IMP: R-25361-16150 This function is omitted from SQLite by default. It
** is only available if the SQLITE4_SOUNDEX compile-time option is used
** when SQLite is built.
*/

Changes to src/sqlite.h.in.

2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
....
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
....
4030
4031
4032
4033
4034
4035
4036


4037
4038
4039
4040
4041
4042
4043
*/
const void *sqlite4_column_blob(sqlite4_stmt*, int iCol);
int sqlite4_column_bytes(sqlite4_stmt*, int iCol);
int sqlite4_column_bytes16(sqlite4_stmt*, int iCol);
double sqlite4_column_double(sqlite4_stmt*, int iCol);
int sqlite4_column_int(sqlite4_stmt*, int iCol);
sqlite4_int64 sqlite4_column_int64(sqlite4_stmt*, int iCol);
const unsigned char *sqlite4_column_text(sqlite4_stmt*, int iCol);
const void *sqlite4_column_text16(sqlite4_stmt*, int iCol);
int sqlite4_column_type(sqlite4_stmt*, int iCol);
sqlite4_value *sqlite4_column_value(sqlite4_stmt*, int iCol);

/*
** CAPIREF: Destroy A Prepared Statement Object
**
................................................................................
*/
const void *sqlite4_value_blob(sqlite4_value*);
int sqlite4_value_bytes(sqlite4_value*);
int sqlite4_value_bytes16(sqlite4_value*);
double sqlite4_value_double(sqlite4_value*);
int sqlite4_value_int(sqlite4_value*);
sqlite4_int64 sqlite4_value_int64(sqlite4_value*);
const unsigned char *sqlite4_value_text(sqlite4_value*);
const void *sqlite4_value_text16(sqlite4_value*);
const void *sqlite4_value_text16le(sqlite4_value*);
const void *sqlite4_value_text16be(sqlite4_value*);
int sqlite4_value_type(sqlite4_value*);
int sqlite4_value_numeric_type(sqlite4_value*);

/*
................................................................................
** ^The [sqlite4_strnicmp()] API allows applications and extensions to
** compare the contents of two buffers containing UTF-8 strings in a
** case-independent fashion, using the same definition of case independence 
** that SQLite uses internally when comparing identifiers.
*/
int sqlite4_stricmp(const char*, const char*);
int sqlite4_strnicmp(const char *, const char *, int);



/*
** CAPIREF: Error Logging Interface
**
** ^The [sqlite4_log()] interface writes a message into the error log
** established by the [SQLITE4_CONFIG_LOG] option to [sqlite4_env_config()].
** ^If logging is enabled, the zFormat string and subsequent arguments are







|







 







|







 







>
>







2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
....
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
....
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
*/
const void *sqlite4_column_blob(sqlite4_stmt*, int iCol);
int sqlite4_column_bytes(sqlite4_stmt*, int iCol);
int sqlite4_column_bytes16(sqlite4_stmt*, int iCol);
double sqlite4_column_double(sqlite4_stmt*, int iCol);
int sqlite4_column_int(sqlite4_stmt*, int iCol);
sqlite4_int64 sqlite4_column_int64(sqlite4_stmt*, int iCol);
const char *sqlite4_column_text(sqlite4_stmt*, int iCol);
const void *sqlite4_column_text16(sqlite4_stmt*, int iCol);
int sqlite4_column_type(sqlite4_stmt*, int iCol);
sqlite4_value *sqlite4_column_value(sqlite4_stmt*, int iCol);

/*
** CAPIREF: Destroy A Prepared Statement Object
**
................................................................................
*/
const void *sqlite4_value_blob(sqlite4_value*);
int sqlite4_value_bytes(sqlite4_value*);
int sqlite4_value_bytes16(sqlite4_value*);
double sqlite4_value_double(sqlite4_value*);
int sqlite4_value_int(sqlite4_value*);
sqlite4_int64 sqlite4_value_int64(sqlite4_value*);
const char *sqlite4_value_text(sqlite4_value*);
const void *sqlite4_value_text16(sqlite4_value*);
const void *sqlite4_value_text16le(sqlite4_value*);
const void *sqlite4_value_text16be(sqlite4_value*);
int sqlite4_value_type(sqlite4_value*);
int sqlite4_value_numeric_type(sqlite4_value*);

/*
................................................................................
** ^The [sqlite4_strnicmp()] API allows applications and extensions to
** compare the contents of two buffers containing UTF-8 strings in a
** case-independent fashion, using the same definition of case independence 
** that SQLite uses internally when comparing identifiers.
*/
int sqlite4_stricmp(const char*, const char*);
int sqlite4_strnicmp(const char *, const char *, int);

int sqlite4_tolower(int);

/*
** CAPIREF: Error Logging Interface
**
** ^The [sqlite4_log()] interface writes a message into the error log
** established by the [SQLITE4_CONFIG_LOG] option to [sqlite4_env_config()].
** ^If logging is enabled, the zFormat string and subsequent arguments are

Changes to src/sqliteInt.h.

2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
....
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
....
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
#define WRC_Prune       1   /* Omit children but continue walking siblings */
#define WRC_Abort       2   /* Abandon the tree walk */

/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
#define SQLITE4_SKIP_UTF8(zIn) {                        \
  if( (*(zIn++))>=0xc0 ){                              \
    while( (*zIn & 0xc0)==0x80 ){ zIn++; }             \
  }                                                    \
}

/*
** Default memory allocator
*/
................................................................................
int sqlite4FixExprList(DbFixer*, ExprList*);
int sqlite4FixTriggerStep(DbFixer*, TriggerStep*);
int sqlite4AtoF(const char *z, double*, int, u8);
int sqlite4GetInt32(const char *, int*);
int sqlite4Atoi(const char*);
int sqlite4Utf16ByteLen(const void *pData, int nChar);
int sqlite4Utf8CharLen(const char *pData, int nByte);
u32 sqlite4Utf8Read(const u8*, const u8**);

/*
** Routines to read and write variable-length integers.  These used to
** be defined locally, but now we use the varint routines in the util.c
** file.  Code should use the MACRO forms below, as the Varint32 versions
** are coded to assume the single byte case is already handled (which 
** the MACRO form does).
................................................................................
#ifndef SQLITE4_OMIT_LOAD_EXTENSION
  void sqlite4CloseExtensions(sqlite4*);
#else
# define sqlite4CloseExtensions(X)
#endif

#ifdef SQLITE4_TEST
  int sqlite4Utf8To8(unsigned char*);
#endif

#ifdef SQLITE4_OMIT_VIRTUALTABLE
#  define sqlite4VtabClear(Y)
#  define sqlite4VtabSync(X,Y) SQLITE4_OK
#  define sqlite4VtabRollback(X)
#  define sqlite4VtabCommit(X)







|
|







 







|







 







|







2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
....
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
....
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
#define WRC_Prune       1   /* Omit children but continue walking siblings */
#define WRC_Abort       2   /* Abandon the tree walk */

/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
*/
#define SQLITE4_SKIP_UTF8(zIn) {                       \
  if( (*(unsigned char *)(zIn++))>=0xc0 ){             \
    while( (*zIn & 0xc0)==0x80 ){ zIn++; }             \
  }                                                    \
}

/*
** Default memory allocator
*/
................................................................................
int sqlite4FixExprList(DbFixer*, ExprList*);
int sqlite4FixTriggerStep(DbFixer*, TriggerStep*);
int sqlite4AtoF(const char *z, double*, int, u8);
int sqlite4GetInt32(const char *, int*);
int sqlite4Atoi(const char*);
int sqlite4Utf16ByteLen(const void *pData, int nChar);
int sqlite4Utf8CharLen(const char *pData, int nByte);
u32 sqlite4Utf8Read(const char*, const char**);

/*
** Routines to read and write variable-length integers.  These used to
** be defined locally, but now we use the varint routines in the util.c
** file.  Code should use the MACRO forms below, as the Varint32 versions
** are coded to assume the single byte case is already handled (which 
** the MACRO form does).
................................................................................
#ifndef SQLITE4_OMIT_LOAD_EXTENSION
  void sqlite4CloseExtensions(sqlite4*);
#else
# define sqlite4CloseExtensions(X)
#endif

#ifdef SQLITE4_TEST
  int sqlite4Utf8To8(char*);
#endif

#ifdef SQLITE4_OMIT_VIRTUALTABLE
#  define sqlite4VtabClear(Y)
#  define sqlite4VtabSync(X,Y) SQLITE4_OK
#  define sqlite4VtabRollback(X)
#  define sqlite4VtabCommit(X)

Changes to src/utf.c.

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
...
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
...
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
...
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
      c = (c<<6) + (0x3f & *(zIn++));                      \
    }                                                      \
    if( c<0x80                                             \
        || (c&0xFFFFF800)==0xD800                          \
        || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }        \
  }
u32 sqlite4Utf8Read(
  const unsigned char *zIn,       /* First byte of UTF-8 character */
  const unsigned char **pzNext    /* Write first byte past UTF-8 char here */
){
  unsigned int c;

  /* Same as READ_UTF8() above but without the zTerm parameter.
  ** For this routine, we assume the UTF8 string is always zero-terminated.
  */
  c = *(zIn++);
  if( c>=0xc0 ){
    c = sqlite4Utf8Trans1[c-0xc0];
    while( (*zIn & 0xc0)==0x80 ){
      c = (c<<6) + (0x3f & *(zIn++));
    }
    if( c<0x80
        || (c&0xFFFFF800)==0xD800
................................................................................
/*
** Versions of stricmp and strnicmp that work with (simple) unicode
** case mapping.
*/
int sqlite4_stricmp(const char *zLeft, const char *zRight){
  unsigned char *a, *b;
  unsigned int ac, bc;
  int x;
  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  do{
    READ_UTF8(a, 0, ac);
    ac = sqlite4_tolower(ac);
    READ_UTF8(b, 0, bc);
    bc = sqlite4_tolower(bc);
  }while( ac==bc && ac!=0 );
  return ac - bc;
}
int sqlite4_strnicmp(const char *zLeft, const char *zRight, int N){
  unsigned char *a, *b, *aTerm, *bTerm;
  unsigned int ac, bc;
  int x;
  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  aTerm = a + N;
  bTerm = b + N;
  do{
    READ_UTF8(a, aTerm, ac);
    ac = sqlite4_tolower(ac);
................................................................................
**
** This has the effect of making sure that the string is well-formed
** UTF-8.  Miscoded characters are removed.
**
** The translation is done in-place and aborted if the output
** overruns the input.
*/
int sqlite4Utf8To8(unsigned char *zIn){
  unsigned char *zOut = zIn;
  unsigned char *zStart = zIn;
  u32 c;

  while( zIn[0] && zOut<=zIn ){
    c = sqlite4Utf8Read(zIn, (const u8**)&zIn);
    if( c!=0xfffd ){
      WRITE_UTF8(zOut, c);
    }
  }
  *zOut = 0;
  return (int)(zOut - zStart);
}
................................................................................
/*
** This routine is called from the TCL test function "translate_selftest".
** It checks that the primitives for serializing and deserializing
** characters in each encoding are inverses of each other.
*/
void sqlite4UtfSelfTest(void){
  unsigned int i, t;
  unsigned char zBuf[20];
  unsigned char *z;
  int n;
  unsigned int c;

  for(i=0; i<0x00110000; i++){
    z = zBuf;
    WRITE_UTF8(z, i);
    n = (int)(z-zBuf);
    assert( n>0 && n<=4 );
    z[0] = 0;
    z = zBuf;
    c = sqlite4Utf8Read(z, (const u8**)&z);
    t = i;
    if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
    if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
    assert( c==t );
    assert( (z-zBuf)==n );
  }
  for(i=0; i<0x00110000; i++){







|
|






|







 







<













<







 







|
|
|



|







 







|
|










|







160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
...
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
...
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
...
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
      c = (c<<6) + (0x3f & *(zIn++));                      \
    }                                                      \
    if( c<0x80                                             \
        || (c&0xFFFFF800)==0xD800                          \
        || (c&0xFFFFFFFE)==0xFFFE ){  c = 0xFFFD; }        \
  }
u32 sqlite4Utf8Read(
  const char *zIn,                /* First byte of UTF-8 character */
  const char **pzNext             /* Write first byte past UTF-8 char here */
){
  unsigned int c;

  /* Same as READ_UTF8() above but without the zTerm parameter.
  ** For this routine, we assume the UTF8 string is always zero-terminated.
  */
  c = *(unsigned char *)(zIn++);
  if( c>=0xc0 ){
    c = sqlite4Utf8Trans1[c-0xc0];
    while( (*zIn & 0xc0)==0x80 ){
      c = (c<<6) + (0x3f & *(zIn++));
    }
    if( c<0x80
        || (c&0xFFFFF800)==0xD800
................................................................................
/*
** Versions of stricmp and strnicmp that work with (simple) unicode
** case mapping.
*/
int sqlite4_stricmp(const char *zLeft, const char *zRight){
  unsigned char *a, *b;
  unsigned int ac, bc;

  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  do{
    READ_UTF8(a, 0, ac);
    ac = sqlite4_tolower(ac);
    READ_UTF8(b, 0, bc);
    bc = sqlite4_tolower(bc);
  }while( ac==bc && ac!=0 );
  return ac - bc;
}
int sqlite4_strnicmp(const char *zLeft, const char *zRight, int N){
  unsigned char *a, *b, *aTerm, *bTerm;
  unsigned int ac, bc;

  a = (unsigned char *)zLeft;
  b = (unsigned char *)zRight;
  aTerm = a + N;
  bTerm = b + N;
  do{
    READ_UTF8(a, aTerm, ac);
    ac = sqlite4_tolower(ac);
................................................................................
**
** This has the effect of making sure that the string is well-formed
** UTF-8.  Miscoded characters are removed.
**
** The translation is done in-place and aborted if the output
** overruns the input.
*/
int sqlite4Utf8To8(char *zIn){
  char *zOut = zIn;
  char *zStart = zIn;
  u32 c;

  while( zIn[0] && zOut<=zIn ){
    c = sqlite4Utf8Read(zIn, (const char **)&zIn);
    if( c!=0xfffd ){
      WRITE_UTF8(zOut, c);
    }
  }
  *zOut = 0;
  return (int)(zOut - zStart);
}
................................................................................
/*
** This routine is called from the TCL test function "translate_selftest".
** It checks that the primitives for serializing and deserializing
** characters in each encoding are inverses of each other.
*/
void sqlite4UtfSelfTest(void){
  unsigned int i, t;
  char zBuf[20];
  char *z;
  int n;
  unsigned int c;

  for(i=0; i<0x00110000; i++){
    z = zBuf;
    WRITE_UTF8(z, i);
    n = (int)(z-zBuf);
    assert( n>0 && n<=4 );
    z[0] = 0;
    z = zBuf;
    c = sqlite4Utf8Read(z, (const char **)&z);
    t = i;
    if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD;
    if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD;
    assert( c==t );
    assert( (z-zBuf)==n );
  }
  for(i=0; i<0x00110000; i++){

Changes to src/vdbeapi.c.

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
...
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
}
int sqlite4_value_int(sqlite4_value *pVal){
  return (int)sqlite4VdbeIntValue((Mem*)pVal);
}
sqlite4_int64 sqlite4_value_int64(sqlite4_value *pVal){
  return sqlite4VdbeIntValue((Mem*)pVal);
}
const unsigned char *sqlite4_value_text(sqlite4_value *pVal){
  return (const unsigned char *)sqlite4ValueText(pVal, SQLITE4_UTF8);
}
#ifndef SQLITE4_OMIT_UTF16
const void *sqlite4_value_text16(sqlite4_value* pVal){
  return sqlite4ValueText(pVal, SQLITE4_UTF16NATIVE);
}
const void *sqlite4_value_text16be(sqlite4_value *pVal){
  return sqlite4ValueText(pVal, SQLITE4_UTF16BE);
................................................................................
  return val;
}
sqlite4_int64 sqlite4_column_int64(sqlite4_stmt *pStmt, int i){
  sqlite4_int64 val = sqlite4_value_int64( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
const unsigned char *sqlite4_column_text(sqlite4_stmt *pStmt, int i){
  const unsigned char *val = sqlite4_value_text( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
sqlite4_value *sqlite4_column_value(sqlite4_stmt *pStmt, int i){
  Mem *pOut = columnMem(pStmt, i);
  if( pOut->flags&MEM_Static ){
    pOut->flags &= ~MEM_Static;







|
|







 







|
|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
...
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
}
int sqlite4_value_int(sqlite4_value *pVal){
  return (int)sqlite4VdbeIntValue((Mem*)pVal);
}
sqlite4_int64 sqlite4_value_int64(sqlite4_value *pVal){
  return sqlite4VdbeIntValue((Mem*)pVal);
}
const char *sqlite4_value_text(sqlite4_value *pVal){
  return (const char *)sqlite4ValueText(pVal, SQLITE4_UTF8);
}
#ifndef SQLITE4_OMIT_UTF16
const void *sqlite4_value_text16(sqlite4_value* pVal){
  return sqlite4ValueText(pVal, SQLITE4_UTF16NATIVE);
}
const void *sqlite4_value_text16be(sqlite4_value *pVal){
  return sqlite4ValueText(pVal, SQLITE4_UTF16BE);
................................................................................
  return val;
}
sqlite4_int64 sqlite4_column_int64(sqlite4_stmt *pStmt, int i){
  sqlite4_int64 val = sqlite4_value_int64( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
const char *sqlite4_column_text(sqlite4_stmt *pStmt, int i){
  const char *val = sqlite4_value_text( columnMem(pStmt,i) );
  columnMallocFailure(pStmt);
  return val;
}
sqlite4_value *sqlite4_column_value(sqlite4_stmt *pStmt, int i){
  Mem *pOut = columnMem(pStmt, i);
  if( pOut->flags&MEM_Static ){
    pOut->flags &= ~MEM_Static;