sqlite.patch 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. Index: Makefile.in
  2. --- Makefile.in.orig 2010-07-18 21:30:41.000000000 +0200
  3. +++ Makefile.in 2010-07-22 21:25:22.000000000 +0200
  4. @@ -181,7 +181,7 @@
  5. table.lo tokenize.lo trigger.lo \
  6. update.lo util.lo vacuum.lo \
  7. vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbetrace.lo \
  8. - wal.lo walker.lo where.lo utf.o vtab.lo
  9. + wal.lo walker.lo where.lo utf.lo vtab.lo
  10. # Object files for the amalgamation.
  11. #
  12. @@ -191,6 +191,21 @@
  13. #
  14. LIBOBJ = $(LIBOBJS$(USE_AMALGAMATION))
  15. +# FTS3 support
  16. +ifdef FTS3
  17. +TCC += -DSQLITE_ENABLE_FTS3 -I$(TOP)/ext/fts3
  18. +endif
  19. +
  20. +# RTREE support
  21. +ifdef RTREE
  22. +TCC += -DSQLITE_ENABLE_RTREE -I$(TOP)/ext/rtree
  23. +endif
  24. +
  25. +# REGEXP support
  26. +ifdef REGEXP
  27. +TCC += -DSQLITE_ENABLE_REGEXP
  28. +LIBOBJ += regexp.lo
  29. +endif
  30. # All of the source code files.
  31. #
  32. @@ -325,6 +340,8 @@
  33. SRC += \
  34. $(TOP)/ext/rtree/rtree.h \
  35. $(TOP)/ext/rtree/rtree.c
  36. +SRC += \
  37. + $(TOP)/ext/regexp/regexp.c
  38. # Generated source code files
  39. @@ -835,6 +852,8 @@
  40. rtree.lo: $(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
  41. $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
  42. +regexp.lo: $(TOP)/ext/regexp/regexp.c $(HDR) $(EXTHDR)
  43. + $(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/regexp/regexp.c
  44. # Rules to build the 'testfixture' application.
  45. #
  46. Index: configure
  47. --- configure.orig 2010-07-18 21:30:41.000000000 +0200
  48. +++ configure 2010-07-22 21:24:57.000000000 +0200
  49. @@ -6012,11 +6012,7 @@
  50. if $ac_preproc_ok; then
  51. :
  52. else
  53. - { { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
  54. -See \`config.log' for more details." >&5
  55. -$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
  56. -See \`config.log' for more details." >&2;}
  57. - { (exit 1); exit 1; }; }
  58. + :
  59. fi
  60. ac_ext=c
  61. Index: ext/regexp/regexp.c
  62. --- ext/regexp/regexp.c.orig 2010-07-22 21:24:57.000000000 +0200
  63. +++ ext/regexp/regexp.c 2010-07-22 21:24:57.000000000 +0200
  64. @@ -0,0 +1,147 @@
  65. +/*
  66. + * SQLite REGEXP(regex, string) function
  67. + * Copyright (c) 2010 by Ralf S. Engelschall <rse@engelschall.com>
  68. + *
  69. + * Based on Public Domain code from 2007 by Alexey Tourbin
  70. + * <at@altlinux.org> which added plain PCRE based REGEXP function to
  71. + * SQLite. In order to not require the SQLite _library_ to require the
  72. + * external PCRE library, the code was adapted to the regex(3) API as
  73. + * standardized by IEEE Std 1003.2 ("POSIX.2"), sections 2.8 (Regular
  74. + * Expression Notation) and B.5 (C Binding for Regular Expression
  75. + * Matching) and which is usually provided already by any modern Unix
  76. + * system in libc.
  77. + */
  78. +
  79. +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_REGEXP)
  80. +
  81. +/* standard includes */
  82. +#include <assert.h>
  83. +#include <stdlib.h>
  84. +#include <string.h>
  85. +#include <regex.h>
  86. +
  87. +/* SQLite includes */
  88. +#ifndef SQLITE_CORE
  89. +#include "sqlite3ext.h"
  90. +SQLITE_EXTENSION_INIT1
  91. +#else
  92. +#include "sqlite3.h"
  93. +#endif
  94. +
  95. +/* regex cache configuration */
  96. +#ifndef CACHE_SIZE
  97. +#define CACHE_SIZE 32
  98. +#endif
  99. +typedef struct {
  100. + char *str;
  101. + regex_t re;
  102. +} cache_entry;
  103. +
  104. +/* the SQL REGEXP(regex, string) function C implementation */
  105. +static void regexp(sqlite3_context *ctx, int argc, sqlite3_value **argv)
  106. +{
  107. + const char *re_str, *str;
  108. + regex_t *re;
  109. + int i;
  110. + int rc;
  111. + int found;
  112. + cache_entry *cache;
  113. + cache_entry c;
  114. + char err[1024];
  115. +
  116. + /* sanity check arguments */
  117. + if (argc != 2) {
  118. + sqlite3_result_error(ctx, "invalid number of arguments to REGEXP function", -1);
  119. + return;
  120. + }
  121. + if ((re_str = (const char *)sqlite3_value_text(argv[0])) == NULL) {
  122. + sqlite3_result_error(ctx, "no regexp argument given to REGEXP function", -1);
  123. + return;
  124. + }
  125. + if ((str = (const char *)sqlite3_value_text(argv[1])) == NULL) {
  126. + sqlite3_result_error(ctx, "no string argument given to REGEXP function", -1);
  127. + return;
  128. + }
  129. +
  130. + /* simple regex LRU caching */
  131. + if ((cache = sqlite3_user_data(ctx)) == NULL) {
  132. + sqlite3_result_error(ctx, "no regex cache available", -1);
  133. + return;
  134. + }
  135. + found = 0;
  136. + for (i = 0; i < CACHE_SIZE && cache[i].str != NULL; i++) {
  137. + if (strcmp(re_str, cache[i].str) == 0) {
  138. + found = 1;
  139. + break;
  140. + }
  141. + }
  142. + if (found) {
  143. + if (i > 0) {
  144. + /* move cache[i] element to front for faster searching next time */
  145. + c = cache[i];
  146. + memmove(cache + 1, cache, i * sizeof(cache_entry));
  147. + cache[0] = c;
  148. + }
  149. + }
  150. + else {
  151. + /* compile and store regular expression */
  152. + int rc = regcomp(&(c.re), re_str, REG_EXTENDED|REG_NOSUB);
  153. + if (rc != 0) {
  154. + regerror(rc, &(c.re), err, sizeof(err));
  155. + char *e2 = sqlite3_mprintf("regex \"%s\" failed to compile: %s", re_str, err);
  156. + sqlite3_result_error(ctx, e2, -1);
  157. + sqlite3_free(e2);
  158. + return;
  159. + }
  160. + if ((c.str = strdup(re_str)) == NULL) {
  161. + sqlite3_result_error(ctx, "strdup: ENOMEM", -1);
  162. + regfree(&(c.re));
  163. + return;
  164. + }
  165. +
  166. + /* insert regex into cache (at first position) */
  167. + i = CACHE_SIZE - 1;
  168. + if (cache[i].str != NULL) {
  169. + /* expire oldest cache entry */
  170. + free(cache[i].str);
  171. + regfree(&(cache[i].re));
  172. + }
  173. + memmove(cache + 1, cache, i * sizeof(cache_entry));
  174. + cache[0] = c;
  175. + }
  176. +
  177. + /* take compiled regular expression (either found old one or created new one) */
  178. + re = &(cache[0].re);
  179. +
  180. + /* apply regular expression onto given string and report matching result */
  181. + rc = regexec(re, str, 0, NULL, 0);
  182. + sqlite3_result_int(ctx, rc == 0);
  183. +
  184. + return;
  185. +}
  186. +
  187. +/* SQLITE_CORE (built-in) entry point */
  188. +int sqlite3RegexpInit(sqlite3 *);
  189. +int sqlite3RegexpInit(sqlite3 *db)
  190. +{
  191. + cache_entry *cache = NULL;
  192. + int rc = SQLITE_OK;
  193. +
  194. + if ((cache = calloc(CACHE_SIZE, sizeof(cache_entry))) == NULL)
  195. + return SQLITE_NOMEM;
  196. + rc = sqlite3_create_function(db, "REGEXP", 2, SQLITE_UTF8, cache, regexp, NULL, NULL);
  197. + return rc;
  198. +}
  199. +
  200. +#ifndef SQLITE_CORE
  201. +/* DSO entry point */
  202. +int sqlite3_extension_init(sqlite3 *, char **, const sqlite3_api_routines *);
  203. +int sqlite3_extension_init(sqlite3 *db, char **err, const sqlite3_api_routines *api)
  204. +{
  205. + SQLITE_EXTENSION_INIT2(api)
  206. + return sqlite3RegexpInit(db);
  207. +}
  208. +#endif
  209. +
  210. +#endif
  211. +
  212. Index: sqlite3.pc.in
  213. --- sqlite3.pc.in.orig 2010-06-21 13:48:22.000000000 +0200
  214. +++ sqlite3.pc.in 2010-07-22 21:24:57.000000000 +0200
  215. @@ -8,6 +8,5 @@
  216. Name: SQLite
  217. Description: SQL database engine
  218. Version: @RELEASE@
  219. -Libs: -L${libdir} -lsqlite3
  220. -Libs.private: @LIBS@
  221. +Libs: -L${libdir} -lsqlite3 @LIBS@
  222. Cflags: -I${includedir}
  223. Index: src/main.c
  224. --- src/main.c.orig 2010-07-18 21:30:41.000000000 +0200
  225. +++ src/main.c 2010-07-22 21:24:57.000000000 +0200
  226. @@ -1869,6 +1869,13 @@
  227. }
  228. #endif
  229. +#ifdef SQLITE_ENABLE_REGEXP
  230. + if( !db->mallocFailed && rc==SQLITE_OK){
  231. + extern int sqlite3RegexpInit(sqlite3*);
  232. + rc = sqlite3RegexpInit(db);
  233. + }
  234. +#endif
  235. +
  236. sqlite3Error(db, rc, 0);
  237. /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking