]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix for ticket #1: Implement the GLOB and LIKE operators as functions that
authordrh <drh@noemail.net>
Sat, 20 Apr 2002 14:24:41 +0000 (14:24 +0000)
committerdrh <drh@noemail.net>
Sat, 20 Apr 2002 14:24:41 +0000 (14:24 +0000)
can be overridden.  This way, a developer can change the LIKE operator to
be case sensitive, for example. (CVS 537)

FossilOrigin-Name: 51572bf71774d7631c7083be90b806e621bc9bee

VERSION
manifest
manifest.uuid
src/expr.c
src/func.c
src/parse.y
src/vdbe.c
src/vdbe.h
tool/speedtest.tcl

diff --git a/VERSION b/VERSION
index e30309f735e40c4eb0347dc467f7dc970cf574c3..f041bc6dba218c58ccee9b909685a8c1db543b0f 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.4.7
+2.4.8
index d1483440c86ba245fdc4b3a664e4fb80a663314a..6b8e1adb8d0e4c470b21bc9d819b1c746d64a5ac 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,9 +1,9 @@
-C Add\ssupport\sfor\ssaving\sthe\ssqlite\sshell\scommand-line\shistory\sacross\ssessions.\s(CVS\s536)
-D 2002-04-19T12:34:06
+C Fix\sfor\sticket\s#1:\sImplement\sthe\sGLOB\sand\sLIKE\soperators\sas\sfunctions\sthat\ncan\sbe\soverridden.\s\sThis\sway,\sa\sdeveloper\scan\schange\sthe\sLIKE\soperator\sto\nbe\scase\ssensitive,\sfor\sexample.\s(CVS\s537)
+D 2002-04-20T14:24:42
 F Makefile.in 50f1b3351df109b5774771350d8c1b8d3640130d
 F Makefile.template 89e373b2dad0321df00400fa968dc14b61a03296
 F README a4c0ba11354ef6ba0776b400d057c59da47a4cc0
-F VERSION bb2c45e1821c29d3e52ea953e25a4c4a2d2f15e7
+F VERSION 5446cf3087aa40ee419d025faa144cfb7da913b7
 F aclocal.m4 11faa843caa38fd451bc6aeb43e248d1723a269d
 F config.guess f38b1e93d1e0fa6f5a6913e9e7b12774b9232588
 F config.log 6a73d03433669b10a3f0c221198c3f26b9413914
@@ -24,8 +24,8 @@ F src/btree.c 7dd7ddc66459982dd0cb9800958c1f8d65a32d9f
 F src/btree.h 8abeabfe6e0b1a990b64fa457592a6482f6674f3
 F src/build.c d01b81f41481e733e27ab2fa8e1bfcc64f24257d
 F src/delete.c 6a6b8192cdff5e4b083da3bc63de099f3790d01f
-F src/expr.c e7a1e22bc2ebcd789f0f8c0db544cf16ad664054
-F src/func.c dca9df811298cd0beb3724d40cee348e884352b2
+F src/expr.c cf8d2ea17e419fc83b23e080195b2952e0be4164
+F src/func.c a31dcba85bc2ecb9b752980289cf7e6cd0cafbce
 F src/hash.c cc259475e358baaf299b00a2c7370f2b03dda892
 F src/hash.h dca065dda89d4575f3176e75e9a3dc0f4b4fb8b9
 F src/insert.c 31233f44fc79edbb43523a830e54736a8e222ff4
@@ -35,7 +35,7 @@ F src/os.c 5ab8b6b4590d0c1ab8e96c67996c170e4462e0fc
 F src/os.h 4a361fccfbc4e7609b3e1557f604f94c1e96ad10
 F src/pager.c ba5740104cc27b342cd43eebfdc44d60f64a3ded
 F src/pager.h 6fddfddd3b73aa8abc081b973886320e3c614f0e
-F src/parse.y 9a8a2311dd95101bb02b3991042e619eea49729a
+F src/parse.y 0ce56f1c751657f01e18a4b4ac1aa4d29525ac20
 F src/printf.c 300a90554345751f26e1fc0c0333b90a66110a1d
 F src/random.c 19e8e00fe0df32a742f115773f57651be327cabe
 F src/select.c 92aef3f69e90dc065d680d88b1f075409e9249bb
@@ -52,8 +52,8 @@ F src/threadtest.c 81f0598e0f031c1bd506af337fdc1b7e8dff263f
 F src/tokenize.c 5624d342601f616157ba266abccc1368a5afee70
 F src/update.c 7dd714a6a7fa47f849ebb36b6d915974d6c6accb
 F src/util.c b34cd91387bbfdc79319ea451a7d120cef478120
-F src/vdbe.c 9213ff1ab136eabcf3e8a58157765a01274bf8e9
-F src/vdbe.h f9be1f6e9a336c3ff4d14ea7489ee976e07460cc
+F src/vdbe.c 0ed88fff32273c103a24396d491b71bc69b4b596
+F src/vdbe.h 67840a462e1daedb958cca0ccc97db140d3d9152
 F src/where.c 9d36f6c9fea4af71501770c13089f824cb9b033c
 F test/all.test 6aa106eee4d7127afa5cee97c51a783a79694ead
 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
@@ -110,7 +110,7 @@ F tool/opNames.awk 5ba1f48aa854ee3b7c3d2b54233665bc3e649ea2
 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
 F tool/renumberOps.awk 6d067177ad5f8d711b79577b462da9b3634bd0a9
 F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
-F tool/speedtest.tcl 6d89431651f2eb800fb0998a8de44b84168e08b9
+F tool/speedtest.tcl 8287851340fd4a9500a69e9b10fb5ed9e6b0d0c3
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F www/arch.fig d5f9752a4dbf242e9cfffffd3f5762b6c63b3bcf
 F www/arch.png 82ef36db1143828a7abc88b1e308a5f55d4336f4
@@ -131,7 +131,7 @@ F www/speed.tcl da8afcc1d3ccc5696cfb388a68982bc3d9f7f00f
 F www/sqlite.tcl 8b5884354cb615049aed83039f8dfe1552a44279
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P 6c32c07e8218caffebd4503e7d8a90226ac81cdc
-R fdf61026ce1ec867dd8bbc684e7b26b1
+P ca4abf3fe1f0e66802f9f98a20e0c8b82a6459aa
+R 296e96183752df57d48880aeba4ee595
 U drh
-Z efe3d88b41e036fdbd5e6a43e4d0b877
+Z 1714d41230ea0b8c518108a22a7c1e16
index 1fc9a30e560101b0d29bbd0e76f7cc4402efa0bc..359ebe3d9784ddc7f203e62ac1a4705dd947aabf 100644 (file)
@@ -1 +1 @@
-ca4abf3fe1f0e66802f9f98a20e0c8b82a6459aa
\ No newline at end of file
+51572bf71774d7631c7083be90b806e621bc9bee
\ No newline at end of file
index 5b0e732c66200af9b105caf94a511a1ccceb2f4a..9184758b66f8bb33ef7337e88f6f284db689396d 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.57 2002/03/24 13:13:29 drh Exp $
+** $Id: expr.c,v 1.58 2002/04/20 14:24:42 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -705,8 +705,6 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
     case TK_GE:       op = OP_Ge;       break;
     case TK_NE:       op = OP_Ne;       break;
     case TK_EQ:       op = OP_Eq;       break;
-    case TK_LIKE:     op = OP_Like;     break;
-    case TK_GLOB:     op = OP_Glob;     break;
     case TK_ISNULL:   op = OP_IsNull;   break;
     case TK_NOTNULL:  op = OP_NotNull;  break;
     case TK_NOT:      op = OP_Not;      break;
@@ -784,9 +782,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){
     case TK_GT:
     case TK_GE:
     case TK_NE:
-    case TK_EQ: 
-    case TK_LIKE: 
-    case TK_GLOB: {
+    case TK_EQ: {
       int dest;
       sqliteVdbeAddOp(v, OP_Integer, 1, 0);
       sqliteExprCode(pParse, pExpr->pLeft);
@@ -938,8 +934,6 @@ void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest){
     case TK_GE:       op = OP_Ge;       break;
     case TK_NE:       op = OP_Ne;       break;
     case TK_EQ:       op = OP_Eq;       break;
-    case TK_LIKE:     op = OP_Like;     break;
-    case TK_GLOB:     op = OP_Glob;     break;
     case TK_ISNULL:   op = OP_IsNull;   break;
     case TK_NOTNULL:  op = OP_NotNull;  break;
     default:  break;
@@ -966,9 +960,7 @@ void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest){
     case TK_GT:
     case TK_GE:
     case TK_NE:
-    case TK_EQ:
-    case TK_LIKE:
-    case TK_GLOB: {
+    case TK_EQ: {
       sqliteExprCode(pParse, pExpr->pLeft);
       sqliteExprCode(pParse, pExpr->pRight);
       sqliteVdbeAddOp(v, op, 0, dest);
@@ -1026,8 +1018,6 @@ void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest){
     case TK_GE:       op = OP_Lt;       break;
     case TK_NE:       op = OP_Eq;       break;
     case TK_EQ:       op = OP_Ne;       break;
-    case TK_LIKE:     op = OP_Like;     break;
-    case TK_GLOB:     op = OP_Glob;     break;
     case TK_ISNULL:   op = OP_NotNull;  break;
     case TK_NOTNULL:  op = OP_IsNull;   break;
     default:  break;
@@ -1060,13 +1050,6 @@ void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest){
       sqliteVdbeAddOp(v, op, 0, dest);
       break;
     }
-    case TK_LIKE:
-    case TK_GLOB: {
-      sqliteExprCode(pParse, pExpr->pLeft);
-      sqliteExprCode(pParse, pExpr->pRight);
-      sqliteVdbeAddOp(v, op, 1, dest);
-      break;
-    }
     case TK_ISNULL:
     case TK_NOTNULL: {
       sqliteExprCode(pParse, pExpr->pLeft);
index c75a65beea01db88f312d9b6c0c164db3a6cd3f0..ac4c05f44886b5d1d9f644b269c13bfb8337c7a1 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.15 2002/04/06 14:10:47 drh Exp $
+** $Id: func.c,v 1.16 2002/04/20 14:24:42 drh Exp $
 */
 #include <ctype.h>
 #include <math.h>
@@ -200,11 +200,39 @@ static void randomFunc(sqlite_func *context, int argc, const char **argv){
 ** Implementation of the last_insert_rowid() SQL function.  The return
 ** value is the same as the sqlite_last_insert_rowid() API function.
 */
-static void last_insert_rowid(sqlite_func *context, int arg, char **argv){
+static void last_insert_rowid(sqlite_func *context, int arg, const char **argv){
   sqlite *db = sqlite_user_data(context);
   sqlite_set_result_int(context, sqlite_last_insert_rowid(db));
 }
 
+/*
+** Implementation of the like() SQL function.  This function implements
+** the build-in LIKE operator.  The first argument to the function is the
+** string and the second argument is the pattern.  So, the SQL statements:
+**
+**       A LIKE B
+**
+** is implemented as like(A,B).
+*/
+static void likeFunc(sqlite_func *context, int arg, const char **argv){
+  sqlite_set_result_int(context, 
+     sqliteLikeCompare(argv[0] ? argv[0] : "",argv[1] ? argv[1] : ""));
+}
+
+/*
+** Implementation of the glob() SQL function.  This function implements
+** the build-in GLOB operator.  The first argument to the function is the
+** string and the second argument is the pattern.  So, the SQL statements:
+**
+**       A GLOB B
+**
+** is implemented as glob(A,B).
+*/
+static void globFunc(sqlite_func *context, int arg, const char **argv){
+  sqlite_set_result_int(context,
+    sqliteGlobCompare(argv[0] ? argv[0] : "",argv[1] ? argv[1] : ""));
+}
+
 /*
 ** An instance of the following structure holds the context of a
 ** sum() or avg() aggregate computation.
@@ -394,6 +422,8 @@ void sqliteRegisterBuildinFunctions(sqlite *db){
     { "coalesce",   0, 0          },
     { "coalesce",   1, 0          },
     { "random",    -1, randomFunc },
+    { "like",       2, likeFunc   },
+    { "glob",       2, globFunc   },
   };
   static struct {
     char *zName;
index 4838543187f2274d76a32918b639bcf03bced80a..cf89bb1155559b8fd0faecb790a7ed0f030a2585 100644 (file)
@@ -14,7 +14,7 @@
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.61 2002/04/06 13:57:43 drh Exp $
+** @(#) $Id: parse.y,v 1.62 2002/04/20 14:24:42 drh Exp $
 */
 %token_prefix TK_
 %token_type {Token}
@@ -431,18 +431,21 @@ expr(A) ::= expr(X) BITAND expr(Y). {A = sqliteExpr(TK_BITAND, X, Y, 0);}
 expr(A) ::= expr(X) BITOR expr(Y).  {A = sqliteExpr(TK_BITOR, X, Y, 0);}
 expr(A) ::= expr(X) LSHIFT expr(Y). {A = sqliteExpr(TK_LSHIFT, X, Y, 0);}
 expr(A) ::= expr(X) RSHIFT expr(Y). {A = sqliteExpr(TK_RSHIFT, X, Y, 0);}
-expr(A) ::= expr(X) LIKE expr(Y).   {A = sqliteExpr(TK_LIKE, X, Y, 0);}
-expr(A) ::= expr(X) NOT LIKE expr(Y).  {
-  A = sqliteExpr(TK_LIKE, X, Y, 0);
-  A = sqliteExpr(TK_NOT, A, 0, 0);
-  sqliteExprSpan(A,&X->span,&Y->span);
-}
-expr(A) ::= expr(X) GLOB expr(Y).  {A = sqliteExpr(TK_GLOB,X,Y,0);}
-expr(A) ::= expr(X) NOT GLOB expr(Y).  {
-  A = sqliteExpr(TK_GLOB, X, Y, 0);
+expr(A) ::= expr(X) likeop(OP) expr(Y).  [LIKE]  {
+  ExprList *pList = sqliteExprListAppend(0, Y, 0);
+  pList = sqliteExprListAppend(pList, X, 0);
+  A = sqliteExprFunction(pList, &OP);
+  sqliteExprSpan(A, &X->span, &Y->span);
+}
+expr(A) ::= expr(X) NOT likeop(OP) expr(Y). [LIKE] {
+  ExprList *pList = sqliteExprListAppend(0, Y, 0);
+  pList = sqliteExprListAppend(pList, X, 0);
+  A = sqliteExprFunction(pList, &OP);
   A = sqliteExpr(TK_NOT, A, 0, 0);
   sqliteExprSpan(A,&X->span,&Y->span);
 }
+likeop(A) ::= LIKE(X). {A = X;}
+likeop(A) ::= GLOB(X). {A = X;}
 expr(A) ::= expr(X) PLUS expr(Y).  {A = sqliteExpr(TK_PLUS, X, Y, 0);}
 expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
 expr(A) ::= expr(X) STAR expr(Y).  {A = sqliteExpr(TK_STAR, X, Y, 0);}
index 2c9a35b32ad1eae717666f5d628e6f4cdcc31638..319fbd027b659180444d21dd41832d99a09e8978 100644 (file)
@@ -30,7 +30,7 @@
 ** But other routines are also provided to help in building up
 ** a program instruction by instruction.
 **
-** $Id: vdbe.c,v 1.138 2002/04/12 10:09:00 drh Exp $
+** $Id: vdbe.c,v 1.139 2002/04/20 14:24:42 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -1058,11 +1058,11 @@ static char *zOpName[] = { 0,
   "MustBeInt",         "Add",               "AddImm",            "Subtract",
   "Multiply",          "Divide",            "Remainder",         "BitAnd",
   "BitOr",             "BitNot",            "ShiftLeft",         "ShiftRight",
-  "AbsValue",          "Like",              "Glob",              "Eq",
-  "Ne",                "Lt",                "Le",                "Gt",
-  "Ge",                "IsNull",            "NotNull",           "Negative",
-  "And",               "Or",                "Not",               "Concat",
-  "Noop",              "Function",          "Limit",           
+  "AbsValue",          "Eq",                "Ne",                "Lt",
+  "Le",                "Gt",                "Ge",                "IsNull",
+  "NotNull",           "Negative",          "And",               "Or",
+  "Not",               "Concat",            "Noop",              "Function",
+  "Limit",           
 };
 
 /*
@@ -2011,69 +2011,6 @@ case OP_Ge: {
   break;
 }
 
-/* Opcode: Like P1 P2 *
-**
-** Pop the top two elements from the stack.  The top-most is a
-** "like" pattern -- the right operand of the SQL "LIKE" operator.
-** The lower element is the string to compare against the like
-** pattern.  Jump to P2 if the two compare, and fall through without
-** jumping if they do not.  The '%' in the top-most element matches
-** any sequence of zero or more characters in the lower element.  The
-** '_' character in the topmost matches any single character of the
-** lower element.  Case is ignored for this comparison.
-**
-** If P1 is not zero, the sense of the test is inverted and we
-** have a "NOT LIKE" operator.  The jump is made if the two values
-** are different.
-*/
-case OP_Like: {
-  int tos = p->tos;
-  int nos = tos - 1;
-  int c;
-  VERIFY( if( nos<0 ) goto not_enough_stack; )
-  if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem;
-  c = sqliteLikeCompare((unsigned char*)zStack[tos], 
-                        (unsigned char*)zStack[nos]);
-  POPSTACK;
-  POPSTACK;
-  if( pOp->p1 ) c = !c;
-  if( c ) pc = pOp->p2-1;
-  break;
-}
-
-/* Opcode: Glob P1 P2 *
-**
-** Pop the top two elements from the stack.  The top-most is a
-** "glob" pattern.  The lower element is the string to compare 
-** against the glob pattern.
-**
-** Jump to P2 if the two compare, and fall through without
-** jumping if they do not.  The '*' in the top-most element matches
-** any sequence of zero or more characters in the lower element.  The
-** '?' character in the topmost matches any single character of the
-** lower element.  [...] matches a range of characters.  [^...]
-** matches any character not in the range.  Case is significant
-** for globs.
-**
-** If P1 is not zero, the sense of the test is inverted and we
-** have a "NOT GLOB" operator.  The jump is made if the two values
-** are different.
-*/
-case OP_Glob: {
-  int tos = p->tos;
-  int nos = tos - 1;
-  int c;
-  VERIFY( if( nos<0 ) goto not_enough_stack; )
-  if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem;
-  c = sqliteGlobCompare((unsigned char*)zStack[tos],
-                        (unsigned char*)zStack[nos]);
-  POPSTACK;
-  POPSTACK;
-  if( pOp->p1 ) c = !c;
-  if( c ) pc = pOp->p2-1;
-  break;
-}
-
 /* Opcode: And * * *
 **
 ** Pop two values off the stack.  Take the logical AND of the
index 201cfa051a8c91746c7678c9ba05cb0f7cf4ada3..f75b67551f2cc444ef442342cf5f3485d4f78bac 100644 (file)
@@ -15,7 +15,7 @@
 ** or VDBE.  The VDBE implements an abstract machine that runs a
 ** simple program to access and modify the underlying database.
 **
-** $Id: vdbe.h,v 1.49 2002/02/28 03:31:12 drh Exp $
+** $Id: vdbe.h,v 1.50 2002/04/20 14:24:43 drh Exp $
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
@@ -180,27 +180,25 @@ typedef struct VdbeOp VdbeOp;
 #define OP_ShiftLeft          95
 #define OP_ShiftRight         96
 #define OP_AbsValue           97
-#define OP_Like               98
-#define OP_Glob               99
-#define OP_Eq                100
-#define OP_Ne                101
-#define OP_Lt                102
-#define OP_Le                103
-#define OP_Gt                104
-#define OP_Ge                105
-#define OP_IsNull            106
-#define OP_NotNull           107
-#define OP_Negative          108
-#define OP_And               109
-#define OP_Or                110
-#define OP_Not               111
-#define OP_Concat            112
-#define OP_Noop              113
-#define OP_Function          114
-
-#define OP_Limit             115
-
-#define OP_MAX               115
+#define OP_Eq                 98
+#define OP_Ne                 99
+#define OP_Lt                100
+#define OP_Le                101
+#define OP_Gt                102
+#define OP_Ge                103
+#define OP_IsNull            104
+#define OP_NotNull           105
+#define OP_Negative          106
+#define OP_And               107
+#define OP_Or                108
+#define OP_Not               109
+#define OP_Concat            110
+#define OP_Noop              111
+#define OP_Function          112
+
+#define OP_Limit             113
+
+#define OP_MAX               113
 
 /*
 ** Prototypes for the VDBE interface.  See comments on the implementation
index 7090e2e4258f5fa3c3fb7beebae587e966e345b7..0e187dd52f9d98a02015be30ee9bf3bf416134b3 100644 (file)
@@ -32,10 +32,10 @@ proc runtest {title} {
   puts "</blockquote><table border=0 cellpadding=0 cellspacing=0>"
   set format {<tr><td>%s</td><td align="right">&nbsp;&nbsp;&nbsp;%.3f</td></tr>}
   set delay 1000
-  exec sync; after $delay;
-  set t [time "exec psql drh <$sqlfile" 1]
-  set t [expr {[lindex $t 0]/1000000.0}]
-  puts [format $format PostgreSQL: $t]
+#  exec sync; after $delay;
+#  set t [time "exec psql drh <$sqlfile" 1]
+#  set t [expr {[lindex $t 0]/1000000.0}]
+#  puts [format $format PostgreSQL: $t]
   exec sync; after $delay;
   set t [time "exec mysql -f drh <$sqlfile" 1]
   set t [expr {[lindex $t 0]/1000000.0}]
@@ -47,11 +47,11 @@ proc runtest {title} {
 #  set t [expr {[lindex $t 0]/1000000.0}]
 #  puts [format $format {SQLite 2.4 (cache=100):} $t]
   exec sync; after $delay;
-  set t [time "exec ./sqlite240 s2k.db <$sqlfile" 1]
+  set t [time "exec ./sqlite248 s2k.db <$sqlfile" 1]
   set t [expr {[lindex $t 0]/1000000.0}]
   puts [format $format {SQLite 2.4:} $t]
   exec sync; after $delay;
-  set t [time "exec ./sqlite240 sns.db <$sqlfile" 1]
+  set t [time "exec ./sqlite248 sns.db <$sqlfile" 1]
   set t [expr {[lindex $t 0]/1000000.0}]
   puts [format $format {SQLite 2.4 (nosync):} $t]
 #  set t [time "exec ./sqlite-t1 st1.db <$sqlfile" 1]
@@ -78,14 +78,14 @@ puts $fd {
   PRAGMA default_synchronous=on;
 }
 close $fd
-exec ./sqlite240 s2k.db <2kinit.sql
+exec ./sqlite248 s2k.db <2kinit.sql
 set fd [open nosync-init.sql w]
 puts $fd {
   PRAGMA default_cache_size=2000;
   PRAGMA default_synchronous=off;
 }
 close $fd
-exec ./sqlite240 sns.db <nosync-init.sql
+exec ./sqlite248 sns.db <nosync-init.sql
 set ones {zero one two three four five six seven eight nine
           ten eleven twelve thirteen fourteen fifteen sixteen seventeen
           eighteen nineteen}