From 9d951766ea063c5a566c479ed51433b8da5810fb Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Wed, 23 Jun 2004 12:15:55 +0000 Subject: [PATCH] Add some tests for user functions that prefer various text encodings. (CVS 1676) FossilOrigin-Name: db6bab574869fde49a147d4e19dd73005f247092 --- manifest | 16 +++---- manifest.uuid | 2 +- src/expr.c | 4 +- src/test1.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++- test/enc2.test | 109 +++++++++++++++++++++++++++++++++++++++--- 5 files changed, 239 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 2f56094a56..895e9675a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Test\scases\sto\sverify\srecovery\safter\sa\scrash.\s(CVS\s1675) -D 2004-06-23T10:43:10 +C Add\ssome\stests\sfor\suser\sfunctions\sthat\sprefer\svarious\stext\sencodings.\s(CVS\s1676) +D 2004-06-23T12:15:55 F Makefile.in 0a3d7aaefa50717bd550b0cf568a51072c4c103c F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -32,7 +32,7 @@ F src/build.c fc0b51748da8bc9c8266fdb36e57d49393793947 F src/date.c b3e8b2bef1e3f2ce24e5b057203036defb18c3f1 F src/delete.c e81545e546f6bc87d7508a93a09ca70695265af3 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 -F src/expr.c a0372aa8d27ce9a82f6419c066b47f0500ec50a6 +F src/expr.c 31e48dd1d9d10fe8e2c307a4a4f36837ed11d3cf F src/func.c 3d32878eeb4c6a9977c72ec19984d329b6954c7e F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb @@ -62,7 +62,7 @@ F src/sqlite.h.in 1f400a561fca3b1df73677d2d97046425d47cae4 F src/sqliteInt.h dd796b6abc6d50505fe33c54f0143d7000681a41 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/tclsqlite.c 8d093146332b2f0cbf2a8ebe8597d481619308a3 -F src/test1.c a7e559240e677671224d2d13b4d1dab284e23c20 +F src/test1.c 821dcde84c317e504919fc0c150e4b490b7d23bd F src/test2.c dafd8bd314a554bf376c6d3a8c83fd69219f5a40 F src/test3.c 7247090d15a5a43823079b6fd8dad1ed3cccdedf F src/test4.c a921a69821fd30209589228e64f94e9f715b6fe2 @@ -109,7 +109,7 @@ F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2 F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d F test/delete.test 4f0c86e2bebdc822d179c80697b1ceabe6bbcd07 F test/enc.test e29a0d0558f4597ac1652a7bbac03b0e4ce17416 -F test/enc2.test 57c847492afd46eef7a498fc3853fe909a40fef7 +F test/enc2.test 30805ba8dfc13dcf4d9e2f0a0cabf299e3da5f59 F test/enc3.test 315f302ed9a6042be76710eb6aa70e4551e9aa73 F test/expr.test b4e945265c4c697bf5213b72558914ba10a989cc F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7 @@ -229,7 +229,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/version3.tcl 563ba3ac02f64da27ab17f3edbe8e56bfd0293fb F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P 46107da7eddbdda8b582e2ece2dc41222a70330a -R 2d06dadbd77bf8c7d6cc2f4d941e75d8 +P 41868d79ac5b3c496c4d87ca6b4ee7c17ef38965 +R 45808ef42046b583bcf8b64ab537bd5d U danielk1977 -Z eb0225a30546e9d6f49bf0fdd5127daf +Z 26dffde445a781b6437c186807dfe93e diff --git a/manifest.uuid b/manifest.uuid index 4f2cbbfea8..10d2dd5c1d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -41868d79ac5b3c496c4d87ca6b4ee7c17ef38965 \ No newline at end of file +db6bab574869fde49a147d4e19dd73005f247092 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6665daf7b1..c89f8e4a39 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.147 2004/06/21 09:06:42 danielk1977 Exp $ +** $Id: expr.c,v 1.148 2004/06/23 12:15:55 danielk1977 Exp $ */ #include "sqliteInt.h" #include @@ -1764,7 +1764,7 @@ FuncDef *sqlite3FindFunction( ** ** A larger value of 'matchqual' indicates a more desirable match. */ - if( p->nArg==-1 || p->nArg==nArg || nArg==-1 ){ + if( (p->xStep||p->xFunc ) && (p->nArg==-1||p->nArg==nArg||nArg==-1) ){ int match = 1; /* Quality of this match */ if( p->nArg==nArg || nArg==-1 ){ match = 4; diff --git a/src/test1.c b/src/test1.c index aedda2dd73..e61b4e5b3b 100644 --- a/src/test1.c +++ b/src/test1.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test1.c,v 1.84 2004/06/23 10:43:11 danielk1977 Exp $ +** $Id: test1.c,v 1.85 2004/06/23 12:15:55 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -984,6 +984,129 @@ bad_args: return TCL_ERROR; } +/* +** Usage: add_test_function +** +** This function is used to test that SQLite selects the correct user +** function callback when multiple versions (for different text encodings) +** are available. +** +** Calling this routine registers up to three versions of the user function +** "test_function" with database handle . If the second argument is +** true, then a version of test_function is registered for UTF-8, if the +** third is true, a version is registered for UTF-16le, if the fourth is +** true, a UTF-16be version is available. Previous versions of +** test_function are deleted. +** +** The user function is implemented by calling the following TCL script: +** +** "test_function " +** +** Where is one of UTF-8, UTF-16LE or UTF16BE, and is the +** single argument passed to the SQL function. The value returned by +** the TCL script is used as the return value of the SQL function. It +** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8 +** for a UTF-16LE test_function(), and UTF-16LE for an implementation that +** prefers UTF-16BE. +*/ +static void test_function_utf8( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **argv +){ + Tcl_Interp *interp; + Tcl_Obj *pX; + sqlite3_value *pVal; + interp = (Tcl_Interp *)sqlite3_user_data(pCtx); + pX = Tcl_NewStringObj("test_function", -1); + Tcl_IncrRefCount(pX); + Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-8", -1)); + Tcl_ListObjAppendElement(interp, pX, + Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); + Tcl_EvalObjEx(interp, pX, 0); + Tcl_DecrRefCount(pX); + sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT); + pVal = sqlite3ValueNew(); + sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), + SQLITE_UTF8, SQLITE_STATIC); + sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal), + -1, SQLITE_TRANSIENT); + sqlite3ValueFree(pVal); +} +static void test_function_utf16le( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **argv +){ + Tcl_Interp *interp; + Tcl_Obj *pX; + sqlite3_value *pVal; + interp = (Tcl_Interp *)sqlite3_user_data(pCtx); + pX = Tcl_NewStringObj("test_function", -1); + Tcl_IncrRefCount(pX); + Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16LE", -1)); + Tcl_ListObjAppendElement(interp, pX, + Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); + Tcl_EvalObjEx(interp, pX, 0); + Tcl_DecrRefCount(pX); + pVal = sqlite3ValueNew(); + sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), + SQLITE_UTF8, SQLITE_STATIC); + sqlite3_result_text(pCtx,sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT); + sqlite3ValueFree(pVal); +} +static void test_function_utf16be( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **argv +){ + Tcl_Interp *interp; + Tcl_Obj *pX; + sqlite3_value *pVal; + interp = (Tcl_Interp *)sqlite3_user_data(pCtx); + pX = Tcl_NewStringObj("test_function", -1); + Tcl_IncrRefCount(pX); + Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16BE", -1)); + Tcl_ListObjAppendElement(interp, pX, + Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); + Tcl_EvalObjEx(interp, pX, 0); + Tcl_DecrRefCount(pX); + pVal = sqlite3ValueNew(); + sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), + SQLITE_UTF8, SQLITE_STATIC); + sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal), + -1, SQLITE_TRANSIENT); + sqlite3ValueFree(pVal); +} +static int test_function( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3 *db; + int val; + + if( objc!=5 ) goto bad_args; + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + + if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; + sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8, + interp, val?test_function_utf8:0, 0, 0); + if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; + sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE, + interp, val?test_function_utf16le:0, 0, 0); + if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; + sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE, + interp, val?test_function_utf16be:0, 0, 0); + + return TCL_OK; +bad_args: + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " ", 0); + return TCL_ERROR; +} + static int sqlite3_crashparams( void * clientData, Tcl_Interp *interp, @@ -2068,6 +2191,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3OsLock", test_sqlite3OsLock, 0 }, { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, { "add_test_collate", test_collate, 0 }, + { "add_test_function", test_function, 0 }, { "sqlite3_crashparams", sqlite3_crashparams, 0 }, }; diff --git a/test/enc2.test b/test/enc2.test index 5ab8189ed6..4474a3cf70 100644 --- a/test/enc2.test +++ b/test/enc2.test @@ -13,7 +13,7 @@ # various suported unicode encodings (UTF-8, UTF-16, UTF-16le and # UTF-16be). # -# $Id: enc2.test,v 1.12 2004/06/19 00:16:31 drh Exp $ +# $Id: enc2.test,v 1.13 2004/06/23 12:15:55 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -263,6 +263,103 @@ do_test enc2-5.11 { db close file delete -force test.db +# The following tests - enc2-5.* - test that SQLite selects the correct +# collation sequence when more than one is available. + +proc test_function {enc arg} { + return "$enc $arg" +} + +file delete -force test.db +set DB [sqlite3 db test.db] +execsql {pragma encoding = 'UTF-8'} +do_test enc2-6.0 { + execsql { + CREATE TABLE t5(a); + INSERT INTO t5 VALUES('one'); + } +} {} +do_test enc2-6.1 { + add_test_function $DB 1 1 1 + execsql { + SELECT test_function('sqlite') + } +} {{UTF-8 sqlite}} + +do_test enc2-6.2 { + add_test_function $DB 0 1 0 + execsql { + SELECT test_function('sqlite') + } +} {{UTF-16LE sqlite}} +do_test enc2-6.3 { + add_test_function $DB 0 0 1 + execsql { + SELECT test_function('sqlite') + } +} {{UTF-16BE sqlite}} + +file delete -force test.db +set DB [sqlite3 db test.db] +execsql {pragma encoding = 'UTF-16LE'} +do_test enc2-6.3 { + execsql { + CREATE TABLE t5(a); + INSERT INTO t5 VALUES('sqlite'); + } +} {} +do_test enc2-6.4 { + add_test_function $DB 1 1 1 + execsql { + SELECT test_function('sqlite') + } +} {{UTF-16LE sqlite}} + +do_test enc2-6.5 { + add_test_function $DB 0 1 0 + execsql { + SELECT test_function('sqlite') + } +} {{UTF-16LE sqlite}} +do_test enc2-6.6 { + add_test_function $DB 0 0 1 + execsql { + SELECT test_function('sqlite') + } +} {{UTF-16BE sqlite}} + +file delete -force test.db +set DB [sqlite3 db test.db] +execsql {pragma encoding = 'UTF-16BE'} +do_test enc2-6.7 { + execsql { + CREATE TABLE t5(a); + INSERT INTO t5 VALUES('sqlite'); + } +} {} +do_test enc2-6.8 { + add_test_function $DB 1 1 1 + execsql { + SELECT test_function('sqlite') + } +} {{UTF-16BE sqlite}} + +do_test enc2-6.9 { + add_test_function $DB 0 1 0 + execsql { + SELECT test_function('sqlite') + } +} {{UTF-16LE sqlite}} +do_test enc2-6.10 { + add_test_function $DB 0 0 1 + execsql { + SELECT test_function('sqlite') + } +} {{UTF-16BE sqlite}} + +db close +file delete -force test.db + # The following tests - enc2-6.* - function as follows: # # 1: Open an empty database file assuming UTF-16 encoding. @@ -271,32 +368,32 @@ file delete -force test.db # 3: Read the sqlite_master table from the first handle. # 4: Ensure the first handle recognises the database encoding is UTF-8. # -do_test enc2-6.1 { +do_test enc2-7.1 { sqlite3 db test.db execsql { PRAGMA encoding = 'UTF-16'; SELECT * FROM sqlite_master; } } {} -do_test enc2-6.2 { +do_test enc2-7.2 { set enc [execsql { PRAGMA encoding; }] string range $enc 0 end-2 ;# Chop off the "le" or "be" } {UTF-16} -do_test enc2-6.3 { +do_test enc2-7.3 { sqlite3 db2 test.db execsql { PRAGMA encoding = 'UTF-8'; CREATE TABLE abc(a, b, c); } db2 } {} -do_test enc2-6.4 { +do_test enc2-7.4 { execsql { SELECT * FROM sqlite_master; } } {table abc abc 2 {CREATE TABLE abc(a, b, c)}} -do_test enc2-6.5 { +do_test enc2-7.5 { execsql { PRAGMA encoding; }