]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Enhance the REGEXP extension so that it will accept the start-of-input
authordrh <>
Mon, 18 Jul 2022 13:55:21 +0000 (13:55 +0000)
committerdrh <>
Mon, 18 Jul 2022 13:55:21 +0000 (13:55 +0000)
mark ("^") in the middle of parentheses.
[forum:/forumpost/0d6a9160f81ef1a8|Forum post 0d6a9160f81ef1a8].

FossilOrigin-Name: ed8a8ebd62a319b5dabbdf67ee27141153b9899d7c8f08eeb4bdf35271015c71

ext/misc/regexp.c
manifest
manifest.uuid
test/regexp1.test

index 8a3e13115ff646d4c5a8f194f03e6a30d87b75ca..7413ab80ec3b345b4f4deb913a118c4cb98f992e 100644 (file)
@@ -72,6 +72,7 @@ SQLITE_EXTENSION_INIT1
 
 /* The end-of-input character */
 #define RE_EOF            0    /* End of input */
+#define RE_START  0xfffffff    /* Start of input - larger than an UTF-8 */
 
 /* The NFA is implemented as sequence of opcodes taken from the following
 ** set.  Each opcode has a single integer argument.
@@ -93,6 +94,7 @@ SQLITE_EXTENSION_INIT1
 #define RE_OP_SPACE      15    /* space:  [ \t\n\r\v\f] */
 #define RE_OP_NOTSPACE   16    /* Not a digit */
 #define RE_OP_BOUNDARY   17    /* Boundary between word and non-word */
+#define RE_OP_ATSTART    18    /* Currently at the start of the string */
 
 #if defined(SQLITE_DEBUG)
 /* Opcode names used for symbolic debugging */
@@ -115,6 +117,7 @@ static const char *ReOpName[] = {
   "SPACE",
   "NOTSPACE",
   "BOUNDARY",
+  "ATSTART",
 };
 #endif /* SQLITE_DEBUG */
 
@@ -225,7 +228,7 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
   ReStateNumber *pToFree;
   unsigned int i = 0;
   unsigned int iSwap = 0;
-  int c = RE_EOF+1;
+  int c = RE_START;
   int cPrev = 0;
   int rc = 0;
   ReInput in;
@@ -244,6 +247,7 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
       in.i++;
     }
     if( in.i+pRe->nInit>in.mx ) return 0;
+    c = RE_START-1;
   }
 
   if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
@@ -272,6 +276,10 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
           if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
           break;
         }
+        case RE_OP_ATSTART: {
+          if( cPrev==RE_START ) re_add_state(pThis, x+1);
+          break;
+        }
         case RE_OP_ANY: {
           if( c!=0 ) re_add_state(pNext, x+1);
           break;
@@ -550,6 +558,10 @@ static const char *re_subcompile_string(ReCompiled *p){
         re_append(p, RE_OP_MATCH, RE_EOF);
         break;
       }
+      case '^': {
+        re_append(p, RE_OP_ATSTART, 0);
+        break;
+      }
       case '{': {
         int m = 0, n = 0;
         int sz, j;
index 643970b2d406ef1b6772f486453044a55f02efdc..be8d9e29ffda05d0f2c231964d76c228d367d0fc 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sproblem\sin\sthe\sREGEXP\sextension\sfor\sthe\s{M,N}\sconstruct\swhere\sM\sis\szero.\nSee\s[forum:/forumpost/8694e55a2c29963c|forum\spost\s8694e55a2c29963c]\sfor\smore\ninformation.
-D 2022-07-18T13:10:53.496
+C Enhance\sthe\sREGEXP\sextension\sso\sthat\sit\swill\saccept\sthe\sstart-of-input\nmark\s("^")\sin\sthe\smiddle\sof\sparentheses.\n[forum:/forumpost/0d6a9160f81ef1a8|Forum\spost\s0d6a9160f81ef1a8].
+D 2022-07-18T13:55:21.667
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -334,7 +334,7 @@ F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d
 F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691
 F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196
 F ext/misc/qpvtab.c 09738419e25f603a35c0ac8bd0a04daab794f48d08a9bc07a6085b9057b99009
-F ext/misc/regexp.c 76693a7c74555947fb90bda00082b0a67ff40ac08b78c022b24623d85772fb75
+F ext/misc/regexp.c 1459fe1452b61aafb25b11d7144f3dabfaf890b566c4ef9cfa4dc270451a8f02
 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c
 F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c
 F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946
@@ -1343,7 +1343,7 @@ F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
 F test/rbu.test 168573d353cd0fd10196b87b0caa322c144ef736
 F test/rdonly.test 64e2696c322e3538df0b1ed624e21f9a23ed9ff8
 F test/recover.test ccb8c2623902a92ebb76770edd075cb4f75a4760bb7afde38026572c6e79070d
-F test/regexp1.test d5d019b599d04475b1e6291ff87befeb6b6436fe8a5c96df0cd1afdd4c521860
+F test/regexp1.test 83c631617357150f8054ca1d1fed40a552b0d0f8eb7a7f090c3be02cee9f9913
 F test/regexp2.test 55ed41da802b0e284ac7e2fe944be3948f93ff25abbca0361a609acfed1368b5
 F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d
 F test/releasetest_data.tcl 11ba48a21ed1c808147b0e77c6e93d204577f4327ffe6d7c3b34cd3c01eac3a2
@@ -1980,8 +1980,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P cb5c08978fe8f074e6ae16953575213709e98b8bbae4359e0d2e6de67a7ea9e5
-R 37f87d1133b807cf92a2fb764578dc08
+P af15bb75306a4b94593b8431a34768b3de3d6689293e85ca02db16bf3e9f39e2
+R 012943bc0a0dde589766791fd61f6489
 U drh
-Z e81c08e4815bfae8cfa31e84be51c0a0
+Z 6dd034c999f521ca4e2cae722ceb4800
 # Remove this line to create a well-formed Fossil manifest.
index 65040fd41bdf61372bcc03ee7cd30e2408427427..0d563f647d07a90c17b90a0a4c8d76f5125a4366 100644 (file)
@@ -1 +1 @@
-af15bb75306a4b94593b8431a34768b3de3d6689293e85ca02db16bf3e9f39e2
\ No newline at end of file
+ed8a8ebd62a319b5dabbdf67ee27141153b9899d7c8f08eeb4bdf35271015c71
\ No newline at end of file
index d7a12ceed17f0fc5392229fbd2d204bf8e9f810c..102c1280c09534aaf4bac2f3dcf74ddb0a3733bb 100644 (file)
@@ -289,6 +289,20 @@ do_execsql_test regexp1-5.3 {SELECT 'fooX' REGEXP '^[a-z][a-z0-9]{0,2}X$';} {1}
 do_execsql_test regexp1-5.4 {SELECT 'foooX' REGEXP '^[a-z][a-z0-9]{0,2}X$';} {0}
 do_execsql_test regexp1-5.5 {SELECT 'foooX' REGEXP '^[a-z][a-z0-9]{0,3}X$';} {1}
 
+# 2022-07-18
+# https://sqlite.org/forum/forumpost/18f87fdcdf
+# Allow "^" to occur inside of "(..)"
+#
+do_execsql_test regexp1-6.1 {SELECT 'foo' REGEXP '[a-z]';} {1}
+do_execsql_test regexp1-6.2 {SELECT 'foo' REGEXP '^[a-z]+$';} {1}
+do_execsql_test regexp1-6.3 {SELECT 'foo' REGEXP '^([a-z]+)$';} {1}
+do_execsql_test regexp1-6.4 {SELECT 'foo' REGEXP '(^[a-z]+)$';} {1}
+do_execsql_test regexp1-6.5 {SELECT 'foo' REGEXP '(^[a-z]+$)';} {1}
+do_execsql_test regexp1-6.6 {SELECT 'abc' REGEXP '(^abc|def)';} {1}
+do_execsql_test regexp1-6.7 {SELECT 'xabc' REGEXP '(^abc|def)';} {0}
+do_execsql_test regexp1-6.8 {SELECT 'def' REGEXP '(^abc|def)';} {1}
+do_execsql_test regexp1-6.9 {SELECT 'xdef' REGEXP '(^abc|def)';} {1}
+
 
 
 finish_test