]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the load_extension() SQL function. (CVS 3269)
authordrh <drh@noemail.net>
Sat, 17 Jun 2006 14:12:47 +0000 (14:12 +0000)
committerdrh <drh@noemail.net>
Sat, 17 Jun 2006 14:12:47 +0000 (14:12 +0000)
FossilOrigin-Name: e08e2ddafe909ae6073ec56dfa3fdca23e36bf2e

manifest
manifest.uuid
src/func.c
test/loadext.test
www/lang.tcl

index f4bd6c436122064f6fb042acb7f515becdda5ac8..063f8c4d692177f5011c63d5a79f67c5439fa543 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C The\sdefault\sentry\spoint\sfor\sloadable\sextensions\sis\snow\nalways\ssqlite3_extension_init().\s(CVS\s3268)
-D 2006-06-17T13:21:32
+C Add\sthe\sload_extension()\sSQL\sfunction.\s(CVS\s3269)
+D 2006-06-17T14:12:48
 F Makefile.in f839b470345d3cb4b0644068474623fe2464b5d3
 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -43,7 +43,7 @@ F src/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e
 F src/delete.c e6a324650fb9f6afe5757ec5c7d8dad62d9496b8
 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b
 F src/expr.c 78b521337d628b1fd9d87b12dbbe771247aab585
-F src/func.c 01e559893b5e43bea85135ad3e481d86c447942a
+F src/func.c a8a52723878b38ad275513b81260c29980332504
 F src/hash.c 449f3d6620193aa557f5d86cbc5cc6b87702b185
 F src/hash.h 1b3f7e2609141fd571f62199fc38687d262e9564
 F src/insert.c 5c1fddd7e4d05805e02e12bdced2a3841d2bd8dc
@@ -196,7 +196,7 @@ F test/lastinsert.test 9d7241f562d7adcf61730de83176417d7e30d76b
 F test/laststmtchanges.test 19a6d0c11f7a31dc45465b495f7b845a62cbec17
 F test/like.test 5f7d76574752a9101cac13372c8a85999d0d91e6
 F test/limit.test 71884068d47b18f614735f0686690319b32cdc22
-F test/loadext.test 30b38ddaf4ca0703833903bf8ab2e9a680d9cfeb
+F test/loadext.test c5790632f1ae974e8c01d43c859a56bb8c08ded6
 F test/lock.test 9b7afcb24f53d24da502abb33daaad2cd6d44107
 F test/lock2.test d83ba79d3c4fffdb5b926c7d8ca7a36c34288a55
 F test/lock3.test 615111293cf32aa2ed16d01c6611737651c96fb9
@@ -348,7 +348,7 @@ F www/fullscanb.gif f7c94cb227f060511f8909e10f570157263e9a25
 F www/index-ex1-x-b.gif f9b1d85c3fa2435cf38b15970c7e3aa1edae23a3
 F www/index.tcl 1d4a2d4011bbc85e060b36094c071e3c47cd786b
 F www/indirect1b1.gif adfca361d2df59e34f9c5cac52a670c2bfc303a1
-F www/lang.tcl 46d34df01cbb3fb280aa9389a144a33f90e0c495
+F www/lang.tcl 432ee67f7528dd6e6313f149d5df33cad2dfb359
 F www/lockingv3.tcl f59b19d6c8920a931f096699d6faaf61c05db55f
 F www/mingw.tcl d96b451568c5d28545fefe0c80bee3431c73f69c
 F www/nulls.tcl ec35193f92485b87b90a994a01d0171b58823fcf
@@ -370,7 +370,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P ea7e4eca106cea27d5dc447d2afcd45448152151
-R 02aad4e8db5989bcc93408708ac41194
+P 059b1f61406ca60fdbd3ec59c5b15fadc6552564
+R 6e75aa9555d6b6ac99ebbabeb152a126
 U drh
-Z 306df56e80d8ad47056ba5abd005e0af
+Z 6bcb5d58c602d9ee2f0ac3771c819d7b
index 5564b877c79de2995a710c768fd866cf972e4b0d..a59f631f77e2790d3ae2bbd4113c2e929984eb6a 100644 (file)
@@ -1 +1 @@
-059b1f61406ca60fdbd3ec59c5b15fadc6552564
\ No newline at end of file
+e08e2ddafe909ae6073ec56dfa3fdca23e36bf2e
\ No newline at end of file
index 9d62e54f3012493ec93eaf216efea580d8a90706..375346aa761c96865b4b983d1bc924a928353acf 100644 (file)
@@ -16,7 +16,7 @@
 ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: func.c,v 1.130 2006/06/13 19:26:11 drh Exp $
+** $Id: func.c,v 1.131 2006/06/17 14:12:48 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -676,6 +676,26 @@ static void soundexFunc(sqlite3_context *context, int argc, sqlite3_value **argv
 }
 #endif
 
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+/*
+** A function that loads a shared-library extension then returns NULL.
+*/
+static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){
+  const char *zFile = sqlite3_value_text(argv[0]);
+  const char *zProc = 0;
+  sqlite3 *db = sqlite3_user_data(context);
+  char *zErrMsg = 0;
+
+  if( argc==2 ){
+    zProc = sqlite3_value_text(argv[1]);
+  }
+  if( sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){
+    sqlite3_result_error(context, zErrMsg, -1);
+    sqlite3_free(zErrMsg);
+  }
+}
+#endif
+
 #ifdef SQLITE_TEST
 /*
 ** This function generates a string of random characters.  Used for
@@ -1021,6 +1041,10 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
 #ifdef SQLITE_SOUNDEX
     { "soundex",            1, 0, SQLITE_UTF8, 0, soundexFunc},
 #endif
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
+    { "load_extension",     1, 1, SQLITE_UTF8,    0, loadExt },
+    { "load_extension",     2, 1, SQLITE_UTF8,    0, loadExt },
+#endif
 #ifdef SQLITE_TEST
     { "randstr",               2, 0, SQLITE_UTF8, 0, randStr    },
     { "test_destructor",       1, 1, SQLITE_UTF8, 0, test_destructor},
index 52171731548098a1f16b6aed5ff6f80a2079f1aa..ba0d2f87d157c581410be01f68680a7d69a2fd81 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is in-memory database backend.
 #
-# $Id: loadext.test,v 1.2 2006/06/17 13:21:33 drh Exp $
+# $Id: loadext.test,v 1.3 2006/06/17 14:12:48 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -130,4 +130,32 @@ do_test loadext-2.4 {
   list $rc $msg
 } {1 {error during initialization: broken!}}
 
+############################################################################
+# Tests for the load_extension() SQL function
+#
+
+db close
+sqlite3 db test.db
+do_test loadext-3.1 {
+  catchsql {
+    SELECT half(5);
+  }
+} {1 {no such function: half}}
+do_test loadext-3.2 {
+  catchsql {
+    SELECT load_extension($::testextension)
+  }
+} [list 1 "no entry point \[sqlite3_extension_init\]\
+           in shared library \[$testextension\]"]
+do_test loadext-3.3 {
+  catchsql {
+    SELECT load_extension($::testextension,'testloadext_init')
+  }
+} {0 {{}}}
+do_test loadext-3.4 {
+  catchsql {
+    SELECT half(5);
+  }
+} {0 2.5}
+
 finish_test
index 5226ef3cd6bcad95c03b3a039a989add3b7f1f15..fc3811811a26e545ae1d2620812b430ab7bad586 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the lang-*.html files.
 #
-set rcsid {$Id: lang.tcl,v 1.112 2006/05/31 11:12:01 drh Exp $}
+set rcsid {$Id: lang.tcl,v 1.113 2006/06/17 14:12:48 drh Exp $}
 source common.tcl
 
 if {[llength $argv]>0} {
@@ -962,7 +962,7 @@ Syntax {expr} {
 CASE [<expr>] LP WHEN <expr> THEN <expr> RPPLUS [ELSE <expr>] END |
 CAST ( <expr> AS <type> )
 } {like-op} {
-LIKE | GLOB | REGEXP
+LIKE | GLOB | REGEXP | MATCH
 }
 
 puts {
@@ -991,6 +991,10 @@ OR</font>
 <font color="#2c2cf0"><big>-    +    !    ~    NOT</big></font>
 </pre></blockquote>
 
+<p>The unary operator [Operator +] is a no-op.  It can be applied
+to strings, numbers, or blobs and it always gives as its result the
+value of the operand.</p>
+
 <p>Note that there are two variations of the equals and not equals
 operators.  Equals can be either}
 puts "[Operator =] or [Operator ==].
@@ -1056,6 +1060,10 @@ The number assigned is the next unused number.  To avoid confusion,
 it is best to avoid mixing named and numbered parameters.</td>
 </tr>
 <tr>
+<td align="right" valign="top"><b>@</b><i>AAAA</i></td><td width="20"></td>
+<td>An "at" sign works exactly like a colon.</td>
+</tr>
+<tr>
 <td align="right" valign="top"><b>$</b><i>AAAA</i></td><td width="20"></td>
 <td>A dollar-sign followed by an identifier name also holds a spot for a named
 parameter with the name AAAA.  The identifier name in this case can include
@@ -1127,9 +1135,16 @@ that function.</p>
 user function.  No regexp() user function is defined by default
 and so use of the REGEXP operator will normally result in an
 error message.  If a user-defined function named "regexp"
-is defined at run-time, that function will be called in order
+is added at run-time, that function will be called in order
 to implement the REGEXP operator.</p>
 
+<a name="match"></a>
+<p>The MATCH operator is a special syntax for the match()
+user function.  The default match() function implementation
+raises and exception and is not really useful for anything.
+But extensions can override the match() function with more
+helpful logic.</p>
+
 <p>A column name can be any of the names defined in the CREATE TABLE
 statement or one of the following special identifiers: "<b>ROWID</b>",
 "<b>OID</b>", or "<b>_ROWID_</b>".
@@ -1249,6 +1264,16 @@ LIKE operator depending on whether or not an ESCAPE clause was
 specified.</td>
 </tr>
 
+<tr>
+<td valign="top" align="right">load_extension(<i>X</i>)<br>
+load_extension(<i>X</i>,<i>Y</i>)</td>
+<td valign="top">Load SQLite extensions out of the shared library
+file named <i>X</i> using the entry point <i>Y</i>.  The result
+is a NULL.  If <i>Y</i> is omitted then the default entry point
+of <b>sqlite3_extension_init</b> is used.  This function raises
+an exception if the extension fails to load or initialize correctly.
+</tr>
+
 <tr>
 <td valign="top" align="right">lower(<i>X</i>)</td>
 <td valign="top">Return a copy of string <i>X</i> will all characters
@@ -1294,8 +1319,8 @@ is also useful when writing triggers to implement undo/redo functionality.
 
 <tr>
 <td valign="top" align="right">random(*)</td>
-<td valign="top">Return a random integer between -2147483648 and
-+2147483647.</td>
+<td valign="top">Return a pseudo-random integer
+between -9223372036854775808 and +9223372036854775807.</td>
 </tr>
 
 <tr>