From 3f6b08747175508d3078a8cc56e3ee745ba6a044 Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Thu, 17 Jun 2004 05:36:44 +0000 Subject: [PATCH] Use the faster LIKE function from sqlite v2. Add special user functions to test builds to test the auxdata APIs. (CVS 1610) FossilOrigin-Name: b9493c5facea4d24a6cbc4f6fa2f75dc2399a11d --- manifest | 22 ++++++++--------- manifest.uuid | 2 +- src/func.c | 62 +++++++++++++++++++++++++++++++++++++++++++--- src/sqliteInt.h | 4 +-- src/utf.c | 59 +++++++++++++++++++++++++++++++++++++++++-- src/vdbemem.c | 35 +++++++++++++++++++++++--- test/expr.test | 3 ++- test/func.test | 66 +++++++++++++++++++++++++++++++++++++++++++++++-- 8 files changed, 228 insertions(+), 25 deletions(-) diff --git a/manifest b/manifest index 4c0102e1b2..34f552fb34 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sthe\ssecond\sdefinition\sof\sSQLITE_N_BTREE_META\sfrom\stest3.c.\s(CVS\s1609) -D 2004-06-17T00:01:21 +C Use\sthe\sfaster\sLIKE\sfunction\sfrom\ssqlite\sv2.\sAdd\sspecial\suser\sfunctions\sto\ntest\sbuilds\sto\stest\sthe\sauxdata\sAPIs.\s(CVS\s1610) +D 2004-06-17T05:36:44 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -33,7 +33,7 @@ F src/date.c 65b483caeb0e4dd663667d2f927caa058168ebff F src/delete.c 1e94ef693e45b441f5c828ea0a064ac339008f8e F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 F src/expr.c 657ca11f63a06aefd78014e6bc51dab6c735cc63 -F src/func.c be055fc63f1ae59c6a5dc4901240669f2a21f40c +F src/func.c 1959a0c2f5328b2b9934620f9492964f080f4a71 F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb F src/insert.c 15575e57917ea2e5702a2b5935583c84139699c3 @@ -57,7 +57,7 @@ F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/select.c ee37ea91bea336e9cb3356e0790d3e8787b6ba13 F src/shell.c ca519519dcbbc582f6d88f7d0e7583b857fd3469 F src/sqlite.h.in 36c253844656186ca53e1999efa6ef7b44f88779 -F src/sqliteInt.h 924f0bcb493722c90cec7b19a240a37a4f01bbe7 +F src/sqliteInt.h 59c1e1b637e7cf329f39425469bc4dbeab1fa1d5 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/tclsqlite.c 6f88be282a3617c6739c043fd13571b5f2fe9922 F src/test1.c 49c69d360ce09f8ecf56ec5e55fba625703d8b21 @@ -68,7 +68,7 @@ F src/test5.c 13ac1db35b03acbc197ceb245fe862da5ebf2369 F src/tokenize.c 183c5d7da11affab5d70d903d33409c8c0ce6c5b F src/trigger.c 3325207ea41d2d429e70370ce2ff987fd49b7ada F src/update.c f9a03233577e0c3d57234d1957963875fc941da2 -F src/utf.c e16737b3fc4201bf7ce9bd8ced5250596aa31b76 +F src/utf.c 92f0dd69bd1c1e4eff93c6038dd91b37ac1b9a65 F src/util.c 6e93dad9a17b34f37fc270ba871b224240168bf0 F src/vacuum.c f9561c8095407a970af4e6a304b77c4083433d3e F src/vdbe.c 35ae18345a8c35b17a37226cf868a99623288139 @@ -76,7 +76,7 @@ F src/vdbe.h 46f74444a213129bc4b5ce40124dd8ed613b0cde F src/vdbeInt.h 4e636b1b6c18d1d85b085fe0e5a19d45ad85f382 F src/vdbeapi.c ee350b552fc4c1c695b760f914f69e9c5556e829 F src/vdbeaux.c dc0e7d3bdf3b6f322448b4bee29fe5bec656b4d4 -F src/vdbemem.c 1e7df5ed53bc05433c7d3fb28899cf2c82bd16ac +F src/vdbemem.c c00e939cfb19380fc80349e143b541a45ab53424 F src/where.c 4955f34f7b46c9ca5c4e50e2db440f5e356f04dd F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/attach.test aed659e52635662bcd5069599aaca823533edf5a @@ -107,9 +107,9 @@ F test/date.test aed5030482ebc02bd8d386c6c86a29f694ab068d F test/delete.test ac14bd6df5f1581d646eebc013d6b844a885dcf6 F test/enc.test a55481d45ff493804e8d88357feb4642fc50a6b2 F test/enc2.test 8b00df318822731ea545365629bc9f52d73a3c6f -F test/expr.test 521588701dae8cf5aa2b8a18c5c897711f754332 +F test/expr.test 2262ade5e4e98e359b11e40b01cb3498ac7fa42b F test/fkey1.test d65c824459916249bee501532d6154ddab0b5db7 -F test/func.test a63cf7a16bbd9dd1430214f6a0625099faa530f3 +F test/func.test 5fb6008f8805f8ff1f41cf269cf675aff8923c04 F test/hook.test c4102c672d67f8fb60ea459842805abcba69a747 F test/in.test b92a2df9162e1cbd33c6449a29a05e6955b1741a F test/index.test 4d2e73647872b540df4335387cc91faff4365020 @@ -224,7 +224,7 @@ F www/support.tcl 1801397edd271cc39a2aadd54e701184b5181248 F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075 F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 -P b3d5ad6f7832d46e34e99e4a1cb7e47c88f207a4 -R d93bea5ab3d12a073c52b74c322a8b4e +P b1e66ae4640c2cd32d47c043b5c25ea67182098b +R 79cf4eb54da41f0b0cf0acbcc361a701 U danielk1977 -Z 8afc068f768f5a3187c752516f58beb6 +Z ebc17dbd051543173585388ad5a016a2 diff --git a/manifest.uuid b/manifest.uuid index efea0cd066..8bded2f41c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b1e66ae4640c2cd32d47c043b5c25ea67182098b \ No newline at end of file +b9493c5facea4d24a6cbc4f6fa2f75dc2399a11d \ No newline at end of file diff --git a/src/func.c b/src/func.c index e4660ecabd..015b200702 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.70 2004/06/16 10:39:24 danielk1977 Exp $ +** $Id: func.c,v 1.71 2004/06/17 05:36:44 danielk1977 Exp $ */ #include #include @@ -317,8 +317,8 @@ void deleteLike(void *pLike){ } +#if 0 /* #define TRACE_LIKE */ - #if defined(TRACE_LIKE) && !defined(NDEBUG) char *dumpLike(LikePattern *pLike){ int i; @@ -543,6 +543,31 @@ skip_read: sqlite3_result_int(context, 0); } } +#endif + +/* +** Implementation of the like() SQL function. This function implements +** the build-in LIKE operator. The first argument to the function is the +** pattern and the second argument is the string. So, the SQL statements: +** +** A LIKE B +** +** is implemented as like(B,A). +** +** If the pointer retrieved by via a call to sqlite3_user_data() is +** not NULL, then this function uses UTF-16. Otherwise UTF-8. +*/ +static void likeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + const unsigned char *zA = sqlite3_value_text(argv[0]); + const unsigned char *zB = sqlite3_value_text(argv[1]); + if( zA && zB ){ + sqlite3_result_int(context, sqlite3utf8LikeCompare(zA, zB)); + } +} /* ** Implementation of the glob() SQL function. This function implements @@ -785,6 +810,36 @@ static void test_destructor_count( ){ sqlite3_result_int(pCtx, test_destructor_count_var); } + +static void free_test_auxdata(void *p) {sqliteFree(p);} +static void test_auxdata( + sqlite3_context *pCtx, + int nArg, + sqlite3_value **argv +){ + int i; + char *zRet = sqliteMalloc(nArg*2); + if( !zRet ) return; + for(i=0; iflags & MEM_Term)!=0 || (pMem->flags & (MEM_Str|MEM_Blob))==0 ){ return SQLITE_OK; /* Nothing to do */ } - /* Only static or ephemeral strings can be unterminated */ - assert( (pMem->flags & (MEM_Static|MEM_Ephem))!=0 ); - return sqlite3VdbeMemMakeWriteable(pMem); + + if( pMem->flags & (MEM_Static|MEM_Ephem) ){ + return sqlite3VdbeMemMakeWriteable(pMem); + }else{ + if( pMem->flags & MEM_Dyn ){ + if( pMem->xDel ){ + char *z = sqliteMalloc(pMem->n+2); + if( !z ) return SQLITE_NOMEM; + memcpy(z, pMem->z, pMem->n); + pMem->xDel(pMem->z); + pMem->xDel = 0; + pMem->z = z; + }else{ + pMem->z = sqliteRealloc(pMem->z, pMem->n+2); + if( !pMem->z ) return SQLITE_NOMEM; + } + }else{ + assert( pMem->flags & MEM_Short ); + if( pMem->n+2>NBFS ){ + char *z = sqliteMalloc(pMem->n+2); + if( !z ) return SQLITE_NOMEM; + memcpy(z, pMem->z, pMem->n); + pMem->flags &= !(MEM_Short); + pMem->flags |= MEM_Dyn; + pMem->xDel = 0; + pMem->z = z; + } + } + pMem->z[pMem->n++] = 0; + pMem->z[pMem->n++] = 0; + } + return SQLITE_OK; } /* diff --git a/test/expr.test b/test/expr.test index 6fd003b0e2..bfc03aeb66 100644 --- a/test/expr.test +++ b/test/expr.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing expressions. # -# $Id: expr.test,v 1.33 2004/06/02 00:41:10 drh Exp $ +# $Id: expr.test,v 1.34 2004/06/17 05:36:45 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -232,6 +232,7 @@ test_expr expr-5.2 {t1='abc', t2='ABC'} {t1 LIKE t2} 1 test_expr expr-5.3 {t1='abc', t2='A_C'} {t1 LIKE t2} 1 test_expr expr-5.4 {t1='abc', t2='abc_'} {t1 LIKE t2} 0 test_expr expr-5.5 {t1='abc', t2='A%C'} {t1 LIKE t2} 1 +test_expr expr-5.5a {t1='abdc', t2='a%c'} {t1 LIKE t2} 1 test_expr expr-5.5b {t1='ac', t2='A%C'} {t1 LIKE t2} 1 test_expr expr-5.6 {t1='abxyzzyc', t2='A%C'} {t1 LIKE t2} 1 test_expr expr-5.7 {t1='abxyzzy', t2='A%C'} {t1 LIKE t2} 0 diff --git a/test/func.test b/test/func.test index 1a7a17cc16..66c547fe3d 100644 --- a/test/func.test +++ b/test/func.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this file is testing built-in functions. # -# $Id: func.test,v 1.21 2004/06/12 09:25:30 danielk1977 Exp $ +# $Id: func.test,v 1.22 2004/06/17 05:36:45 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -337,7 +337,14 @@ do_test func-11.1 { } [sqlite -version] # Test that destructors passed to sqlite by calls to sqlite3_result_text() -# etc. are called. +# etc. are called. These tests use two special user-defined functions +# (implemented in func.c) only available in test builds. +# +# Function test_destructor() takes one argument and returns a copy of the +# text form of that argument. A destructor is associated with the return +# value. Function test_destructor_count() returns the number of outstanding +# destructor calls for values returned by test_destructor(). +# do_test func-12.1 { execsql { SELECT test_destructor('hello world'), test_destructor_count(); @@ -371,6 +378,61 @@ do_test func-12.6 { SELECT test_destructor_count(); } } {0} +do_test func-12.7 { + execsql { + DROP TABLE t4; + } +} {} + +# Test that the auxdata API for scalar functions works. This test uses +# a special user-defined function only available in test builds, +# test_auxdata(). Function test_auxdata() takes any number of arguments. +do_test func-13.1 { + execsql { + SELECT test_auxdata('hello world'); + } +} {0} +do_test func-13.2 { + execsql { + CREATE TABLE t4(a, b); + INSERT INTO t4 VALUES('abc', 'def'); + INSERT INTO t4 VALUES('ghi', 'jkl'); + } +} {} +do_test func-13.3 { + execsql { + SELECT test_auxdata('hello world') FROM t4; + } +} {0 1} +do_test func-13.4 { + execsql { + SELECT test_auxdata('hello world', 123) FROM t4; + } +} {{0 0} {1 1}} +do_test func-13.5 { + execsql { + SELECT test_auxdata('hello world', a) FROM t4; + } +} {{0 0} {1 0}} +do_test func-13.6 { + execsql { + SELECT test_auxdata('hello'||'world', a) FROM t4; + } +} {{0 0} {1 0}} + +# Test that auxilary data is preserved between calls for SQL variables. +do_test func-13.7 { + db close + set DB [sqlite db test.db] + set sql "SELECT test_auxdata( ? , a ) FROM t4;" + set STMT [sqlite3_prepare $DB $sql -1 TAIL] + sqlite3_bind_text $STMT 1 hello -1 + set res [list] + while { "SQLITE_ROW"==[sqlite3_step $STMT] } { + lappend res [sqlite3_column_text $STMT 0] + } + lappend res [sqlite3_finalize $STMT] +} {{0 0} {1 0} SQLITE_OK} finish_test