Have the vdbe handle strings in the same encoding as the database. (CVS 1445)

FossilOrigin-Name: b7155db2b13aa3ca5f6c68e948d9e8740ebcac47
This commit is contained in:
danielk1977 2004-05-24 07:04:25 +00:00
parent 93d4675d67
commit 8a6b5411b3
9 changed files with 682 additions and 490 deletions

View File

@ -1,5 +1,5 @@
C Begin\schanging\sthe\svdbe\sso\sall\sstack\svalues\suse\sthe\sdatabase\sencoding.\s(CVS\s1444)
D 2004-05-23T13:30:58
C Have\sthe\svdbe\shandle\sstrings\sin\sthe\ssame\sencoding\sas\sthe\sdatabase.\s(CVS\s1445)
D 2004-05-24T07:04:26
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@ -28,11 +28,11 @@ F src/btree.c 51dfa34da5f42762b228d7360cf3273ee403bce8
F src/btree.h b65140b5ae891f30d2a39e64b9f0343225553545
F src/build.c 35cbeb439b49cca5eb5e8a1de010a5194f4523e8
F src/copy.c 4d2038602fd0549d80c59bda27d96f13ea9b5e29
F src/date.c 0eb0a89960bb45c7f7e768748605a7a97b0c8064
F src/date.c fd6a46498449db9c4ff5d45544d9a9b8ba9d8cd5
F src/delete.c 2e1dda38345416a1ea1c0a6468589a7472334dac
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
F src/expr.c 5b283e68bd6df365b7c2ad10bd04cc54c2b4b07c
F src/func.c cfbb7096efb58e2857e3b312a8958a12774b625a
F src/func.c 333bbc06cc281f4dbded5dfc4faa1457764bc1b3
F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
F src/insert.c e510d62d23b4de4d901e7ccbbe7833b7fb3b9570
@ -53,9 +53,9 @@ F src/pragma.c e14dd3b06cedeadcc027f0b6706b2f53d456a46e
F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c 7d77a8bed7eeac23216d42fc1be006fb4352fcdc
F src/shell.c 657623c2a3df126538d41842c2146cadbd52b154
F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f
F src/sqlite.h.in 69393dbaa5b11853685ae656d1bef6a98b808bbb
F src/sqliteInt.h 823411100924138073aa542af4aae8bd5eede4a3
F src/sqliteInt.h e1191166ac9055d6c99c97771d3f35212ef2cff2
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
F src/tclsqlite.c f241854328ee2b06006efded270d84799159f760
F src/test1.c b5f2f9f9d866c8a586b8d47c5999d2cbefaac686
@ -67,12 +67,12 @@ F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847
F src/trigger.c 11afe9abfba13a2ba142944c797c952e162d117f
F src/update.c 1a5e9182596f3ea8c7a141e308a3d2a7e5689fee
F src/utf.c 441c5918ee3777cd8e9611cbb810312ed314737d
F src/util.c 5cbeb452da09cfc7248de9948c15b14d840723f7
F src/util.c 4c0adcbc9ce6678dd046931253e45d623c6d279f
F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad
F src/vdbe.c b40ff0912ddfae65d9a90ca38302b74a04c6ee76
F src/vdbe.c d5d15429c0be735d325d53d0dadbb2197a9f405d
F src/vdbe.h 391d5642a83af686f35c228fcd36cb4456d68f44
F src/vdbeInt.h 6c2444a60fc030b275dc0cff407cdaa79d84ce86
F src/vdbeaux.c 60fa2357fc12dec128d9606e5b84cec836aa7e40
F src/vdbeaux.c 7f0c4ad22d5e61465d509467e2535293b468373a
F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
@ -202,7 +202,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
P 18e690e405710c9a8010340c01754bbfa3231fe9
R a90f19b4bed57bb3a6862d24faf34718
P f47de3a933b51b37629a0ca2e492a534a12e7339
R 0d8b15870c4105fdf982c7cf1ceb6e90
U danielk1977
Z 72938d5d6b2f4afcbbfc88e30cdfc1f0
Z 680dc16bbdc1913b8e540b4d62c8fcee

View File

@ -1 +1 @@
f47de3a933b51b37629a0ca2e492a534a12e7339
b7155db2b13aa3ca5f6c68e948d9e8740ebcac47

View File

@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: date.c,v 1.19 2004/05/14 11:00:53 danielk1977 Exp $
** $Id: date.c,v 1.20 2004/05/24 07:04:26 danielk1977 Exp $
**
** NOTES:
**
@ -321,7 +321,7 @@ static int parseDateOrTime(const char *zDate, DateTime *p){
return 0;
}
return 1;
}else if( sqlite3IsNumber(zDate, 0) ){
}else if( sqlite3IsNumber(zDate, 0, TEXT_Utf8) ){
p->rJD = sqlite3AtoF(zDate, 0);
p->validJD = 1;
return 0;

View File

@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.48 2004/05/16 11:15:38 danielk1977 Exp $
** $Id: func.c,v 1.49 2004/05/24 07:04:26 danielk1977 Exp $
*/
#include <ctype.h>
#include <math.h>
@ -295,7 +295,7 @@ static void quoteFunc(sqlite_func *context, int argc, const char **argv){
if( argc<1 ) return;
if( argv[0]==0 ){
sqlite3_set_result_string(context, "NULL", 4);
}else if( sqlite3IsNumber(argv[0], 0) ){
}else if( sqlite3IsNumber(argv[0], 0, TEXT_Utf8) ){
sqlite3_set_result_string(context, argv[0], -1);
}else{
int i,j,n;

View File

@ -12,7 +12,7 @@
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.97 2004/05/22 09:21:21 danielk1977 Exp $
** $Id: shell.c,v 1.98 2004/05/24 07:04:26 danielk1977 Exp $
*/
#include <stdlib.h>
#include <string.h>
@ -80,7 +80,7 @@ static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
/*
** Determines if a string is a number of not.
*/
extern int sqlite3IsNumber(const char*, int*);
extern int sqlite3IsNumber(const char*, int*, unsigned char);
/*
** This routine reads a line of text from standard input, stores
@ -392,7 +392,7 @@ static int callback(void *pArg, int nArg, char **azArg, char **azCol){
char *zSep = i>0 ? ",": "";
if( azArg[i]==0 ){
fprintf(p->out,"%sNULL",zSep);
}else if( sqlite3IsNumber(azArg[i], 0) ){
}else if( sqlite3IsNumber(azArg[i], 0, 1) ){
fprintf(p->out,"%s%s",zSep, azArg[i]);
}else{
if( zSep[0] ) fprintf(p->out,"%s",zSep);

View File

@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.247 2004/05/23 13:30:58 danielk1977 Exp $
** @(#) $Id: sqliteInt.h,v 1.248 2004/05/24 07:04:26 danielk1977 Exp $
*/
#include "config.h"
#include "sqlite.h"
@ -326,10 +326,10 @@ struct Db {
/*
** Possible values for the Db.textEnc field.
*/
#define TEXT_Utf8 1
#define TEXT_Utf16le 2
#define TEXT_Utf16be 3
/* #define TEXT_Utf16 4 */
#define TEXT_Utf8 1
#define TEXT_Utf16le 2
#define TEXT_Utf16be 3
#define TEXT_Utf16 (SQLITE3_BIGENDIAN?TEXT_Utf16be:TEXT_Utf16le)
/*
** Each database is an instance of the following structure.
@ -1177,7 +1177,7 @@ extern int always_code_trigger_setup;
int sqlite3StrICmp(const char *, const char *);
int sqlite3StrNICmp(const char *, const char *, int);
int sqlite3HashNoCase(const char *, int);
int sqlite3IsNumber(const char*, int*);
int sqlite3IsNumber(const char*, int*, u8);
int sqlite3Compare(const char *, const char *);
int sqlite3SortCompare(const char *, const char *);
void sqlite3RealToSortable(double r, char *);
@ -1368,7 +1368,7 @@ 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*);
int sqlite3atoi64(const char*, i64*, u8);
void sqlite3Error(sqlite *, int, const char*,...);
int sqlite3utfTranslate(const void *, int , u8 , void **, int *, u8);
u8 sqlite3UtfReadBom(const void *zData, int nData);

View File

@ -14,7 +14,7 @@
** 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 $
** $Id: util.c,v 1.88 2004/05/24 07:04:26 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
@ -564,25 +564,27 @@ int sqlite3StrNICmp(const char *zLeft, const char *zRight, int N){
**
** Am empty string is considered non-numeric.
*/
int sqlite3IsNumber(const char *z, int *realnum){
if( *z=='-' || *z=='+' ) z++;
int sqlite3IsNumber(const char *z, int *realnum, u8 enc){
int incr = (enc==TEXT_Utf8?1:2);
if( enc==TEXT_Utf16be ) z++;
if( *z=='-' || *z=='+' ) z += incr;
if( !isdigit(*z) ){
return 0;
}
z++;
z += incr;
if( realnum ) *realnum = 0;
while( isdigit(*z) ){ z++; }
while( isdigit(*z) ){ z += incr; }
if( *z=='.' ){
z++;
z += incr;
if( !isdigit(*z) ) return 0;
while( isdigit(*z) ){ z++; }
while( isdigit(*z) ){ z += incr; }
if( realnum ) *realnum = 1;
}
if( *z=='e' || *z=='E' ){
z++;
if( *z=='+' || *z=='-' ) z++;
z += incr;
if( *z=='+' || *z=='-' ) z += incr;
if( !isdigit(*z) ) return 0;
while( isdigit(*z) ){ z++; }
while( isdigit(*z) ){ z += incr; }
if( realnum ) *realnum = 1;
}
return *z==0;
@ -663,23 +665,27 @@ double sqlite3AtoF(const char *z, const char **pzEnd){
** 32-bit numbers. At that time, it was much faster than the
** atoi() library routine in RedHat 7.2.
*/
int sqlite3atoi64(const char *zNum, i64 *pNum){
int sqlite3atoi64(const char *zNum, i64 *pNum, u8 enc){
i64 v = 0;
int neg;
int i, c;
int incr = (enc==TEXT_Utf8?1:2);
if( enc==TEXT_Utf16be ) zNum++;
if( *zNum=='-' ){
neg = 1;
zNum++;
zNum += incr;
}else if( *zNum=='+' ){
neg = 0;
zNum++;
zNum += incr;
}else{
neg = 0;
}
for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
for(i=0; (c=zNum[i])>='0' && c<='9'; i += incr){
v = v*10 + c - '0';
}
*pNum = neg ? -v : v;
/* FIX ME: Handle overflow of strings in UTF-16 here */
return c==0 && i>0 &&
(i<19 || (i==19 && memcmp(zNum,"9223372036854775807",19)<=0));
}
@ -738,7 +744,7 @@ int sqlite3FitsIn64Bits(const char *zNum){
*/
int sqlite3GetInt64(const char *zNum, i64 *pValue){
if( sqlite3FitsIn64Bits(zNum) ){
sqlite3atoi64(zNum, pValue);
sqlite3atoi64(zNum, pValue, TEXT_Utf8);
return 1;
}
return 0;
@ -765,8 +771,8 @@ int sqlite3Compare(const char *atext, const char *btext){
}else if( btext==0 ){
return 1;
}
isNumA = sqlite3IsNumber(atext, 0);
isNumB = sqlite3IsNumber(btext, 0);
isNumA = sqlite3IsNumber(atext, 0, TEXT_Utf8);
isNumB = sqlite3IsNumber(btext, 0, TEXT_Utf8);
if( isNumA ){
if( !isNumB ){
result = -1;
@ -857,8 +863,8 @@ int sqlite3SortCompare(const char *a, const char *b){
res = strcmp(&a[1],&b[1]);
if( res ) break;
}else{
isNumA = sqlite3IsNumber(&a[1], 0);
isNumB = sqlite3IsNumber(&b[1], 0);
isNumA = sqlite3IsNumber(&a[1], 0, TEXT_Utf8);
isNumB = sqlite3IsNumber(&b[1], 0, TEXT_Utf8);
if( isNumA ){
double rA, rB;
if( !isNumB ){

File diff suppressed because it is too large Load Diff

View File

@ -1059,242 +1059,6 @@ int sqlite3VdbeFinalize(Vdbe *p, char **pzErrMsg){
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_Term */
){
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;
}
memcpy(pVar->z, zVal, bytes);
}
}
return SQLITE_OK;
}
/*
** Bind a 64 bit integer to an SQL statement variable.
*/
int sqlite3_bind_int64(sqlite3_stmt *p, int i, long long int iValue){
int rc;
Vdbe *v = (Vdbe *)p;
rc = vdbeUnbind(v, i);
if( rc==SQLITE_OK ){
Mem *pVar = &v->apVar[i-1];
pVar->flags = MEM_Int;
pVar->i = iValue;
}
return rc;
}
/*
** Bind a 32 bit integer to an SQL statement variable.
*/
int sqlite3_bind_int32(sqlite3_stmt *p, int i, int iValue){
return sqlite3_bind_int64(p, i, (long long int)iValue);
}
/*
** Bind a double (real) to an SQL statement variable.
*/
int sqlite3_bind_double(sqlite3_stmt *p, int i, double iValue){
int rc;
Vdbe *v = (Vdbe *)p;
rc = vdbeUnbind(v, i);
if( rc==SQLITE_OK ){
Mem *pVar = &v->apVar[i-1];
pVar->flags = MEM_Real;
pVar->r = iValue;
}
return SQLITE_OK;
}
/*
** Bind a NULL value to an SQL statement variable.
*/
int sqlite3_bind_null(sqlite3_stmt* p, int i){
return vdbeUnbind((Vdbe *)p, i);
}
/*
** Bind a UTF-8 text value to an SQL statement variable.
*/
int sqlite3_bind_text(
sqlite3_stmt *p,
int i,
const char *zData,
int nData,
int eCopy
){
int flags = MEM_Str|MEM_Utf8;
if( zData ){
if( nData<0 ){
nData = strlen(zData)+1;
flags |= MEM_Term;
}else if( !zData[nData-1] ){
flags |= MEM_Term;
}
}
return vdbeBindBlob((Vdbe *)p, i, zData, nData, eCopy, flags);
}
/*
** Bind a UTF-16 text value to an SQL statement variable.
*/
int sqlite3_bind_text16(
sqlite3_stmt *pStmt,
int i,
const void *zData,
int nData,
int eCopy
){
Vdbe *p = (Vdbe *)pStmt;
Mem *pVar;
u8 db_enc = p->db->enc; /* Text encoding of the database */
u8 txt_enc;
int null_term = 0;
int flags;
int rc;
rc = vdbeUnbind(p, i);
if( rc!=SQLITE_OK ){
return rc;
}
pVar = &p->apVar[i-1];
if( db_enc==TEXT_Utf8 ){
/* If the database encoding is UTF-8, then do a translation. */
pVar->z = sqlite3utf16to8(zData, nData, SQLITE3_BIGENDIAN);
if( !pVar->z ) return SQLITE_NOMEM;
pVar->n = strlen(pVar->z)+1;
pVar->flags = MEM_Str|MEM_Term|MEM_Dyn;
return SQLITE_OK;
}
/* There may or may not be a byte order mark at the start of the UTF-16.
** Either way set 'txt_enc' to the TEXT_Utf16* value indicating the
** actual byte order used by this string. If the string does happen
** to contain a BOM, then move zData so that it points to the first
** byte after the BOM.
*/
txt_enc = sqlite3UtfReadBom(zData, nData);
if( txt_enc ){
zData = (void *)(((u8 *)zData) + 2);
}else{
txt_enc = SQLITE3_BIGENDIAN?TEXT_Utf16be:TEXT_Utf16le;
}
if( nData<0 ){
nData = sqlite3utf16ByteLen(zData, -1) + 2;
null_term = 1;
}else if( nData>1 && !((u8*)zData)[nData-1] && !((u8*)zData)[nData-2] ){
null_term = 1;
}
if( db_enc==txt_enc && !eCopy ){
/* If the byte order of the string matches the byte order of the
** database and the eCopy parameter is not set, then the string can
** be used without making a copy.
*/
pVar->z = (char *)zData;
pVar->n = nData;
pVar->flags = MEM_Str|MEM_Static|(null_term?MEM_Term:0);
}else{
/* Make a copy. Swap the byte order if required */
pVar->n = nData + (null_term?0:2);
pVar->z = sqliteMalloc(pVar->n);
pVar->flags = MEM_Str|MEM_Dyn|MEM_Term;
if( db_enc==txt_enc ){
memcpy(pVar->z, zData, nData);
}else{
swab(zData, pVar->z, nData);
}
pVar->z[pVar->n-1] = '\0';
pVar->z[pVar->n-2] = '\0';
}
return SQLITE_OK;
}
/*
** Bind a blob value to an SQL statement variable.
*/
int sqlite3_bind_blob(
sqlite3_stmt *p,
int i,
const void *zData,
int nData,
int eCopy
){
return vdbeBindBlob((Vdbe *)p, i, zData, nData, eCopy, MEM_Blob);
}
/*
** Set the values of all variables. Variable $1 in the original SQL will
** be the string azValue[0]. $2 will have the value azValue[1]. And