]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add an implementation of the REGEXP operator and function. Only defined regexp
authordrh <drh@noemail.net>
Wed, 12 Sep 2012 18:45:31 +0000 (18:45 +0000)
committerdrh <drh@noemail.net>
Wed, 12 Sep 2012 18:45:31 +0000 (18:45 +0000)
if compiled with SQLITE_ENABLE_REGEXP.

FossilOrigin-Name: 8398f77c5a689c795c5b1e8eea41a3b128dba2fd

manifest
manifest.uuid
src/ctime.c
src/func.c
test/e_expr.test
test/like.test

index d2a266f2417ed70da6a2b667d0c788db003069ac..69de9a7e319f6955aa03cff5d2da02ff5a06be4e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\sversion\snumber\sto\s3.7.15.\s\sDelete\ssome\sobsolete\sbuild\sscripts.
-D 2012-09-12T00:11:20.574
+C Add\san\simplementation\sof\sthe\sREGEXP\soperator\sand\sfunction.\s\sOnly\sdefined\nif\scompiled\swith\sSQLITE_ENABLE_REGEXP.
+D 2012-09-12T18:45:31.050
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in abd5c10d21d1395f140d9e50ea999df8fa4d6376
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -127,13 +127,13 @@ F src/btreeInt.h 4e5c2bd0f9b36b2a815a6d84f771a61a65830621
 F src/build.c a3b700afd475e6387da59be6f2e86161e80d6d87
 F src/callback.c 0cb4228cdcd827dcc5def98fb099edcc9142dbcd
 F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
-F src/ctime.c 500d019da966631ad957c37705642be87524463b
+F src/ctime.c a67101c1a1175167b5f40d4a626bf2eae7a1a2c4
 F src/date.c 067a81c9942c497aafd2c260e13add8a7d0c7dd4
 F src/delete.c 335f36750dc6ac88d580aa36a6487459be9889de
 F src/expr.c 217840a107dcc1e5dbb57cea311daad04bedbb9a
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 9c77d842dc9961d92a06a65abb80c64ef1750296
-F src/func.c b4e88b92838fdab8e0088cc8411c06664b4dcf55
+F src/func.c 2290b491113e37df29c721c4b69a8aaf641b7664
 F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b
 F src/hash.c a4031441741932da9e7a65bee2b36b5d0e81c073
 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
@@ -379,7 +379,7 @@ F test/e_createtable.test 48598b15e8fe6554d301e7b65a10c9851f177e84
 F test/e_delete.test 89aa84d3d1bd284a0689ede04bce10226a5aeaa5
 F test/e_droptrigger.test afd5c4d27dec607f5997a66bf7e2498a082cb235
 F test/e_dropview.test 583411e470458c5d76148542cfb5a5fa84c8f93e
-F test/e_expr.test 5489424d3d9a452ac3701cdf4b680ae31a157894
+F test/e_expr.test 5bc5c9a9eca98ae9a2be449869be7dea5105ed9b
 F test/e_fkey.test 057eed81a41a2b21b1790032f4e8aaba0b2b0e17
 F test/e_fts3.test 5c02288842e4f941896fd44afdef564dd5fc1459
 F test/e_insert.test c6ac239a97cb16dfbd0c16496f8cd871b4068c0c
@@ -564,7 +564,7 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
 F test/keyword1.test a2400977a2e4fde43bf33754c2929fda34dbca05
 F test/lastinsert.test 474d519c68cb79d07ecae56a763aa7f322c72f51
 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
-F test/like.test 7b4aaa4a8192fdec90e0a905984c92a688c51e48
+F test/like.test 25bca9aab5ea225d98516deefcfe63f7980753bc
 F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
 F test/limit.test 2db7b3b34fb925b8e847d583d2eb67531d0ce67e
 F test/loadext.test 2b5e249c51c986a5aff1f0950cf7ba30976c8f22
@@ -1012,7 +1012,10 @@ F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
 F tool/win/sqlite.vsix 67d8a99aceb56384a81b3f30d6c71743146d2cc9
-P bf8a9ca5b58404112a8af666f5840b462b7bbfe1
-R 847379dec46339e4d4e3d3e07e9871f0
+P 9402f81fade5fcae0a3a6efdc7a5cdf71fc2e79f
+R b672680dc581b045b45a052a3b299996
+T *branch * regexp
+T *sym-regexp *
+T -sym-trunk *
 U drh
-Z a42f3ee2165757bae1503891985c3bca
+Z 41a8b832e7bd7f20e716b240445415a6
index 9a08d83f21078169218fefa5291d5f5953dc4a10..10a7768f61683711f83e40b4c2ec6193c99060bf 100644 (file)
@@ -1 +1 @@
-9402f81fade5fcae0a3a6efdc7a5cdf71fc2e79f
\ No newline at end of file
+8398f77c5a689c795c5b1e8eea41a3b128dba2fd
\ No newline at end of file
index 61cf4e3df12a9d08df18a6ef701818e9d3750ffb..11074d1440a7f90a899b6c9d3555977154f6cbe9 100644 (file)
@@ -114,6 +114,9 @@ static const char * const azCompileOpt[] = {
 #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
   "ENABLE_OVERSIZE_CELL_CHECK",
 #endif
+#ifdef SQLITE_ENABLE_REGEXP
+  "ENABLE_REGEXP",
+#endif
 #ifdef SQLITE_ENABLE_RTREE
   "ENABLE_RTREE",
 #endif
index 9d81d0c74114081adbc38eea15306c71c19ef898..962a9895f764178ef406151c1d71aacedd34eb56 100644 (file)
@@ -713,6 +713,64 @@ static void likeFunc(
   }
 }
 
+#if defined(SQLITE_ENABLE_REGEXP)
+#include <sys/types.h>
+#include <regex.h>
+
+/*
+** Free a regex_t object obtained from sqlite_malloc().
+*/
+static void regexpFree(void *pToFree){
+  regex_t *pRe = (regex_t*)pToFree;
+  regfree(pRe);
+  sqlite3_free(pRe);
+}
+
+/*
+** Implementation of the regexp() SQL function.  This function implements
+** the build-in REGEXP operator.  The first argument to the function is the
+** pattern and the second argument is the string.  So, the SQL statements:
+**
+**       A REGEXP B
+**
+** is implemented as regexp(B,A).
+*/
+static void regexpFunc(
+  sqlite3_context *context, 
+  int argc, 
+  sqlite3_value **argv
+){
+  regex_t *pRe;
+  int rc;
+  char zErr[100];
+
+  pRe = sqlite3_get_auxdata(context, 0);
+  if( pRe==0 ){
+    pRe = sqlite3_malloc( sizeof(*pRe) );
+    if( pRe==0 ){
+      sqlite3_result_error_nomem(context);
+      return;
+    }
+    memset(pRe, 0, sizeof(*pRe));
+    rc = regcomp(pRe, (const char*)sqlite3_value_text(argv[0]),
+                 REG_NOSUB|REG_EXTENDED);
+    if( rc ){
+      regerror(rc, pRe, zErr, sizeof(zErr));
+      sqlite3_result_error(context, zErr, -1);
+      regfree(pRe);
+    }else{
+      sqlite3_set_auxdata(context, 0, pRe, regexpFree);
+    }
+  }
+  rc = regexec(pRe, (const char*)sqlite3_value_text(argv[1]), 0, 0, 0);
+  if( rc==0 ){
+    sqlite3_result_int(context, 1);
+  }else{
+    sqlite3_result_int(context, 0);
+  }
+}
+#endif /* defined(SQLITE_ENABLE_REGEXP) */
+
 /*
 ** Implementation of the NULLIF(x,y) function.  The result is the first
 ** argument if the arguments are different.  The result is NULL if the
@@ -1590,6 +1648,10 @@ void sqlite3RegisterGlobalFunctions(void){
     LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
     LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
   #endif
+
+#if defined(SQLITE_ENABLE_REGEXP)
+    FUNCTION(regexp,             2, 0, 0, regexpFunc       ),
+#endif
   };
 
   int i;
index 74d0c407129e13f1f72e8f10070e6154dc072afe..9d36337ad4aea1ae02924be3da3c715f61e44728 100644 (file)
@@ -1063,7 +1063,8 @@ do_execsql_test e_expr-17.3.3 { SELECT 'X' NOT GLOB 'Y' } 0
 do_test         e_expr-17.3.4 { set globargs } {Y X}
 sqlite3 db test.db
 
-# EVIDENCE-OF: R-41650-20872 No regexp() user function is defined by
+if 0 {
+# xxxxEVIDENCE-OF: R-41650-20872 No regexp() user function is defined by
 # default and so use of the REGEXP operator will normally result in an
 # error message.
 #
@@ -1077,6 +1078,7 @@ ifcapable !icu {
     SELECT 'abc' REGEXP 'def'
   } {1 {no such function: REGEXP}}
 }
+}
 
 # EVIDENCE-OF: R-33693-50180 The REGEXP operator is a special syntax for
 # the regexp() user function.
index 767efd5828f46896a00fe1fca52bc8ed874ddd21..f779ee9aa2476e27779b10c2666c361eb8d968c7 100644 (file)
@@ -114,11 +114,15 @@ do_test like-1.10 {
 
 # Tests of the REGEXP operator
 #
-do_test like-2.1 {
+db eval {SELECT sqlite_compileoption_used('ENABLE_REGEXP') AS has_regexp} break;
+if {$has_regexp==0} {
   proc test_regexp {a b} {
     return [regexp $a $b]
   }
   db function regexp -argcount 2 test_regexp
+  puts "# installing substitute REGEXP function"
+}
+do_test like-2.1 {
   execsql {
     SELECT x FROM t1 WHERE x REGEXP 'abc' ORDER BY 1;
   }