sqlite.patch 7.7 KB

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