aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordanielk1977 <danielk1977@noemail.net>2004-06-28 13:09:11 +0000
committerdanielk1977 <danielk1977@noemail.net>2004-06-28 13:09:11 +0000
commitf46188911d103c4a1f0e9f182783c5f1ec39294b (patch)
treef6098702a7391b01d0e3cbe12c522ce54cb42114 /src
parent2ec81649a5622b4ae071fd6635fc491c1e4eef16 (diff)
downloadsqlite-f46188911d103c4a1f0e9f182783c5f1ec39294b.tar.gz
sqlite-f46188911d103c4a1f0e9f182783c5f1ec39294b.zip
More coverage testing. (CVS 1754)
FossilOrigin-Name: 332921041040b343b6b568685ff55d21a624f502
Diffstat (limited to 'src')
-rw-r--r--src/func.c84
-rw-r--r--src/sqliteInt.h3
-rw-r--r--src/utf.c82
-rw-r--r--src/vdbe.c10
-rw-r--r--src/vdbeapi.c6
-rw-r--r--src/vdbemem.c8
6 files changed, 146 insertions, 47 deletions
diff --git a/src/func.c b/src/func.c
index e8cea2bbd..023a42f92 100644
--- a/src/func.c
+++ b/src/func.c
@@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
-** $Id: func.c,v 1.76 2004/06/24 00:20:05 danielk1977 Exp $
+** $Id: func.c,v 1.77 2004/06/28 13:09:11 danielk1977 Exp $
*/
#include <ctype.h>
#include <math.h>
@@ -794,14 +794,26 @@ static void test_destructor(
sqlite3_value **argv
){
char *zVal;
+ int len;
+ sqlite *db = sqlite3_user_data(pCtx);
+
test_destructor_count_var++;
assert( nArg==1 );
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
- zVal = sqliteMalloc(sqlite3_value_bytes(argv[0]) + 2);
+ len = sqlite3ValueBytes(argv[0], db->enc);
+ zVal = sqliteMalloc(len+3);
+ zVal[len] = 0;
+ zVal[len-1] = 0;
assert( zVal );
zVal++;
- strcpy(zVal, sqlite3_value_text(argv[0]));
- sqlite3_result_text(pCtx, zVal, -1, destructor);
+ memcpy(zVal, sqlite3ValueText(argv[0], db->enc), len);
+ if( db->enc==SQLITE_UTF8 ){
+ sqlite3_result_text(pCtx, zVal, -1, destructor);
+ }else if( db->enc==SQLITE_UTF16LE ){
+ sqlite3_result_text16le(pCtx, zVal, -1, destructor);
+ }else{
+ sqlite3_result_text16be(pCtx, zVal, -1, destructor);
+ }
}
static void test_destructor_count(
sqlite3_context *pCtx,
@@ -1010,45 +1022,45 @@ void sqlite3RegisterBuiltinFunctions(sqlite *db){
static struct {
char *zName;
signed char nArg;
- u8 argType; /* 0: none. 1: db 2: (-1) */
- u8 eTextRep; /* 1: UTF-16. 0: UTF-8 */
+ u8 argType; /* 0: none. 1: db 2: (-1) */
+ u8 eTextRep; /* 1: UTF-16. 0: UTF-8 */
u8 needCollSeq;
void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
} aFuncs[] = {
- { "min", -1, 0, SQLITE_UTF8, 1, minmaxFunc },
- { "min", 0, 0, SQLITE_UTF8, 1, 0 },
- { "max", -1, 2, SQLITE_UTF8, 1, minmaxFunc },
- { "max", 0, 2, SQLITE_UTF8, 1, 0 },
- { "typeof", 1, 0, SQLITE_UTF8, 0, typeofFunc },
- { "length", 1, 0, SQLITE_UTF8, 0, lengthFunc },
- { "substr", 3, 0, SQLITE_UTF8, 0, substrFunc },
- { "abs", 1, 0, SQLITE_UTF8, 0, absFunc },
- { "round", 1, 0, SQLITE_UTF8, 0, roundFunc },
- { "round", 2, 0, SQLITE_UTF8, 0, roundFunc },
- { "upper", 1, 0, SQLITE_UTF8, 0, upperFunc },
- { "lower", 1, 0, SQLITE_UTF8, 0, lowerFunc },
- { "coalesce", -1, 0, SQLITE_UTF8, 0, ifnullFunc },
- { "coalesce", 0, 0, SQLITE_UTF8, 0, 0 },
- { "coalesce", 1, 0, SQLITE_UTF8, 0, 0 },
- { "ifnull", 2, 0, SQLITE_UTF8, 1, ifnullFunc },
- { "random", -1, 0, SQLITE_UTF8, 0, randomFunc },
- { "like", 2, 0, SQLITE_UTF8, 0, likeFunc },
-/* { "like", 2, 2, SQLITE_UTF16,0, likeFunc }, */
- { "glob", 2, 0, SQLITE_UTF8, 0, globFunc },
- { "nullif", 2, 0, SQLITE_UTF8, 0, nullifFunc },
- { "sqlite_version", 0, 0, SQLITE_UTF8, 0, versionFunc},
- { "quote", 1, 0, SQLITE_UTF8, 0, quoteFunc },
- { "last_insert_rowid", 0, 1, SQLITE_UTF8, 0, last_insert_rowid },
- { "changes", 0, 1, SQLITE_UTF8, 0, changes },
- { "total_changes", 0, 1, SQLITE_UTF8, 0, total_changes },
+ { "min", -1, 0, SQLITE_UTF8, 1, minmaxFunc },
+ { "min", 0, 0, SQLITE_UTF8, 1, 0 },
+ { "max", -1, 2, SQLITE_UTF8, 1, minmaxFunc },
+ { "max", 0, 2, SQLITE_UTF8, 1, 0 },
+ { "typeof", 1, 0, SQLITE_UTF8, 0, typeofFunc },
+ { "length", 1, 0, SQLITE_UTF8, 0, lengthFunc },
+ { "substr", 3, 0, SQLITE_UTF8, 0, substrFunc },
+ { "substr", 3, 0, SQLITE_UTF16LE, 0, sqlite3utf16Substr },
+ { "abs", 1, 0, SQLITE_UTF8, 0, absFunc },
+ { "round", 1, 0, SQLITE_UTF8, 0, roundFunc },
+ { "round", 2, 0, SQLITE_UTF8, 0, roundFunc },
+ { "upper", 1, 0, SQLITE_UTF8, 0, upperFunc },
+ { "lower", 1, 0, SQLITE_UTF8, 0, lowerFunc },
+ { "coalesce", -1, 0, SQLITE_UTF8, 0, ifnullFunc },
+ { "coalesce", 0, 0, SQLITE_UTF8, 0, 0 },
+ { "coalesce", 1, 0, SQLITE_UTF8, 0, 0 },
+ { "ifnull", 2, 0, SQLITE_UTF8, 1, ifnullFunc },
+ { "random", -1, 0, SQLITE_UTF8, 0, randomFunc },
+ { "like", 2, 0, SQLITE_UTF8, 0, likeFunc },
+ { "glob", 2, 0, SQLITE_UTF8, 0, globFunc },
+ { "nullif", 2, 0, SQLITE_UTF8, 0, nullifFunc },
+ { "sqlite_version", 0, 0, SQLITE_UTF8, 0, versionFunc},
+ { "quote", 1, 0, SQLITE_UTF8, 0, quoteFunc },
+ { "last_insert_rowid", 0, 1, SQLITE_UTF8, 0, last_insert_rowid },
+ { "changes", 0, 1, SQLITE_UTF8, 0, changes },
+ { "total_changes", 0, 1, SQLITE_UTF8, 0, total_changes },
#ifdef SQLITE_SOUNDEX
- { "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc},
+ { "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc},
#endif
#ifdef SQLITE_TEST
- { "randstr", 2, 0, SQLITE_UTF8, 0, randStr },
- { "test_destructor", 1, 0, SQLITE_UTF8, 0, test_destructor},
+ { "randstr", 2, 0, SQLITE_UTF8, 0, randStr },
+ { "test_destructor", 1, 1, SQLITE_UTF8, 0, test_destructor},
{ "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count},
- { "test_auxdata", -1, 0, SQLITE_UTF8, 0, test_auxdata},
+ { "test_auxdata", -1, 0, SQLITE_UTF8, 0, test_auxdata},
#endif
};
static struct {
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 60fccc787..fde5bac5b 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.301 2004/06/26 08:38:25 danielk1977 Exp $
+** @(#) $Id: sqliteInt.h,v 1.302 2004/06/28 13:09:11 danielk1977 Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
@@ -1368,6 +1368,7 @@ int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3CheckIndexCollSeq(Parse *, Index *);
int sqlite3CheckObjectName(Parse *, const char *);
void sqlite3VdbeSetChanges(sqlite3 *, int);
+void sqlite3utf16Substr(sqlite3_context *,int,sqlite3_value **);
const void *sqlite3ValueText(sqlite3_value*, u8);
int sqlite3ValueBytes(sqlite3_value*, u8);
diff --git a/src/utf.c b/src/utf.c
index 326e9bde9..5fc37b5b5 100644
--- a/src/utf.c
+++ b/src/utf.c
@@ -12,7 +12,7 @@
** This file contains routines used to translate between UTF-8,
** UTF-16, UTF-16BE, and UTF-16LE.
**
-** $Id: utf.c,v 1.25 2004/06/23 13:46:32 danielk1977 Exp $
+** $Id: utf.c,v 1.26 2004/06/28 13:09:11 danielk1977 Exp $
**
** Notes on UTF-8:
**
@@ -210,6 +210,38 @@ static const int xtra_utf8_bits[4] = {
} \
}
+#define SKIP_UTF16BE(zIn){ \
+ if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn+1)==0x00)) ){ \
+ zIn += 4; \
+ }else{ \
+ zIn += 2; \
+ } \
+}
+#define SKIP_UTF16LE(zIn){ \
+ zIn++; \
+ if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn-1)==0x00)) ){ \
+ zIn += 3; \
+ }else{ \
+ zIn += 1; \
+ } \
+}
+
+#define RSKIP_UTF16LE(zIn){ \
+ if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn-1)==0x00)) ){ \
+ zIn -= 4; \
+ }else{ \
+ zIn -= 2; \
+ } \
+}
+#define RSKIP_UTF16BE(zIn){ \
+ zIn--; \
+ if( *zIn>=0xD8 && (*zIn<0xE0 || (*zIn==0xE0 && *(zIn+1)==0x00)) ){ \
+ zIn -= 3; \
+ }else{ \
+ zIn -= 1; \
+ } \
+}
+
/*
** If the TRANSLATE_TRACE macro is defined, the value of each Mem is
** printed on stderr on the way into and out of sqlite3VdbeMemTranslate().
@@ -507,6 +539,54 @@ int sqlite3utf8LikeCompare(
return *zString==0;
}
+/*
+** UTF-16 implementation of the substr()
+*/
+void sqlite3utf16Substr(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ int y, z;
+ unsigned char const *zStr;
+ unsigned char const *zStrEnd;
+ unsigned char const *zStart;
+ unsigned char const *zEnd;
+ int i;
+
+ zStr = (unsigned char const *)sqlite3_value_text16(argv[0]);
+ zStrEnd = &zStr[sqlite3_value_bytes16(argv[0])];
+ y = sqlite3_value_int(argv[1]);
+ z = sqlite3_value_int(argv[2]);
+
+ if( y>0 ){
+ y = y-1;
+ zStart = zStr;
+ if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){
+ for(i=0; i<y && zStart<zStrEnd; i++) SKIP_UTF16BE(zStart);
+ }else{
+ for(i=0; i<y && zStart<zStrEnd; i++) SKIP_UTF16LE(zStart);
+ }
+ }else{
+ zStart = zStrEnd;
+ if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){
+ for(i=y; i<0 && zStart>zStr; i++) RSKIP_UTF16BE(zStart);
+ }else{
+ for(i=y; i<0 && zStart>zStr; i++) RSKIP_UTF16LE(zStart);
+ }
+ for(; i<0; i++) z -= 1;
+ }
+
+ zEnd = zStart;
+ if( SQLITE_UTF16BE==SQLITE_UTF16NATIVE ){
+ for(i=0; i<z && zEnd<zStrEnd; i++) SKIP_UTF16BE(zEnd);
+ }else{
+ for(i=0; i<z && zEnd<zStrEnd; i++) SKIP_UTF16LE(zEnd);
+ }
+
+ sqlite3_result_text16(context, zStart, zEnd-zStart, SQLITE_TRANSIENT);
+}
+
#if defined(SQLITE_TEST)
/*
** This routine is called from the TCL test function "translate_selftest".
diff --git a/src/vdbe.c b/src/vdbe.c
index 6f2b71b33..5b49d1d9b 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -43,7 +43,7 @@
** 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.392 2004/06/28 01:11:47 danielk1977 Exp $
+** $Id: vdbe.c,v 1.393 2004/06/28 13:09:11 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@@ -1288,8 +1288,12 @@ case OP_Function: {
}
/* If the function returned an error, throw an exception */
if( ctx.isError ){
- sqlite3SetString(&p->zErrMsg,
- (pTos->flags & MEM_Str)!=0 ? pTos->z : "user function error", (char*)0);
+ if( !(pTos->flags&MEM_Str) ){
+ sqlite3SetString(&p->zErrMsg, "user function error", (char*)0);
+ }else{
+ sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pTos), (char*)0);
+ sqlite3VdbeChangeEncoding(pTos, db->enc);
+ }
rc = SQLITE_ERROR;
}
break;
diff --git a/src/vdbeapi.c b/src/vdbeapi.c
index 57b1b8776..6935ca7d1 100644
--- a/src/vdbeapi.c
+++ b/src/vdbeapi.c
@@ -341,7 +341,6 @@ const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
Mem *pColName;
if( N>=sqlite3_column_count(pStmt) || N<0 ){
- sqlite3Error(p->db, SQLITE_RANGE, 0);
return 0;
}
@@ -358,7 +357,6 @@ const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
Mem *pColName;
if( N>=sqlite3_column_count(pStmt) || N<0 ){
- sqlite3Error(p->db, SQLITE_RANGE, 0);
return 0;
}
@@ -375,7 +373,6 @@ const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
Mem *pColName;
if( N>=sqlite3_column_count(pStmt) || N<0 ){
- sqlite3Error(p->db, SQLITE_RANGE, 0);
return 0;
}
@@ -392,7 +389,6 @@ const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
Mem *pColName;
if( N>=sqlite3_column_count(pStmt) || N<0 ){
- sqlite3Error(p->db, SQLITE_RANGE, 0);
return 0;
}
@@ -459,7 +455,7 @@ int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
if( rc==SQLITE_OK ){
sqlite3VdbeMemSetDouble(&p->apVar[i-1], rValue);
}
- return SQLITE_OK;
+ return rc;
}
int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
return sqlite3_bind_int64(p, i, (i64)iValue);
diff --git a/src/vdbemem.c b/src/vdbemem.c
index 55b0fbb9f..7f26c7dd6 100644
--- a/src/vdbemem.c
+++ b/src/vdbemem.c
@@ -497,13 +497,19 @@ int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
if( pMem1->enc==pColl->enc ){
return pColl->xCmp(pColl->pUser,pMem1->n,pMem1->z,pMem2->n,pMem2->z);
}else{
- return pColl->xCmp(
+ u8 origEnc = pMem1->enc;
+ rc = pColl->xCmp(
pColl->pUser,
sqlite3ValueBytes((sqlite3_value*)pMem1, pColl->enc),
sqlite3ValueText((sqlite3_value*)pMem1, pColl->enc),
sqlite3ValueBytes((sqlite3_value*)pMem2, pColl->enc),
sqlite3ValueText((sqlite3_value*)pMem2, pColl->enc)
);
+ sqlite3ValueBytes((sqlite3_value*)pMem1, origEnc);
+ sqlite3ValueText((sqlite3_value*)pMem1, origEnc);
+ sqlite3ValueBytes((sqlite3_value*)pMem2, origEnc);
+ sqlite3ValueText((sqlite3_value*)pMem2, origEnc);
+ return rc;
}
}
/* If a NULL pointer was passed as the collate function, fall through