From 326a67d0e8da09067c46001edb6808ba5fc3b02c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 26 Mar 2011 15:05:27 +0000 Subject: [PATCH 1/7] Skeleton code for the word-fuzzer virtual table. FossilOrigin-Name: ea3a4ee136ff6699c3099178f0efaa8bb517715f --- Makefile.in | 1 + main.mk | 1 + manifest | 34 +++- manifest.uuid | 2 +- src/tclsqlite.c | 2 + src/test_fuzzer.c | 407 ++++++++++++++++++++++++++++++++++++++++++++++ test/fuzzer1.test | 41 +++++ 7 files changed, 478 insertions(+), 10 deletions(-) create mode 100644 src/test_fuzzer.c create mode 100644 test/fuzzer1.test diff --git a/Makefile.in b/Makefile.in index 2c5490265d..2ee36dec43 100644 --- a/Makefile.in +++ b/Makefile.in @@ -356,6 +356,7 @@ TESTSRC = \ $(TOP)/src/test_demovfs.c \ $(TOP)/src/test_devsym.c \ $(TOP)/src/test_func.c \ + $(TOP)/src/test_fuzzer.c \ $(TOP)/src/test_hexio.c \ $(TOP)/src/test_init.c \ $(TOP)/src/test_intarray.c \ diff --git a/main.mk b/main.mk index 29374c546f..cfea9b590f 100644 --- a/main.mk +++ b/main.mk @@ -237,6 +237,7 @@ TESTSRC = \ $(TOP)/src/test_demovfs.c \ $(TOP)/src/test_devsym.c \ $(TOP)/src/test_func.c \ + $(TOP)/src/test_fuzzer.c \ $(TOP)/src/test_hexio.c \ $(TOP)/src/test_init.c \ $(TOP)/src/test_intarray.c \ diff --git a/manifest b/manifest index d485703eda..44205160e6 100644 --- a/manifest +++ b/manifest @@ -1,7 +1,10 @@ -C Minor\schange\sto\ssqlite3Utf8Read()\sto\smake\sconsistent\swith\sREAD_UTF8()\susage\sand\savoid\simplementation\sdefined\susages\sof\s<<.\s\s\nAdded\ssome\sadditional\sUTF-8\stest\scases. -D 2011-03-24T17:43:18.990 +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +C Skeleton\scode\sfor\sthe\sword-fuzzer\svirtual\stable. +D 2011-03-26T15:05:27.457 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f -F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f +F Makefile.in 6c96e694f446500449f683070b906de9fce17b88 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.vxworks c85ec1d8597fe2f7bc225af12ac1666e21379151 F README cd04a36fbc7ea56932a4052d7d0b7f09f27c33d6 @@ -101,7 +104,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 -F main.mk 54190fab7cdba523e311c274c95ea480f32abfb5 +F main.mk a767e12162f02719fa94697a6ff0c8b51bcd62a6 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac @@ -184,7 +187,7 @@ F src/sqliteInt.h f8f1d00a22c98fd3f2fbc94da74eeb880879f89f F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44 F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e -F src/tclsqlite.c 879bf8a23d99fc0e99d9177fe1b48896bc796d65 +F src/tclsqlite.c 44979405594d33c55ec5ef8e82533d3b4133e455 F src/test1.c 9020310c7617234b33fd1c3064f89524db25f290 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31 F src/test3.c 056093cfef69ff4227a6bdb9108564dc7f45e4bc @@ -202,6 +205,7 @@ F src/test_config.c 62f0f8f934b1d5c7e4cd4f506ae453a1117b47d7 F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 +F src/test_fuzzer.c b09d2f47bc3ae1485100b323479c5d785d4f6e4b F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2 F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 @@ -475,6 +479,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c +F test/fuzzer1.test 29120e10821e2d04887b39c6c1ae4ddcbd2bb7f6 F test/hook.test f04c3412463f8ec117c1c704c74ca0f627ce733a F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d @@ -916,7 +921,18 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 69fe0c873d702ef1d781453ee6ac2b1fb77fce48 -R 3655844fccb71eb3fdafa07a1f475145 -U shaneh -Z 4c379d73c236b4115e9dab5017415240 +P 7173b3929fae4e678223b0e978a2da7fa50a9005 +R 88772465d0029c6e2564e31a16d9e60f +T *bgcolor * #b0b28e +T *branch * word-fuzzer +T *sym-word-fuzzer * +T -sym-trunk * +U drh +Z 56aa191286824371992372fc6a5d252f +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.6 (GNU/Linux) + +iD8DBQFNjgC7oxKgR168RlERAutAAJ0V6j75yMfG5zTEYnDlvPG7yBJM5ACfSqKu +yFIOeN9GMM2kCskHQ5jGilY= +=IVMz +-----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 44925bdb50..a0f61071e0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7173b3929fae4e678223b0e978a2da7fa50a9005 \ No newline at end of file +ea3a4ee136ff6699c3099178f0efaa8bb517715f \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index 57f38d78d1..e77a1ee919 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -3581,6 +3581,7 @@ static void init_all(Tcl_Interp *interp){ extern int Sqlitequota_Init(Tcl_Interp*); extern int Sqlitemultiplex_Init(Tcl_Interp*); extern int SqliteSuperlock_Init(Tcl_Interp*); + extern int Sqlitetestfuzzer_Init(Tcl_Interp*); #ifdef SQLITE_ENABLE_ZIPVFS extern int Zipvfs_Init(Tcl_Interp*); @@ -3618,6 +3619,7 @@ static void init_all(Tcl_Interp *interp){ Sqlitequota_Init(interp); Sqlitemultiplex_Init(interp); SqliteSuperlock_Init(interp); + Sqlitetestfuzzer_Init(interp); Tcl_CreateObjCommand(interp,"load_testfixture_extensions",init_all_cmd,0,0); diff --git a/src/test_fuzzer.c b/src/test_fuzzer.c new file mode 100644 index 0000000000..406c1a264e --- /dev/null +++ b/src/test_fuzzer.c @@ -0,0 +1,407 @@ +/* +** 2011 March 24 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** Code for demonstartion virtual table that generates variations +** on an input word at increasing edit distances from the original. +*/ +#include "sqlite3.h" +#include +#include +#include + +#ifndef SQLITE_OMIT_VIRTUALTABLE + +/* +** Forward declaration of objects used by this implementation +*/ +typedef struct fuzzer_vtab fuzzer_vtab; +typedef struct fuzzer_cursor fuzzer_cursor; +typedef struct fuzzer_rule fuzzer_rule; +typedef struct fuzzer_seen fuzzer_seen; +typedef struct fuzzer_stem fuzzer_stem; + + +/* +** Each transformation rule is stored as an instance of this object. +** All rules are kept on a linked list sorted by rCost. +*/ +struct fuzzer_rule { + fuzzer_rule *pNext; /* Next rule in order of increasing rCost */ + float rCost; /* Cost of this transformation */ + char *zFrom; /* Transform from */ + char zTo[4]; /* Transform to (extra space appended) */ +}; + +/* +** When generating fuzzed words, we have to remember all previously +** generated terms in order to suppress duplicates. Each previously +** generated term is an instance of the following structure. +*/ +struct fuzzer_seen { + fuzzer_seen *pNext; /* Next with the same hash */ + char zWord[4]; /* The generated term. */ +}; + +/* +** A stem object is used to generate variants. +*/ +struct fuzzer_stem { + char *zBasis; /* Word being fuzzed */ + fuzzer_rule *pRule; /* Next rule to apply */ + int n; /* Apply rule at this character offset */ + float rBaseCost; /* Base cost of getting to zBasis */ + float rCost; /* rBaseCost + cost of applying pRule at n */ + fuzzer_stem *pNext; /* Next stem in rCost order */ +}; + +/* +** A fuzzer virtual-table object +*/ +struct fuzzer_vtab { + sqlite3_vtab base; /* Base class - must be first */ + char *zClassName; /* Name of this class. Default: "fuzzer" */ + fuzzer_rule *pRule; /* All active rules in this fuzzer */ + fuzzer_rule *pNewRule; /* New rules to add when last cursor expires */ + int nCursor; /* Number of active cursors */ +}; + +/* A fuzzer cursor object */ +struct fuzzer_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + float rMax; /* Maximum cost of any term */ + fuzzer_stem *pStem; /* Sorted list of stems for generating new terms */ + int nSeen; /* Number of terms already generated */ + int nHash; /* Number of slots in apHash */ + fuzzer_seen **apHash; /* Hash table of previously generated terms */ +}; + +/* Methods for the fuzzer module */ +static int fuzzerConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + fuzzer_vtab *pNew; + char *zSql; + int n; + if( strcmp(argv[1],"temp")!=0 ){ + *pzErr = sqlite3_mprintf("%s virtual tables must be TEMP", argv[0]); + return SQLITE_ERROR; + } + n = strlen(argv[0]) + 1; + pNew = sqlite3_malloc( sizeof(*pNew) + n ); + if( pNew==0 ) return SQLITE_NOMEM; + pNew->zClassName = (char*)&pNew[1]; + memcpy(pNew->zClassName, argv[0], n); + zSql = sqlite3_mprintf( + "CREATE TABLE x(word, distance, cFrom, cTo, cost, \"%w\" HIDDEN)", + argv[2] + ); + sqlite3_declare_vtab(db, zSql); + sqlite3_free(zSql); + memset(pNew, 0, sizeof(*pNew)); + *ppVtab = &pNew->base; + return SQLITE_OK; +} +/* Note that for this virtual table, the xCreate and xConnect +** methods are identical. */ + +static int fuzzerDisconnect(sqlite3_vtab *pVtab){ + fuzzer_vtab *p = (fuzzer_vtab*)pVtab; + assert( p->nCursor==0 ); + do{ + while( p->pRule ){ + fuzzer_rule *pRule = p->pRule; + p->pRule = pRule->pNext; + sqlite3_free(pRule); + } + p->pRule = p->pNewRule; + p->pNewRule = 0; + }while( p->pRule ); + sqlite3_free(p); + return SQLITE_OK; +} +/* The xDisconnect and xDestroy methods are also the same */ + +/* +** The two input rule lists are both sorted in order of increasing +** cost. Merge them together into a single list, sorted by cost, and +** return a pointer to the head of that list. +*/ +static fuzzer_rule *fuzzerMergeRules(fuzzer_rule *pA, fuzzer_rule *pB){ + fuzzer_rule head; + fuzzer_rule *pTail; + + pTail = &head; + while( pA && pB ){ + if( pA->rCost<=pB->rCost ){ + pTail->pNext = pA; + pTail = pA; + pA = pA->pNext; + }else{ + pTail->pNext = pB; + pTail = pB; + pB = pB->pNext; + } + } + if( pA==0 ){ + pTail->pNext = pB; + }else{ + pTail->pNext = pA; + } + return head.pNext; +} + + +/* +** Open a new fuzzer cursor. +*/ +static int fuzzerOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ + fuzzer_vtab *p = (fuzzer_vtab*)pVTab; + fuzzer_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + *ppCursor = &pCur->base; + if( p->nCursor==0 && p->pNewRule ){ + unsigned int i; + fuzzer_rule *pX; + fuzzer_rule *a[15]; + for(i=0; ipNewRule)!=0 ){ + p->pNewRule = pX->pNext; + pX->pNext = 0; + for(i=0; a[i] && ipRule = fuzzerMergeRules(p->pRule, pX); + } + + return SQLITE_OK; +} + +/* +** Close a fuzzer cursor. +*/ +static int fuzzerClose(sqlite3_vtab_cursor *cur){ + fuzzer_cursor *pCur = (fuzzer_cursor *)cur; + int i; + for(i=0; inHash; i++){ + fuzzer_seen *pSeen = pCur->apHash[i]; + while( pSeen ){ + fuzzer_seen *pNext = pSeen->pNext; + sqlite3_free(pSeen); + pSeen = pNext; + } + } + sqlite3_free(pCur->apHash); + while( pCur->pStem ){ + fuzzer_stem *pStem = pCur->pStem; + pCur->pStem = pStem->pNext; + sqlite3_free(pStem); + } + sqlite3_free(pCur); + return SQLITE_OK; +} + +static int fuzzerNext(sqlite3_vtab_cursor *cur){ + return 0; +} + +static int fuzzerFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + fuzzer_cursor *pCur = (fuzzer_cursor *)pVtabCursor; + return fuzzerNext(pVtabCursor); +} + +static int fuzzerColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ + fuzzer_cursor *pCur = (fuzzer_cursor*)cur; + return SQLITE_OK; +} + +static int fuzzerRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + *pRowid = 0; + return SQLITE_OK; +} + +static int fuzzerEof(sqlite3_vtab_cursor *cur){ + fuzzer_cursor *pCur = (fuzzer_cursor*)cur; + return 1; +} + +static int fuzzerBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ + + return SQLITE_OK; +} + +/* +** Disallow all attempts to DELETE or UPDATE. Only INSERTs are allowed. +** +** On an insert, the cFrom, cTo, and cost columns are used to construct +** a new rule. All other columns are ignored. The rule is ignored +** if cFrom and cTo are identical. A NULL value for cFrom or cTo is +** interpreted as an empty string. The cost must be positive. +*/ +static int fuzzerUpdate( + sqlite3_vtab *pVTab, + int argc, + sqlite3_value **argv, + sqlite_int64 *pRowid +){ + fuzzer_vtab *p = (fuzzer_vtab*)pVTab; + fuzzer_rule *pRule; + const char *zFrom; + int nFrom; + const char *zTo; + int nTo; + float rCost; + if( argc!=8 ){ + sqlite3_free(pVTab->zErrMsg); + pVTab->zErrMsg = sqlite3_mprintf("cannot delete from a %s virtual table", + p->zClassName); + return SQLITE_CONSTRAINT; + } + if( sqlite3_value_type(argv[0])!=SQLITE_NULL ){ + sqlite3_free(pVTab->zErrMsg); + pVTab->zErrMsg = sqlite3_mprintf("cannot update a %s virtual table", + p->zClassName); + return SQLITE_CONSTRAINT; + } + zFrom = (char*)sqlite3_value_text(argv[4]); + if( zFrom==0 ) zFrom = ""; + zTo = (char*)sqlite3_value_text(argv[5]); + if( zTo==0 ) zTo = ""; + if( strcmp(zFrom,zTo)==0 ){ + /* Silently ignore null transformations */ + return SQLITE_OK; + } + rCost = (float)sqlite3_value_double(argv[6]); + if( rCost<=0 ){ + sqlite3_free(pVTab->zErrMsg); + pVTab->zErrMsg = sqlite3_mprintf("cost must be positive"); + return SQLITE_CONSTRAINT; + } + nFrom = strlen(zFrom)+1; + nTo = strlen(zTo)+1; + if( nTo<4 ) nTo = 4; + pRule = sqlite3_malloc( sizeof(*pRule) + nFrom + nTo - 4 ); + if( pRule==0 ){ + return SQLITE_NOMEM; + } + pRule->zFrom = &pRule->zTo[nTo]; + memcpy(pRule->zFrom, zFrom, nFrom); + memcpy(pRule->zTo, zTo, nTo); + pRule->rCost = rCost; + pRule->pNext = p->pNewRule; + p->pNewRule = pRule; + return SQLITE_OK; +} + +/* +** A virtual table module that provides read-only access to a +** Tcl global variable namespace. +*/ +static sqlite3_module fuzzerModule = { + 0, /* iVersion */ + fuzzerConnect, + fuzzerConnect, + fuzzerBestIndex, + fuzzerDisconnect, + fuzzerDisconnect, + fuzzerOpen, /* xOpen - open a cursor */ + fuzzerClose, /* xClose - close a cursor */ + fuzzerFilter, /* xFilter - configure scan constraints */ + fuzzerNext, /* xNext - advance a cursor */ + fuzzerEof, /* xEof - check for end of scan */ + fuzzerColumn, /* xColumn - read data */ + fuzzerRowid, /* xRowid - read data */ + fuzzerUpdate, /* xUpdate - INSERT */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ +}; + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + +/* +** Register the fuzzer virtual table +*/ +int fuzzer_register(sqlite3 *db){ + int rc = SQLITE_OK; +#ifndef SQLITE_OMIT_VIRTUALTABLE + rc = sqlite3_create_module(db, "fuzzer", &fuzzerModule, 0); +#endif + return rc; +} + +#ifdef SQLITE_TEST +#include +/* +** Decode a pointer to an sqlite3 object. +*/ +extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); + +/* +** Register the echo virtual table module. +*/ +static int register_fuzzer_module( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + sqlite3 *db; + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + fuzzer_register(db); + return TCL_OK; +} + + +/* +** Register commands with the TCL interpreter. +*/ +int Sqlitetestfuzzer_Init(Tcl_Interp *interp){ + static struct { + char *zName; + Tcl_ObjCmdProc *xProc; + void *clientData; + } aObjCmd[] = { + { "register_fuzzer_module", register_fuzzer_module, 0 }, + }; + int i; + for(i=0; i Date: Sat, 26 Mar 2011 19:04:47 +0000 Subject: [PATCH 2/7] Added most of the logic. Simple test runs without segfaulting but does not give the correct answer. FossilOrigin-Name: fb4c31eac8a7290f61c50a3552245660e1271871 --- manifest | 24 ++- manifest.uuid | 2 +- src/test_fuzzer.c | 380 +++++++++++++++++++++++++++++++++++++++------- test/fuzzer1.test | 12 +- 4 files changed, 344 insertions(+), 74 deletions(-) diff --git a/manifest b/manifest index 44205160e6..a9cd7caec3 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Skeleton\scode\sfor\sthe\sword-fuzzer\svirtual\stable. -D 2011-03-26T15:05:27.457 +C Added\smost\sof\sthe\slogic.\s\sSimple\stest\sruns\swithout\ssegfaulting\sbut\sdoes\snot\ngive\sthe\scorrect\sanswer. +D 2011-03-26T19:04:47.346 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6c96e694f446500449f683070b906de9fce17b88 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -205,7 +205,7 @@ F src/test_config.c 62f0f8f934b1d5c7e4cd4f506ae453a1117b47d7 F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 -F src/test_fuzzer.c b09d2f47bc3ae1485100b323479c5d785d4f6e4b +F src/test_fuzzer.c 133c830fdd4342b687910a04cf8e617e0f5f0e5f F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2 F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 @@ -479,7 +479,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/fuzzer1.test 29120e10821e2d04887b39c6c1ae4ddcbd2bb7f6 +F test/fuzzer1.test e0fe96bb8d318250b35407954c7059eea8ea77b2 F test/hook.test f04c3412463f8ec117c1c704c74ca0f627ce733a F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d @@ -921,18 +921,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 7173b3929fae4e678223b0e978a2da7fa50a9005 -R 88772465d0029c6e2564e31a16d9e60f -T *bgcolor * #b0b28e -T *branch * word-fuzzer -T *sym-word-fuzzer * -T -sym-trunk * +P ea3a4ee136ff6699c3099178f0efaa8bb517715f +R 6a09f2dbc53bf6a269c56104914ae3e5 U drh -Z 56aa191286824371992372fc6a5d252f +Z c40c33ca74d9ed106c795140b6ad71ee -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNjgC7oxKgR168RlERAutAAJ0V6j75yMfG5zTEYnDlvPG7yBJM5ACfSqKu -yFIOeN9GMM2kCskHQ5jGilY= -=IVMz +iD8DBQFNjjjSoxKgR168RlERAjfMAKCJigUMIbnNV83nhVCWCpDK5WxPFQCeLIbS ++J80DLXre8S3k4SR8glB8Jc= +=nBDg -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index a0f61071e0..54187bc30b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea3a4ee136ff6699c3099178f0efaa8bb517715f \ No newline at end of file +fb4c31eac8a7290f61c50a3552245660e1271871 \ No newline at end of file diff --git a/src/test_fuzzer.c b/src/test_fuzzer.c index 406c1a264e..e4aca40fc8 100644 --- a/src/test_fuzzer.c +++ b/src/test_fuzzer.c @@ -29,38 +29,36 @@ typedef struct fuzzer_rule fuzzer_rule; typedef struct fuzzer_seen fuzzer_seen; typedef struct fuzzer_stem fuzzer_stem; +/* +** Type of the "cost" of an edit operation. Might be changed to +** "float" or "double" or "sqlite3_int64" in the future. +*/ +typedef int fuzzer_cost; + /* ** Each transformation rule is stored as an instance of this object. ** All rules are kept on a linked list sorted by rCost. */ struct fuzzer_rule { - fuzzer_rule *pNext; /* Next rule in order of increasing rCost */ - float rCost; /* Cost of this transformation */ - char *zFrom; /* Transform from */ - char zTo[4]; /* Transform to (extra space appended) */ -}; - -/* -** When generating fuzzed words, we have to remember all previously -** generated terms in order to suppress duplicates. Each previously -** generated term is an instance of the following structure. -*/ -struct fuzzer_seen { - fuzzer_seen *pNext; /* Next with the same hash */ - char zWord[4]; /* The generated term. */ + fuzzer_rule *pNext; /* Next rule in order of increasing rCost */ + fuzzer_cost rCost; /* Cost of this transformation */ + int nFrom, nTo; /* Length of the zFrom and zTo strings */ + char *zFrom; /* Transform from */ + char zTo[4]; /* Transform to (extra space appended) */ }; /* ** A stem object is used to generate variants. */ struct fuzzer_stem { - char *zBasis; /* Word being fuzzed */ - fuzzer_rule *pRule; /* Next rule to apply */ - int n; /* Apply rule at this character offset */ - float rBaseCost; /* Base cost of getting to zBasis */ - float rCost; /* rBaseCost + cost of applying pRule at n */ - fuzzer_stem *pNext; /* Next stem in rCost order */ + char *zBasis; /* Word being fuzzed */ + int nBasis; /* Length of the zBasis string */ + const fuzzer_rule *pRule; /* Current rule to apply */ + int n; /* Apply pRule at this character offset */ + fuzzer_cost rBaseCost; /* Base cost of getting to zBasis */ + fuzzer_stem *pNext; /* Next stem in rCost order */ + fuzzer_stem *pHash; /* Next stem with same hash on zBasis */ }; /* @@ -74,14 +72,18 @@ struct fuzzer_vtab { int nCursor; /* Number of active cursors */ }; +#define FUZZER_HASH 4001 /* Hash table size */ + /* A fuzzer cursor object */ struct fuzzer_cursor { sqlite3_vtab_cursor base; /* Base class - must be first */ - float rMax; /* Maximum cost of any term */ + fuzzer_vtab *pVtab; /* The virtual table this cursor belongs to */ + fuzzer_cost rLimit; /* Maximum cost of any term */ fuzzer_stem *pStem; /* Sorted list of stems for generating new terms */ - int nSeen; /* Number of terms already generated */ - int nHash; /* Number of slots in apHash */ - fuzzer_seen **apHash; /* Hash table of previously generated terms */ + fuzzer_stem *pDone; /* Stems already processed to completion */ + char *zBuf; /* Temporary use buffer */ + int nBuf; /* Bytes allocated for zBuf */ + fuzzer_stem *apHash[FUZZER_HASH]; /* Hash of previously generated terms */ }; /* Methods for the fuzzer module */ @@ -93,7 +95,6 @@ static int fuzzerConnect( char **pzErr ){ fuzzer_vtab *pNew; - char *zSql; int n; if( strcmp(argv[1],"temp")!=0 ){ *pzErr = sqlite3_mprintf("%s virtual tables must be TEMP", argv[0]); @@ -104,12 +105,7 @@ static int fuzzerConnect( if( pNew==0 ) return SQLITE_NOMEM; pNew->zClassName = (char*)&pNew[1]; memcpy(pNew->zClassName, argv[0], n); - zSql = sqlite3_mprintf( - "CREATE TABLE x(word, distance, cFrom, cTo, cost, \"%w\" HIDDEN)", - argv[2] - ); - sqlite3_declare_vtab(db, zSql); - sqlite3_free(zSql); + sqlite3_declare_vtab(db, "CREATE TABLE x(word,distance,cFrom,cTo,cost)"); memset(pNew, 0, sizeof(*pNew)); *ppVtab = &pNew->base; return SQLITE_OK; @@ -173,7 +169,9 @@ static int fuzzerOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ pCur = sqlite3_malloc( sizeof(*pCur) ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, sizeof(*pCur)); + pCur->pVtab = p; *ppCursor = &pCur->base; + p->nCursor++; if( p->nCursor==0 && p->pNewRule ){ unsigned int i; fuzzer_rule *pX; @@ -193,64 +191,332 @@ static int fuzzerOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ } p->pRule = fuzzerMergeRules(p->pRule, pX); } - return SQLITE_OK; } +/* +** Free up all the memory allocated by a cursor. Set it rLimit to 0 +** to indicate that it is at EOF. +*/ +static void fuzzerClearCursor(fuzzer_cursor *pCur, int clearHash){ + if( pCur->pStem==0 && pCur->pDone==0 ) clearHash = 0; + do{ + while( pCur->pStem ){ + fuzzer_stem *pStem = pCur->pStem; + pCur->pStem = pStem->pNext; + sqlite3_free(pStem); + } + pCur->pStem = pCur->pDone; + pCur->pDone = 0; + }while( pCur->pStem ); + pCur->rLimit = (fuzzer_cost)0; + if( clearHash ) memset(pCur->apHash, 0, sizeof(pCur->apHash)); +} + /* ** Close a fuzzer cursor. */ static int fuzzerClose(sqlite3_vtab_cursor *cur){ fuzzer_cursor *pCur = (fuzzer_cursor *)cur; - int i; - for(i=0; inHash; i++){ - fuzzer_seen *pSeen = pCur->apHash[i]; - while( pSeen ){ - fuzzer_seen *pNext = pSeen->pNext; - sqlite3_free(pSeen); - pSeen = pNext; - } - } - sqlite3_free(pCur->apHash); - while( pCur->pStem ){ - fuzzer_stem *pStem = pCur->pStem; - pCur->pStem = pStem->pNext; - sqlite3_free(pStem); - } - sqlite3_free(pCur); + fuzzerClearCursor(pCur, 0); + sqlite3_free(pCur->zBuf); + pCur->pVtab->nCursor--; return SQLITE_OK; } -static int fuzzerNext(sqlite3_vtab_cursor *cur){ +/* +** Compute the current output term for a fuzzer_stem. +*/ +static int fuzzerComputeWord( + fuzzer_cursor *pCur, + fuzzer_stem *pStem +){ + const fuzzer_rule *pRule = pStem->pRule; + int n; + + n = pStem->nBasis; + if( pStem->n>=0 ) n += pRule->nTo - pRule->nFrom; + if( pCur->nBufzBuf = sqlite3_realloc(pCur->zBuf, n+100); + if( pCur->zBuf==0 ) return SQLITE_NOMEM; + pCur->nBuf = n+100; + } + n = pStem->n; + if( n<0 ){ + memcpy(pCur->zBuf, pStem->zBasis, pStem->nBasis+1); + }else{ + memcpy(pCur->zBuf, pStem->zBasis, n); + memcpy(&pCur->zBuf[n], pRule->zTo, pRule->nTo); + memcpy(&pCur->zBuf[n+pRule->nTo], &pStem->zBasis[n+pRule->nFrom], + pStem->nBasis-n-pRule->nFrom+1); + } + return SQLITE_OK; +} + + +/* +** Compute a hash on zBasis. +*/ +static unsigned int fuzzerHash(const char *z){ + unsigned int h = 0; + while( *z ){ h = (h<<3) ^ (h>>29) ^ *(z++); } + return h%10007; +} + +/* +** Current cost of a stem +*/ +static fuzzer_cost fuzzerCost(fuzzer_stem *pStem){ + return pStem->rBaseCost + pStem->pRule->rCost; +} + +/* +** Advance a fuzzer_stem to its next value. Return 0 if there are +** no more values that can be generated by this fuzzer_stem. +*/ +static int fuzzerAdvance(fuzzer_cursor *pCur, fuzzer_stem *pStem){ + const fuzzer_rule *pRule; + while( (pRule = pStem->pRule)!=0 ){ + while( pStem->n < pStem->nBasis - pRule->nFrom ){ + pStem->n++; + if( pRule->nFrom==0 + || memcmp(&pStem->zBasis[pStem->n], pRule->zFrom, pRule->nFrom)==0 + ){ + /* Found a rewrite case. Make sure it is not a duplicate */ + unsigned int h; + fuzzer_stem *pLookup; + + fuzzerComputeWord(pCur, pStem); + h = fuzzerHash(pCur->zBuf); + pLookup = pCur->apHash[h]; + while( pLookup && strcmp(pLookup->zBasis, pCur->zBuf)!=0 ){ + pLookup = pLookup->pHash; + } + if( pLookup==0 ) return 1; /* A new output is found. */ + } + } + pStem->n = -1; + pStem->pRule = pRule->pNext; + if( fuzzerCost(pStem)>pCur->rLimit ) pStem->pRule = 0; + } return 0; } +/* +** Insert pNew into the list at pList. Return a pointer to the new +** list. The insert is done such the pNew is in the correct order +** according to fuzzer_stem.zBaseCost+fuzzer_stem.pRule->rCost. +*/ +static fuzzer_stem *fuzzerInsert(fuzzer_stem *pList, fuzzer_stem *pNew){ + fuzzer_cost c1; + + c1 = fuzzerCost(pNew); + if( c1 <= fuzzerCost(pList) ){ + pNew->pNext = pList; + return pNew; + }else{ + fuzzer_stem *pPrev; + pPrev = pList; + while( pPrev->pNext && fuzzerCost(pPrev->pNext)pNext; + } + pNew->pNext = pPrev->pNext; + pPrev->pNext = pNew; + return pList; + } +} + +/* +** Allocate a new fuzzer_stem. Add it to the hash table but do not +** link it into either the pCur->pStem or pCur->pDone lists. +*/ +static fuzzer_stem *fuzzerNewStem( + fuzzer_cursor *pCur, + const char *zWord, + fuzzer_cost rBaseCost +){ + fuzzer_stem *pNew; + unsigned int h; + + pNew = sqlite3_malloc( sizeof(*pNew) + strlen(zWord) + 1 ); + if( pNew==0 ) return 0; + memset(pNew, 0, sizeof(*pNew)); + pNew->zBasis = (char*)&pNew[1]; + pNew->nBasis = strlen(zWord); + memcpy(pNew->zBasis, zWord, pNew->nBasis+1); + pNew->pRule = pCur->pVtab->pRule; + pNew->n = -1; + pNew->rBaseCost = rBaseCost; + h = fuzzerHash(pNew->zBasis); + pNew->pHash = pCur->apHash[h]; + pCur->apHash[h] = pNew; + return pNew; +} + + +/* +** Advance a cursor to its next row of output +*/ +static int fuzzerNext(sqlite3_vtab_cursor *cur){ + fuzzer_cursor *pCur = (fuzzer_cursor*)pCur; + fuzzer_stem *pStem, *pNew; + + /* Use the element the cursor is currently point to to create + ** a new stem and insert the new stem into the priority queue. + */ + fuzzerComputeWord(pCur, pCur->pStem); + pNew = fuzzerNewStem(pCur, pCur->zBuf, fuzzerCost(pCur->pStem)); + if( pNew ){ + if( fuzzerAdvance(pCur, pNew)==0 ){ + pNew->pNext = pCur->pDone; + pCur->pDone = pNew; + }else{ + pCur->pStem = fuzzerInsert(pCur->pStem, pNew); + } + } + + /* Adjust the priority queue so that the first element of the + ** stem list is the next lowest cost word. + */ + while( (pStem = pCur->pStem)!=0 ){ + if( fuzzerAdvance(pCur, pStem) ){ + pCur->pStem = fuzzerInsert(pStem->pNext, pStem); + return SQLITE_OK; /* New word found */ + } + pCur->pStem = pStem->pNext; + pStem->pNext = pCur->pDone; + pCur->pDone = pStem; + } + + /* Reach this point only if queue has been exhausted and there is + ** nothing left to be output. */ + pCur->rLimit = (fuzzer_cost)0; + return SQLITE_OK; +} + +/* +** Called to "rewind" a cursor back to the beginning so that +** it starts its output over again. Always called at least once +** prior to any fuzzerColumn, fuzzerRowid, or fuzzerEof call. +*/ static int fuzzerFilter( sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ fuzzer_cursor *pCur = (fuzzer_cursor *)pVtabCursor; - return fuzzerNext(pVtabCursor); + const char *zWord = 0; + pCur->rLimit = 2147483647; + + fuzzerClearCursor(pCur, 1); + if( idxNum==1 ){ + zWord = (const char*)sqlite3_value_text(argv[0]); + }else if( idxNum==2 ){ + pCur->rLimit = (fuzzer_cost)sqlite3_value_int(argv[0]); + }else if( idxNum==3 ){ + zWord = (const char*)sqlite3_value_text(argv[0]); + pCur->rLimit = (fuzzer_cost)sqlite3_value_int(argv[1]); + } + if( zWord==0 ) zWord = ""; + pCur->pStem = fuzzerNewStem(pCur, zWord, (fuzzer_cost)0); + if( pCur->pStem==0 ) return SQLITE_NOMEM; + return SQLITE_OK; } +/* +** Only the word and distance columns have values. All other columns +** return NULL +*/ static int fuzzerColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ fuzzer_cursor *pCur = (fuzzer_cursor*)cur; + if( i==0 ){ + /* the "word" column */ + if( fuzzerComputeWord(pCur, pCur->pStem)==SQLITE_NOMEM ){ + return SQLITE_NOMEM; + } + sqlite3_result_text(ctx, pCur->zBuf, -1, SQLITE_TRANSIENT); + }else if( i==1 ){ + /* the "distance" column */ + sqlite3_result_int(ctx, fuzzerCost(pCur->pStem)); + }else{ + /* All other columns are NULL */ + sqlite3_result_null(ctx); + } return SQLITE_OK; } +/* +** The rowid is always 0 +*/ static int fuzzerRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ - *pRowid = 0; + *pRowid = 0; /* The rowid is always 0 */ return SQLITE_OK; } +/* +** When the fuzzer_cursor.rLimit value is 0 or less, that is a signal +** that the cursor has nothing more to output. +*/ static int fuzzerEof(sqlite3_vtab_cursor *cur){ fuzzer_cursor *pCur = (fuzzer_cursor*)cur; - return 1; + return pCur->rLimit<=(fuzzer_cost)0; } +/* +** Search for terms of these forms: +** +** word MATCH $str +** distance < $value +** distance <= $value +** +** The distance< and distance<= are both treated as distance<=. +** The query plan number is as follows: +** +** 0: None of the terms above are found +** 1: There is a "word MATCH" term with $str in filter.argv[0]. +** 2: There is a "distance<" term with $value in filter.argv[0]. +** 3: Both "word MATCH" and "distance<" with $str in argv[0] and +** $value in argv[1]. +*/ static int fuzzerBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ - + int iPlan = 0; + int iDistTerm = -1; + int i; + const struct sqlite3_index_constraint *pConstraint; + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + if( pConstraint->usable==0 ) continue; + if( (iPlan & 1)==0 + && pConstraint->iColumn==0 + && pConstraint->op==SQLITE_INDEX_CONSTRAINT_MATCH + ){ + iPlan |= 1; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + pIdxInfo->aConstraintUsage[i].omit = 1; + } + if( (iPlan & 2)==0 + && pConstraint->iColumn==1 + && (pConstraint->op==SQLITE_INDEX_CONSTRAINT_LT + || pConstraint->op==SQLITE_INDEX_CONSTRAINT_LE) + ){ + iPlan |= 2; + iDistTerm = i; + } + } + if( iPlan==2 ){ + pIdxInfo->aConstraintUsage[iDistTerm].argvIndex = 1; + }else if( iPlan==3 ){ + pIdxInfo->aConstraintUsage[iDistTerm].argvIndex = 2; + } + pIdxInfo->idxNum = iPlan; + if( pIdxInfo->nOrderBy==1 + && pIdxInfo->aOrderBy[0].iColumn==1 + && pIdxInfo->aOrderBy[0].desc==0 + ){ + pIdxInfo->orderByConsumed = 1; + } + pIdxInfo->estimatedCost = (double)10000; + return SQLITE_OK; } @@ -274,8 +540,8 @@ static int fuzzerUpdate( int nFrom; const char *zTo; int nTo; - float rCost; - if( argc!=8 ){ + fuzzer_cost rCost; + if( argc!=7 ){ sqlite3_free(pVTab->zErrMsg); pVTab->zErrMsg = sqlite3_mprintf("cannot delete from a %s virtual table", p->zClassName); @@ -295,7 +561,7 @@ static int fuzzerUpdate( /* Silently ignore null transformations */ return SQLITE_OK; } - rCost = (float)sqlite3_value_double(argv[6]); + rCost = sqlite3_value_int(argv[6]); if( rCost<=0 ){ sqlite3_free(pVTab->zErrMsg); pVTab->zErrMsg = sqlite3_mprintf("cost must be positive"); @@ -309,8 +575,10 @@ static int fuzzerUpdate( return SQLITE_NOMEM; } pRule->zFrom = &pRule->zTo[nTo]; + pRule->nFrom = nFrom; memcpy(pRule->zFrom, zFrom, nFrom); memcpy(pRule->zTo, zTo, nTo); + pRule->nTo = nTo; pRule->rCost = rCost; pRule->pNext = p->pNewRule; p->pNewRule = pRule; diff --git a/test/fuzzer1.test b/test/fuzzer1.test index 418bba5506..1e33556aa3 100644 --- a/test/fuzzer1.test +++ b/test/fuzzer1.test @@ -31,9 +31,15 @@ do_test fuzzer1-1.1 { } {} do_test fuzzer1-1.2 { db eval { - INSERT INTO f1(cfrom, cto, cost) VALUES('e','a',0.1); - INSERT INTO f1(cfrom, cto, cost) VALUES('a','e',0.1); - INSERT INTO f1(cfrom, cto, cost) VALUES('e','o',0.1); + INSERT INTO f1(cfrom, cto, cost) VALUES('e','a',1); + INSERT INTO f1(cfrom, cto, cost) VALUES('a','e',1); + INSERT INTO f1(cfrom, cto, cost) VALUES('e','o',2); + } +} {} + +do_test fuzzer1-1.3 { + db eval { + SELECT word, distance FROM f1 WHERE word MATCH 'abcde' } } {} From 72384dc28f14b186d3211fc0181cda9ea3b7516f Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 29 Mar 2011 14:08:09 +0000 Subject: [PATCH 3/7] Further improvements to the fuzzer. It still is not quite working. Pausing to work on other things.... FossilOrigin-Name: 5f2f2fce40f43debeb0492c9b460b85c7dad2bde --- install-sh | 0 manifest | 30 +++------ manifest.uuid | 2 +- src/test_fuzzer.c | 153 ++++++++++++++++++++++++++++++--------------- test/fuzzer1.test | 4 +- test/progress.test | 0 tool/mkopts.tcl | 0 7 files changed, 114 insertions(+), 75 deletions(-) mode change 100644 => 100755 install-sh mode change 100755 => 100644 test/progress.test mode change 100755 => 100644 tool/mkopts.tcl diff --git a/install-sh b/install-sh old mode 100644 new mode 100755 diff --git a/manifest b/manifest index a9cd7caec3..8148ffca72 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,5 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -C Added\smost\sof\sthe\slogic.\s\sSimple\stest\sruns\swithout\ssegfaulting\sbut\sdoes\snot\ngive\sthe\scorrect\sanswer. -D 2011-03-26T19:04:47.346 +C Further\simprovements\sto\sthe\sfuzzer.\s\sIt\sstill\sis\snot\squite\sworking.\s\sPausing\nto\swork\son\sother\sthings.... +D 2011-03-29T14:08:09.188 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6c96e694f446500449f683070b906de9fce17b88 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -102,7 +99,7 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024 -F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 +F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F main.mk a767e12162f02719fa94697a6ff0c8b51bcd62a6 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a @@ -205,7 +202,7 @@ F src/test_config.c 62f0f8f934b1d5c7e4cd4f506ae453a1117b47d7 F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 -F src/test_fuzzer.c 133c830fdd4342b687910a04cf8e617e0f5f0e5f +F src/test_fuzzer.c 3e402dd5e6c4f096fdc92c52e775e8fad85bce9b F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2 F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 @@ -479,7 +476,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/fuzzer1.test e0fe96bb8d318250b35407954c7059eea8ea77b2 +F test/fuzzer1.test a5d60f618443b86b5f5a695a41d01b7d8697345d F test/hook.test f04c3412463f8ec117c1c704c74ca0f627ce733a F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d @@ -608,7 +605,7 @@ F test/permutations.test 5b2a4cb756ffb2407cb4743163668d1d769febb6 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea -F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 x +F test/progress.test 5b075c3c790c7b2a61419bc199db87aaf48b8301 F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quota.test ddafe133653093eb9a99ccd6264884ae43f9c9b8 @@ -896,7 +893,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -921,14 +918,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P ea3a4ee136ff6699c3099178f0efaa8bb517715f -R 6a09f2dbc53bf6a269c56104914ae3e5 +P fb4c31eac8a7290f61c50a3552245660e1271871 +R 86b6649d084e41c015babc3a0e3fb294 U drh -Z c40c33ca74d9ed106c795140b6ad71ee ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.4.6 (GNU/Linux) - -iD8DBQFNjjjSoxKgR168RlERAjfMAKCJigUMIbnNV83nhVCWCpDK5WxPFQCeLIbS -+J80DLXre8S3k4SR8glB8Jc= -=nBDg ------END PGP SIGNATURE----- +Z 67d6460bdc70fd366585e4c8607ab8f4 diff --git a/manifest.uuid b/manifest.uuid index 54187bc30b..09a1e57cc7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb4c31eac8a7290f61c50a3552245660e1271871 \ No newline at end of file +5f2f2fce40f43debeb0492c9b460b85c7dad2bde \ No newline at end of file diff --git a/src/test_fuzzer.c b/src/test_fuzzer.c index e4aca40fc8..82f35a2f51 100644 --- a/src/test_fuzzer.c +++ b/src/test_fuzzer.c @@ -17,6 +17,7 @@ #include #include #include +#include #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -49,7 +50,15 @@ struct fuzzer_rule { }; /* -** A stem object is used to generate variants. +** A stem object is used to generate variants. It is also used to record +** previously generated outputs. +** +** Every stem is added to a hash table as it is output. Generation of +** duplicate stems is suppressed. +** +** Active stems (those that might generate new outputs) are kepts on a linked +** list sorted by increasing cost. The cost is the sum of rBaseCost and +** pRule->rCost. */ struct fuzzer_stem { char *zBasis; /* Word being fuzzed */ @@ -83,6 +92,7 @@ struct fuzzer_cursor { fuzzer_stem *pDone; /* Stems already processed to completion */ char *zBuf; /* Temporary use buffer */ int nBuf; /* Bytes allocated for zBuf */ + fuzzer_rule nullRule; /* Null rule used first */ fuzzer_stem *apHash[FUZZER_HASH]; /* Hash of previously generated terms */ }; @@ -171,7 +181,6 @@ static int fuzzerOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ memset(pCur, 0, sizeof(*pCur)); pCur->pVtab = p; *ppCursor = &pCur->base; - p->nCursor++; if( p->nCursor==0 && p->pNewRule ){ unsigned int i; fuzzer_rule *pX; @@ -191,6 +200,7 @@ static int fuzzerOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ } p->pRule = fuzzerMergeRules(p->pRule, pX); } + p->nCursor++; return SQLITE_OK; } @@ -221,35 +231,34 @@ static int fuzzerClose(sqlite3_vtab_cursor *cur){ fuzzerClearCursor(pCur, 0); sqlite3_free(pCur->zBuf); pCur->pVtab->nCursor--; + sqlite3_free(pCur); return SQLITE_OK; } /* ** Compute the current output term for a fuzzer_stem. */ -static int fuzzerComputeWord( - fuzzer_cursor *pCur, - fuzzer_stem *pStem +static int fuzzerRender( + fuzzer_stem *pStem, /* The stem to be rendered */ + char **pzBuf, /* Write results into this buffer. realloc if needed */ + int *pnBuf /* Size of the buffer */ ){ const fuzzer_rule *pRule = pStem->pRule; int n; + char *z; - n = pStem->nBasis; - if( pStem->n>=0 ) n += pRule->nTo - pRule->nFrom; - if( pCur->nBufzBuf = sqlite3_realloc(pCur->zBuf, n+100); - if( pCur->zBuf==0 ) return SQLITE_NOMEM; - pCur->nBuf = n+100; + n = pStem->nBasis + pRule->nTo - pRule->nFrom; + if( (*pnBuf)n; - if( n<0 ){ - memcpy(pCur->zBuf, pStem->zBasis, pStem->nBasis+1); - }else{ - memcpy(pCur->zBuf, pStem->zBasis, n); - memcpy(&pCur->zBuf[n], pRule->zTo, pRule->nTo); - memcpy(&pCur->zBuf[n+pRule->nTo], &pStem->zBasis[n+pRule->nFrom], - pStem->nBasis-n-pRule->nFrom+1); - } + z = *pzBuf; + memcpy(z, pStem->zBasis, n); + memcpy(&z[n], pRule->zTo, pRule->nTo); + memcpy(&z[n+pRule->nTo], &pStem->zBasis[n+pRule->nFrom], + pStem->nBasis-n-pRule->nFrom+1); return SQLITE_OK; } @@ -260,7 +269,7 @@ static int fuzzerComputeWord( static unsigned int fuzzerHash(const char *z){ unsigned int h = 0; while( *z ){ h = (h<<3) ^ (h>>29) ^ *(z++); } - return h%10007; + return h % FUZZER_HASH; } /* @@ -270,9 +279,30 @@ static fuzzer_cost fuzzerCost(fuzzer_stem *pStem){ return pStem->rBaseCost + pStem->pRule->rCost; } +/* +** Return 1 if the string to which the cursor is point has already +** been emitted. Return 0 if not. Return -1 on a memory allocation +** failures. +*/ +static int fuzzerSeen(fuzzer_cursor *pCur, fuzzer_stem *pStem){ + unsigned int h; + fuzzer_stem *pLookup; + + if( fuzzerRender(pStem, &pCur->zBuf, &pCur->nBuf)==SQLITE_NOMEM ){ + return -1; + } + h = fuzzerHash(pCur->zBuf); + pLookup = pCur->apHash[h]; + while( pLookup && strcmp(pLookup->zBasis, pCur->zBuf)!=0 ){ + pLookup = pLookup->pHash; + } + return pLookup!=0; +} + /* ** Advance a fuzzer_stem to its next value. Return 0 if there are -** no more values that can be generated by this fuzzer_stem. +** no more values that can be generated by this fuzzer_stem. Return +** -1 on a memory allocation failure. */ static int fuzzerAdvance(fuzzer_cursor *pCur, fuzzer_stem *pStem){ const fuzzer_rule *pRule; @@ -283,21 +313,14 @@ static int fuzzerAdvance(fuzzer_cursor *pCur, fuzzer_stem *pStem){ || memcmp(&pStem->zBasis[pStem->n], pRule->zFrom, pRule->nFrom)==0 ){ /* Found a rewrite case. Make sure it is not a duplicate */ - unsigned int h; - fuzzer_stem *pLookup; - - fuzzerComputeWord(pCur, pStem); - h = fuzzerHash(pCur->zBuf); - pLookup = pCur->apHash[h]; - while( pLookup && strcmp(pLookup->zBasis, pCur->zBuf)!=0 ){ - pLookup = pLookup->pHash; - } - if( pLookup==0 ) return 1; /* A new output is found. */ + int rc = fuzzerSeen(pCur, pStem); + if( rc<0 ) return -1; + if( rc==0 ) return 1; } } pStem->n = -1; pStem->pRule = pRule->pNext; - if( fuzzerCost(pStem)>pCur->rLimit ) pStem->pRule = 0; + if( pStem->pRule && fuzzerCost(pStem)>pCur->rLimit ) pStem->pRule = 0; } return 0; } @@ -310,6 +333,10 @@ static int fuzzerAdvance(fuzzer_cursor *pCur, fuzzer_stem *pStem){ static fuzzer_stem *fuzzerInsert(fuzzer_stem *pList, fuzzer_stem *pNew){ fuzzer_cost c1; + if( pList==0 ){ + pNew->pNext = 0; + return pNew; + } c1 = fuzzerCost(pNew); if( c1 <= fuzzerCost(pList) ){ pNew->pNext = pList; @@ -358,20 +385,30 @@ static fuzzer_stem *fuzzerNewStem( ** Advance a cursor to its next row of output */ static int fuzzerNext(sqlite3_vtab_cursor *cur){ - fuzzer_cursor *pCur = (fuzzer_cursor*)pCur; + fuzzer_cursor *pCur = (fuzzer_cursor*)cur; + int rc; fuzzer_stem *pStem, *pNew; /* Use the element the cursor is currently point to to create ** a new stem and insert the new stem into the priority queue. */ - fuzzerComputeWord(pCur, pCur->pStem); - pNew = fuzzerNewStem(pCur, pCur->zBuf, fuzzerCost(pCur->pStem)); - if( pNew ){ - if( fuzzerAdvance(pCur, pNew)==0 ){ - pNew->pNext = pCur->pDone; - pCur->pDone = pNew; + pStem = pCur->pStem; + if( fuzzerCost(pStem)>0 ){ + rc = fuzzerRender(pStem, &pCur->zBuf, &pCur->nBuf); + if( rc==SQLITE_NOMEM ) return SQLITE_NOMEM; + pNew = fuzzerNewStem(pCur, pCur->zBuf, fuzzerCost(pStem)); + if( pNew ){ + if( fuzzerAdvance(pCur, pNew)==0 ){ + pNew->pNext = pCur->pDone; + pCur->pDone = pNew; + }else{ + pCur->pStem = fuzzerInsert(pStem, pNew); + if( pCur->pStem==pNew ){ + return SQLITE_OK; + } + } }else{ - pCur->pStem = fuzzerInsert(pCur->pStem, pNew); + return SQLITE_NOMEM; } } @@ -381,7 +418,12 @@ static int fuzzerNext(sqlite3_vtab_cursor *cur){ while( (pStem = pCur->pStem)!=0 ){ if( fuzzerAdvance(pCur, pStem) ){ pCur->pStem = fuzzerInsert(pStem->pNext, pStem); - return SQLITE_OK; /* New word found */ + if( pCur->pStem!=pStem && (rc = fuzzerSeen(pCur, pStem))!=0 ){ + if( rc<0 ) return SQLITE_NOMEM; + continue; + }else{ + return SQLITE_OK; /* New word found */ + } } pCur->pStem = pStem->pNext; pStem->pNext = pCur->pDone; @@ -406,9 +448,10 @@ static int fuzzerFilter( ){ fuzzer_cursor *pCur = (fuzzer_cursor *)pVtabCursor; const char *zWord = 0; - pCur->rLimit = 2147483647; + fuzzer_stem *pStem; fuzzerClearCursor(pCur, 1); + pCur->rLimit = 2147483647; if( idxNum==1 ){ zWord = (const char*)sqlite3_value_text(argv[0]); }else if( idxNum==2 ){ @@ -418,8 +461,15 @@ static int fuzzerFilter( pCur->rLimit = (fuzzer_cost)sqlite3_value_int(argv[1]); } if( zWord==0 ) zWord = ""; - pCur->pStem = fuzzerNewStem(pCur, zWord, (fuzzer_cost)0); - if( pCur->pStem==0 ) return SQLITE_NOMEM; + pCur->pStem = pStem = fuzzerNewStem(pCur, zWord, (fuzzer_cost)0); + if( pStem==0 ) return SQLITE_NOMEM; + pCur->nullRule.pNext = pCur->pVtab->pRule; + pCur->nullRule.rCost = 0; + pCur->nullRule.nFrom = 0; + pCur->nullRule.nTo = 0; + pCur->nullRule.zFrom = ""; + pStem->pRule = &pCur->nullRule; + pStem->n = pStem->nBasis; return SQLITE_OK; } @@ -431,7 +481,7 @@ static int fuzzerColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ fuzzer_cursor *pCur = (fuzzer_cursor*)cur; if( i==0 ){ /* the "word" column */ - if( fuzzerComputeWord(pCur, pCur->pStem)==SQLITE_NOMEM ){ + if( fuzzerRender(pCur->pStem, &pCur->zBuf, &pCur->nBuf)==SQLITE_NOMEM ){ return SQLITE_NOMEM; } sqlite3_result_text(ctx, pCur->zBuf, -1, SQLITE_TRANSIENT); @@ -567,17 +617,16 @@ static int fuzzerUpdate( pVTab->zErrMsg = sqlite3_mprintf("cost must be positive"); return SQLITE_CONSTRAINT; } - nFrom = strlen(zFrom)+1; - nTo = strlen(zTo)+1; - if( nTo<4 ) nTo = 4; - pRule = sqlite3_malloc( sizeof(*pRule) + nFrom + nTo - 4 ); + nFrom = strlen(zFrom); + nTo = strlen(zTo); + pRule = sqlite3_malloc( sizeof(*pRule) + nFrom + nTo ); if( pRule==0 ){ return SQLITE_NOMEM; } - pRule->zFrom = &pRule->zTo[nTo]; + pRule->zFrom = &pRule->zTo[nTo+1]; pRule->nFrom = nFrom; - memcpy(pRule->zFrom, zFrom, nFrom); - memcpy(pRule->zTo, zTo, nTo); + memcpy(pRule->zFrom, zFrom, nFrom+1); + memcpy(pRule->zTo, zTo, nTo+1); pRule->nTo = nTo; pRule->rCost = rCost; pRule->pNext = p->pNewRule; diff --git a/test/fuzzer1.test b/test/fuzzer1.test index 1e33556aa3..aaceaf1ce1 100644 --- a/test/fuzzer1.test +++ b/test/fuzzer1.test @@ -32,8 +32,8 @@ do_test fuzzer1-1.1 { do_test fuzzer1-1.2 { db eval { INSERT INTO f1(cfrom, cto, cost) VALUES('e','a',1); - INSERT INTO f1(cfrom, cto, cost) VALUES('a','e',1); - INSERT INTO f1(cfrom, cto, cost) VALUES('e','o',2); + INSERT INTO f1(cfrom, cto, cost) VALUES('a','e',10); + INSERT INTO f1(cfrom, cto, cost) VALUES('e','o',100); } } {} diff --git a/test/progress.test b/test/progress.test old mode 100755 new mode 100644 diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100755 new mode 100644 From c8e27ab5da2192c526f4b81f1fc10fe32506b5dc Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 29 Mar 2011 18:21:59 +0000 Subject: [PATCH 4/7] The first simple test-case appears to be working now. FossilOrigin-Name: dd41155bc7459cafc1a2d5c75233193abfbac05d --- manifest | 14 +++++------ manifest.uuid | 2 +- src/test_fuzzer.c | 60 +++++++++++++++++++++++++++++++++++++++-------- test/fuzzer1.test | 2 +- 4 files changed, 59 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 8148ffca72..20d5dc398c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\simprovements\sto\sthe\sfuzzer.\s\sIt\sstill\sis\snot\squite\sworking.\s\sPausing\nto\swork\son\sother\sthings.... -D 2011-03-29T14:08:09.188 +C The\sfirst\ssimple\stest-case\sappears\sto\sbe\sworking\snow. +D 2011-03-29T18:21:59.753 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6c96e694f446500449f683070b906de9fce17b88 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -202,7 +202,7 @@ F src/test_config.c 62f0f8f934b1d5c7e4cd4f506ae453a1117b47d7 F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 -F src/test_fuzzer.c 3e402dd5e6c4f096fdc92c52e775e8fad85bce9b +F src/test_fuzzer.c 1427f9b54dbb6fa4742bd611adcd9b0abedfc083 F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2 F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 @@ -476,7 +476,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/fuzzer1.test a5d60f618443b86b5f5a695a41d01b7d8697345d +F test/fuzzer1.test a81a50d7ba6005d9cc98bf58b8aae8c3e73e11a6 F test/hook.test f04c3412463f8ec117c1c704c74ca0f627ce733a F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d @@ -918,7 +918,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P fb4c31eac8a7290f61c50a3552245660e1271871 -R 86b6649d084e41c015babc3a0e3fb294 +P 5f2f2fce40f43debeb0492c9b460b85c7dad2bde +R 1ce7df4d179ed6c133db387973d1e6f3 U drh -Z 67d6460bdc70fd366585e4c8607ab8f4 +Z 6cf1874f37d2b9758d183fd9153a451e diff --git a/manifest.uuid b/manifest.uuid index 09a1e57cc7..98b1b08a7b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f2f2fce40f43debeb0492c9b460b85c7dad2bde \ No newline at end of file +dd41155bc7459cafc1a2d5c75233193abfbac05d \ No newline at end of file diff --git a/src/test_fuzzer.c b/src/test_fuzzer.c index 82f35a2f51..9a5f8c5930 100644 --- a/src/test_fuzzer.c +++ b/src/test_fuzzer.c @@ -255,14 +255,17 @@ static int fuzzerRender( } n = pStem->n; z = *pzBuf; - memcpy(z, pStem->zBasis, n); - memcpy(&z[n], pRule->zTo, pRule->nTo); - memcpy(&z[n+pRule->nTo], &pStem->zBasis[n+pRule->nFrom], - pStem->nBasis-n-pRule->nFrom+1); + if( n<0 ){ + memcpy(z, pStem->zBasis, pStem->nBasis+1); + }else{ + memcpy(z, pStem->zBasis, n); + memcpy(&z[n], pRule->zTo, pRule->nTo); + memcpy(&z[n+pRule->nTo], &pStem->zBasis[n+pRule->nFrom], + pStem->nBasis-n-pRule->nFrom+1); + } return SQLITE_OK; } - /* ** Compute a hash on zBasis. */ @@ -279,6 +282,35 @@ static fuzzer_cost fuzzerCost(fuzzer_stem *pStem){ return pStem->rBaseCost + pStem->pRule->rCost; } +#if 0 +/* +** Print a description of a fuzzer_stem on stderr. +*/ +static void fuzzerStemPrint( + const char *zPrefix, + fuzzer_stem *pStem, + const char *zSuffix +){ + if( pStem->n<0 ){ + fprintf(stderr, "%s[%s](%d)-->self%s", + zPrefix, + pStem->zBasis, pStem->rBaseCost, + zSuffix + ); + }else{ + char *zBuf = 0; + int nBuf = 0; + if( fuzzerRender(pStem, &zBuf, &nBuf)!=SQLITE_OK ) return; + fprintf(stderr, "%s[%s](%d)-->{%s}(%d)%s", + zPrefix, + pStem->zBasis, pStem->rBaseCost, zBuf, fuzzerCost(pStem), + zSuffix + ); + sqlite3_free(zBuf); + } +} +#endif + /* ** Return 1 if the string to which the cursor is point has already ** been emitted. Return 0 if not. Return -1 on a memory allocation @@ -315,7 +347,9 @@ static int fuzzerAdvance(fuzzer_cursor *pCur, fuzzer_stem *pStem){ /* Found a rewrite case. Make sure it is not a duplicate */ int rc = fuzzerSeen(pCur, pStem); if( rc<0 ) return -1; - if( rc==0 ) return 1; + if( rc==0 ){ + return 1; + } } } pStem->n = -1; @@ -417,17 +451,23 @@ static int fuzzerNext(sqlite3_vtab_cursor *cur){ */ while( (pStem = pCur->pStem)!=0 ){ if( fuzzerAdvance(pCur, pStem) ){ - pCur->pStem = fuzzerInsert(pStem->pNext, pStem); - if( pCur->pStem!=pStem && (rc = fuzzerSeen(pCur, pStem))!=0 ){ + pCur->pStem = pStem = fuzzerInsert(pStem->pNext, pStem); + if( (rc = fuzzerSeen(pCur, pStem))!=0 ){ if( rc<0 ) return SQLITE_NOMEM; continue; - }else{ - return SQLITE_OK; /* New word found */ } + return SQLITE_OK; /* New word found */ } pCur->pStem = pStem->pNext; pStem->pNext = pCur->pDone; pCur->pDone = pStem; + if( pCur->pStem ){ + rc = fuzzerSeen(pCur, pCur->pStem); + if( rc<0 ) return SQLITE_NOMEM; + if( rc==0 ){ + return SQLITE_OK; + } + } } /* Reach this point only if queue has been exhausted and there is diff --git a/test/fuzzer1.test b/test/fuzzer1.test index aaceaf1ce1..895d6b3b2a 100644 --- a/test/fuzzer1.test +++ b/test/fuzzer1.test @@ -41,7 +41,7 @@ do_test fuzzer1-1.3 { db eval { SELECT word, distance FROM f1 WHERE word MATCH 'abcde' } -} {} +} {abcde 0 abcda 1 ebcde 10 ebcda 11 abcdo 100 ebcdo 110 obcde 110 obcda 111 obcdo 210} finish_test From f938a87cfdb990d655ded1f954c45c46cf6e6a81 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 29 Mar 2011 23:41:31 +0000 Subject: [PATCH 5/7] Add support for rowid. FossilOrigin-Name: 2cf4158ff051916717fc2c0f4b6332d5f6ea6e3d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/test_fuzzer.c | 9 +++++++-- tool/mkopts.tcl | 0 4 files changed, 15 insertions(+), 10 deletions(-) mode change 100644 => 100755 tool/mkopts.tcl diff --git a/manifest b/manifest index 20d5dc398c..10d2ec544b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sfirst\ssimple\stest-case\sappears\sto\sbe\sworking\snow. -D 2011-03-29T18:21:59.753 +C Add\ssupport\sfor\srowid. +D 2011-03-29T23:41:31.447 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6c96e694f446500449f683070b906de9fce17b88 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -202,7 +202,7 @@ F src/test_config.c 62f0f8f934b1d5c7e4cd4f506ae453a1117b47d7 F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 -F src/test_fuzzer.c 1427f9b54dbb6fa4742bd611adcd9b0abedfc083 +F src/test_fuzzer.c dcb1e78badcf6f469ae386ecbed0e287920699c6 F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2 F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 @@ -893,7 +893,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -918,7 +918,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 5f2f2fce40f43debeb0492c9b460b85c7dad2bde -R 1ce7df4d179ed6c133db387973d1e6f3 +P dd41155bc7459cafc1a2d5c75233193abfbac05d +R 580275be924edc1c171a4ef2518a45c4 U drh -Z 6cf1874f37d2b9758d183fd9153a451e +Z c835c92c0dd7f7913ad85caf0a4ef7ac diff --git a/manifest.uuid b/manifest.uuid index 98b1b08a7b..398d9aafa8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dd41155bc7459cafc1a2d5c75233193abfbac05d \ No newline at end of file +2cf4158ff051916717fc2c0f4b6332d5f6ea6e3d \ No newline at end of file diff --git a/src/test_fuzzer.c b/src/test_fuzzer.c index 9a5f8c5930..5287b1f457 100644 --- a/src/test_fuzzer.c +++ b/src/test_fuzzer.c @@ -86,6 +86,7 @@ struct fuzzer_vtab { /* A fuzzer cursor object */ struct fuzzer_cursor { sqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3_int64 iRowid; /* The rowid of the current word */ fuzzer_vtab *pVtab; /* The virtual table this cursor belongs to */ fuzzer_cost rLimit; /* Maximum cost of any term */ fuzzer_stem *pStem; /* Sorted list of stems for generating new terms */ @@ -423,6 +424,8 @@ static int fuzzerNext(sqlite3_vtab_cursor *cur){ int rc; fuzzer_stem *pStem, *pNew; + pCur->iRowid++; + /* Use the element the cursor is currently point to to create ** a new stem and insert the new stem into the priority queue. */ @@ -510,6 +513,7 @@ static int fuzzerFilter( pCur->nullRule.zFrom = ""; pStem->pRule = &pCur->nullRule; pStem->n = pStem->nBasis; + pCur->iRowid = 1; return SQLITE_OK; } @@ -536,10 +540,11 @@ static int fuzzerColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ } /* -** The rowid is always 0 +** The rowid. */ static int fuzzerRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ - *pRowid = 0; /* The rowid is always 0 */ + fuzzer_cursor *pCur = (fuzzer_cursor*)cur; + *pRowid = pCur->iRowid; return SQLITE_OK; } diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100644 new mode 100755 From 2a0e00b436f94594307cb989cc1235be3011864e Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 30 Mar 2011 01:43:00 +0000 Subject: [PATCH 6/7] Move to an O(NlogN) algorithm for the priority queue. An insertion sort was way too slow. FossilOrigin-Name: 7958cbba736a599c1293b06602eec43dfe4fd7d1 --- manifest | 12 ++-- manifest.uuid | 2 +- src/test_fuzzer.c | 174 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 141 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index 10d2ec544b..7aec386c02 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\srowid. -D 2011-03-29T23:41:31.447 +C Move\sto\san\sO(NlogN)\salgorithm\sfor\sthe\spriority\squeue.\s\sAn\sinsertion\ssort\nwas\sway\stoo\sslow. +D 2011-03-30T01:43:00.780 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6c96e694f446500449f683070b906de9fce17b88 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -202,7 +202,7 @@ F src/test_config.c 62f0f8f934b1d5c7e4cd4f506ae453a1117b47d7 F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 -F src/test_fuzzer.c dcb1e78badcf6f469ae386ecbed0e287920699c6 +F src/test_fuzzer.c edc2aaa0f75ce49efef39bcd2df45138479b0992 F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2 F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 @@ -918,7 +918,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P dd41155bc7459cafc1a2d5c75233193abfbac05d -R 580275be924edc1c171a4ef2518a45c4 +P 2cf4158ff051916717fc2c0f4b6332d5f6ea6e3d +R 9250685bf3b3b21491f862d4fc8952d0 U drh -Z c835c92c0dd7f7913ad85caf0a4ef7ac +Z 0b9911f371ac67382b47460caefb0a30 diff --git a/manifest.uuid b/manifest.uuid index 398d9aafa8..dfc8e61028 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2cf4158ff051916717fc2c0f4b6332d5f6ea6e3d \ No newline at end of file +7958cbba736a599c1293b06602eec43dfe4fd7d1 \ No newline at end of file diff --git a/src/test_fuzzer.c b/src/test_fuzzer.c index 5287b1f457..ffdd61c9f6 100644 --- a/src/test_fuzzer.c +++ b/src/test_fuzzer.c @@ -66,6 +66,7 @@ struct fuzzer_stem { const fuzzer_rule *pRule; /* Current rule to apply */ int n; /* Apply pRule at this character offset */ fuzzer_cost rBaseCost; /* Base cost of getting to zBasis */ + fuzzer_cost rCostX; /* Precomputed rBaseCost + pRule->rCost */ fuzzer_stem *pNext; /* Next stem in rCost order */ fuzzer_stem *pHash; /* Next stem with same hash on zBasis */ }; @@ -82,6 +83,7 @@ struct fuzzer_vtab { }; #define FUZZER_HASH 4001 /* Hash table size */ +#define FUZZER_NQUEUE 20 /* Number of slots on the stem queue */ /* A fuzzer cursor object */ struct fuzzer_cursor { @@ -89,10 +91,13 @@ struct fuzzer_cursor { sqlite3_int64 iRowid; /* The rowid of the current word */ fuzzer_vtab *pVtab; /* The virtual table this cursor belongs to */ fuzzer_cost rLimit; /* Maximum cost of any term */ - fuzzer_stem *pStem; /* Sorted list of stems for generating new terms */ + fuzzer_stem *pStem; /* Stem with smallest rCostX */ fuzzer_stem *pDone; /* Stems already processed to completion */ + fuzzer_stem *aQueue[FUZZER_NQUEUE]; /* Queue of stems with higher rCostX */ + int mxQueue; /* Largest used index in aQueue[] */ char *zBuf; /* Temporary use buffer */ int nBuf; /* Bytes allocated for zBuf */ + int nStem; /* Number of stems allocated */ fuzzer_rule nullRule; /* Null rule used first */ fuzzer_stem *apHash[FUZZER_HASH]; /* Hash of previously generated terms */ }; @@ -205,23 +210,35 @@ static int fuzzerOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ return SQLITE_OK; } +/* +** Free all stems in a list. +*/ +static void fuzzerClearStemList(fuzzer_stem *pStem){ + while( pStem ){ + fuzzer_stem *pNext = pStem->pNext; + sqlite3_free(pStem); + pStem = pNext; + } +} + /* ** Free up all the memory allocated by a cursor. Set it rLimit to 0 ** to indicate that it is at EOF. */ static void fuzzerClearCursor(fuzzer_cursor *pCur, int clearHash){ - if( pCur->pStem==0 && pCur->pDone==0 ) clearHash = 0; - do{ - while( pCur->pStem ){ - fuzzer_stem *pStem = pCur->pStem; - pCur->pStem = pStem->pNext; - sqlite3_free(pStem); - } - pCur->pStem = pCur->pDone; - pCur->pDone = 0; - }while( pCur->pStem ); + int i; + fuzzerClearStemList(pCur->pStem); + fuzzerClearStemList(pCur->pDone); + for(i=0; iaQueue[i]); pCur->rLimit = (fuzzer_cost)0; - if( clearHash ) memset(pCur->apHash, 0, sizeof(pCur->apHash)); + if( clearHash && pCur->nStem ){ + pCur->mxQueue = 0; + pCur->pStem = 0; + pCur->pDone = 0; + memset(pCur->aQueue, 0, sizeof(pCur->aQueue)); + memset(pCur->apHash, 0, sizeof(pCur->apHash)); + } + pCur->nStem = 0; } /* @@ -280,7 +297,7 @@ static unsigned int fuzzerHash(const char *z){ ** Current cost of a stem */ static fuzzer_cost fuzzerCost(fuzzer_stem *pStem){ - return pStem->rBaseCost + pStem->pRule->rCost; + return pStem->rCostX = pStem->rBaseCost + pStem->pRule->rCost; } #if 0 @@ -304,7 +321,7 @@ static void fuzzerStemPrint( if( fuzzerRender(pStem, &zBuf, &nBuf)!=SQLITE_OK ) return; fprintf(stderr, "%s[%s](%d)-->{%s}(%d)%s", zPrefix, - pStem->zBasis, pStem->rBaseCost, zBuf, fuzzerCost(pStem), + pStem->zBasis, pStem->rBaseCost, zBuf, pStem->, zSuffix ); sqlite3_free(zBuf); @@ -349,6 +366,7 @@ static int fuzzerAdvance(fuzzer_cursor *pCur, fuzzer_stem *pStem){ int rc = fuzzerSeen(pCur, pStem); if( rc<0 ) return -1; if( rc==0 ){ + fuzzerCost(pStem); return 1; } } @@ -361,31 +379,106 @@ static int fuzzerAdvance(fuzzer_cursor *pCur, fuzzer_stem *pStem){ } /* -** Insert pNew into the list at pList. Return a pointer to the new +** The two input stem lists are both sorted in order of increasing +** rCostX. Merge them together into a single list, sorted by rCostX, and +** return a pointer to the head of that new list. +*/ +static fuzzer_stem *fuzzerMergeStems(fuzzer_stem *pA, fuzzer_stem *pB){ + fuzzer_stem head; + fuzzer_stem *pTail; + + pTail = &head; + while( pA && pB ){ + if( pA->rCostX<=pB->rCostX ){ + pTail->pNext = pA; + pTail = pA; + pA = pA->pNext; + }else{ + pTail->pNext = pB; + pTail = pB; + pB = pB->pNext; + } + } + if( pA==0 ){ + pTail->pNext = pB; + }else{ + pTail->pNext = pA; + } + return head.pNext; +} + +/* +** Load pCur->pStem with the lowest-cost stem. Return a pointer +** to the lowest-cost stem. +*/ +static fuzzer_stem *fuzzerLowestCostStem(fuzzer_cursor *pCur){ + fuzzer_stem *pBest, *pX; + int iBest; + int i; + + if( pCur->pStem==0 ){ + iBest = -1; + pBest = 0; + for(i=0; i<=pCur->mxQueue; i++){ + pX = pCur->aQueue[i]; + if( pX==0 ) continue; + if( pBest==0 || pBest->rCostX>pX->rCostX ){ + pBest = pX; + iBest = i; + } + } + if( pBest ){ + pCur->aQueue[iBest] = pBest->pNext; + pBest->pNext = 0; + pCur->pStem = pBest; + } + } + return pCur->pStem; +} + +/* +** Insert pNew into queue of pending stems. Then find the stem +** with the lowest rCostX and move it into pCur->pStem. ** list. The insert is done such the pNew is in the correct order ** according to fuzzer_stem.zBaseCost+fuzzer_stem.pRule->rCost. */ -static fuzzer_stem *fuzzerInsert(fuzzer_stem *pList, fuzzer_stem *pNew){ - fuzzer_cost c1; +static fuzzer_stem *fuzzerInsert(fuzzer_cursor *pCur, fuzzer_stem *pNew){ + fuzzer_stem *pX; + int i; - if( pList==0 ){ + /* If pCur->pStem exists and is greater than pNew, then make pNew + ** the new pCur->pStem and insert the old pCur->pStem instead. + */ + if( (pX = pCur->pStem)!=0 && pX->rCostX>pNew->rCostX ){ pNew->pNext = 0; - return pNew; + pCur->pStem = pNew; + pNew = pX; } - c1 = fuzzerCost(pNew); - if( c1 <= fuzzerCost(pList) ){ - pNew->pNext = pList; - return pNew; - }else{ - fuzzer_stem *pPrev; - pPrev = pList; - while( pPrev->pNext && fuzzerCost(pPrev->pNext)pNext; + + /* Insert the new value */ + pNew->pNext = 0; + pX = pNew; + for(i=0; i<=pCur->mxQueue; i++){ + if( pCur->aQueue[i] ){ + pX = fuzzerMergeStems(pX, pCur->aQueue[i]); + pCur->aQueue[i] = 0; + }else{ + pCur->aQueue[i] = pX; + break; } - pNew->pNext = pPrev->pNext; - pPrev->pNext = pNew; - return pList; } + if( i>pCur->mxQueue ){ + if( imxQueue = i; + pCur->aQueue[i] = pX; + }else{ + assert( pCur->mxQueue==FUZZER_NQUEUE-1 ); + pX = fuzzerMergeStems(pX, pCur->aQueue[FUZZER_NQUEUE-1]); + pCur->aQueue[FUZZER_NQUEUE-1] = pX; + } + } + + return fuzzerLowestCostStem(pCur); } /* @@ -408,10 +501,11 @@ static fuzzer_stem *fuzzerNewStem( memcpy(pNew->zBasis, zWord, pNew->nBasis+1); pNew->pRule = pCur->pVtab->pRule; pNew->n = -1; - pNew->rBaseCost = rBaseCost; + pNew->rBaseCost = pNew->rCostX = rBaseCost; h = fuzzerHash(pNew->zBasis); pNew->pHash = pCur->apHash[h]; pCur->apHash[h] = pNew; + pCur->nStem++; return pNew; } @@ -430,17 +524,16 @@ static int fuzzerNext(sqlite3_vtab_cursor *cur){ ** a new stem and insert the new stem into the priority queue. */ pStem = pCur->pStem; - if( fuzzerCost(pStem)>0 ){ + if( pStem->rCostX>0 ){ rc = fuzzerRender(pStem, &pCur->zBuf, &pCur->nBuf); if( rc==SQLITE_NOMEM ) return SQLITE_NOMEM; - pNew = fuzzerNewStem(pCur, pCur->zBuf, fuzzerCost(pStem)); + pNew = fuzzerNewStem(pCur, pCur->zBuf, pStem->rCostX); if( pNew ){ if( fuzzerAdvance(pCur, pNew)==0 ){ pNew->pNext = pCur->pDone; pCur->pDone = pNew; }else{ - pCur->pStem = fuzzerInsert(pStem, pNew); - if( pCur->pStem==pNew ){ + if( fuzzerInsert(pCur, pNew)==pNew ){ return SQLITE_OK; } } @@ -454,17 +547,18 @@ static int fuzzerNext(sqlite3_vtab_cursor *cur){ */ while( (pStem = pCur->pStem)!=0 ){ if( fuzzerAdvance(pCur, pStem) ){ - pCur->pStem = pStem = fuzzerInsert(pStem->pNext, pStem); + pCur->pStem = 0; + pStem = fuzzerInsert(pCur, pStem); if( (rc = fuzzerSeen(pCur, pStem))!=0 ){ if( rc<0 ) return SQLITE_NOMEM; continue; } return SQLITE_OK; /* New word found */ } - pCur->pStem = pStem->pNext; + pCur->pStem = 0; pStem->pNext = pCur->pDone; pCur->pDone = pStem; - if( pCur->pStem ){ + if( fuzzerLowestCostStem(pCur) ){ rc = fuzzerSeen(pCur, pCur->pStem); if( rc<0 ) return SQLITE_NOMEM; if( rc==0 ){ @@ -531,7 +625,7 @@ static int fuzzerColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ sqlite3_result_text(ctx, pCur->zBuf, -1, SQLITE_TRANSIENT); }else if( i==1 ){ /* the "distance" column */ - sqlite3_result_int(ctx, fuzzerCost(pCur->pStem)); + sqlite3_result_int(ctx, pCur->pStem->rCostX); }else{ /* All other columns are NULL */ sqlite3_result_null(ctx); From 1b05c423fe293c13fad8f63699458433c60c8009 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 1 Apr 2011 20:28:31 +0000 Subject: [PATCH 7/7] Add additional test data and documentation to the fuzzer virtual table. FossilOrigin-Name: a6a81d4fdafabba514e8f8e1958d6132b3850772 --- manifest | 16 +- manifest.uuid | 2 +- src/test_fuzzer.c | 81 +++ test/fuzzer1.test | 1335 +++++++++++++++++++++++++++++++++++++++++++++ tool/mkopts.tcl | 0 5 files changed, 1425 insertions(+), 9 deletions(-) mode change 100755 => 100644 tool/mkopts.tcl diff --git a/manifest b/manifest index 7aec386c02..a081a12fe5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sto\san\sO(NlogN)\salgorithm\sfor\sthe\spriority\squeue.\s\sAn\sinsertion\ssort\nwas\sway\stoo\sslow. -D 2011-03-30T01:43:00.780 +C Add\sadditional\stest\sdata\sand\sdocumentation\sto\sthe\sfuzzer\svirtual\stable. +D 2011-04-01T20:28:31.337 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 6c96e694f446500449f683070b906de9fce17b88 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -202,7 +202,7 @@ F src/test_config.c 62f0f8f934b1d5c7e4cd4f506ae453a1117b47d7 F src/test_demovfs.c 0aed671636735116fc872c5b03706fd5612488b5 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc F src/test_func.c cbdec5cededa0761daedde5baf06004a9bf416b5 -F src/test_fuzzer.c edc2aaa0f75ce49efef39bcd2df45138479b0992 +F src/test_fuzzer.c f884f6f32e8513d34248d6e1ac8a32047fead254 F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2 F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c F src/test_intarray.c d879bbf8e4ce085ab966d1f3c896a7c8b4f5fc99 @@ -476,7 +476,7 @@ F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167 F test/fuzz3.test aec64345184d1662bd30e6a17851ff659d596dc5 F test/fuzz_common.tcl a87dfbb88c2a6b08a38e9a070dabd129e617b45b F test/fuzz_malloc.test dd7001ac86d09c154a7dff064f4739c60e2b312c -F test/fuzzer1.test a81a50d7ba6005d9cc98bf58b8aae8c3e73e11a6 +F test/fuzzer1.test 3105b5a89a6cb0d475f0877debec942fe4143462 F test/hook.test f04c3412463f8ec117c1c704c74ca0f627ce733a F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 19b642bb134308980a92249750ea4ce3f6c75c2d @@ -893,7 +893,7 @@ F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5 F tool/lemon.c dfd81a51b6e27e469ba21d01a75ddf092d429027 F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc F tool/mkkeywordhash.c d2e6b4a5965e23afb80fbe74bb54648cd371f309 -F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x +F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c.tcl cf44512a48112b1ba09590548660a5a6877afdb3 F tool/mksqlite3h.tcl d76c226a5e8e1f3b5f6593bcabe5e98b3b1ec9ff @@ -918,7 +918,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 2cf4158ff051916717fc2c0f4b6332d5f6ea6e3d -R 9250685bf3b3b21491f862d4fc8952d0 +P 7958cbba736a599c1293b06602eec43dfe4fd7d1 +R a5f7c9b6891187773247bee84f644851 U drh -Z 0b9911f371ac67382b47460caefb0a30 +Z b39064b9fd85dd1a63e76912c214c45c diff --git a/manifest.uuid b/manifest.uuid index dfc8e61028..f8b467bbd6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7958cbba736a599c1293b06602eec43dfe4fd7d1 \ No newline at end of file +a6a81d4fdafabba514e8f8e1958d6132b3850772 \ No newline at end of file diff --git a/src/test_fuzzer.c b/src/test_fuzzer.c index ffdd61c9f6..cf59257175 100644 --- a/src/test_fuzzer.c +++ b/src/test_fuzzer.c @@ -12,6 +12,87 @@ ** ** Code for demonstartion virtual table that generates variations ** on an input word at increasing edit distances from the original. +** +** A fuzzer virtual table is created like this: +** +** CREATE VIRTUAL TABLE temp.f USING fuzzer; +** +** The name of the new virtual table in the example above is "f". +** Note that all fuzzer virtual tables must be TEMP tables. The +** "temp." prefix in front of the table name is required when the +** table is being created. The "temp." prefix can be omitted when +** using the table as long as the name is unambiguous. +** +** Before being used, the fuzzer needs to be programmed by giving it +** character transformations and a cost associated with each transformation. +** Examples: +** +** INSERT INTO f(cFrom,cTo,Cost) VALUES('','a',100); +** +** The above statement says that the cost of inserting a letter 'a' is +** 100. (All costs are integers. We recommend that costs be scaled so +** that the average cost is around 100.) +** +** INSERT INTO f(cFrom,cTo,Cost) VALUES('b','',87); +** +** The above statement says that the cost of deleting a single letter +** 'b' is 87. +** +** INSERT INTO f(cFrom,cTo,Cost) VALUES('o','oe',38); +** INSERT INTO f(cFrom,cTo,Cost) VALUES('oe','o',40); +** +** This third example says that the cost of transforming the single +** letter "o" into the two-letter sequence "oe" is 38 and that the +** cost of transforming "oe" back into "o" is 40. +** +** After all the transformation costs have been set, the fuzzer table +** can be queried as follows: +** +** SELECT word, distance FROM f +** WHERE word MATCH 'abcdefg' +** AND distance<200; +** +** This first query outputs the string "abcdefg" and all strings that +** can be derived from that string by appling the specified transformations. +** The strings are output together with their total transformation cost +** (called "distance") and appear in order of increasing cost. No string +** is output more than once. If there are multiple ways to transform the +** target string into the output string then the lowest cost transform is +** the one that is returned. In the example, the search is limited to +** strings with a total distance of less than 200. +** +** It is important to put some kind of a limit on the fuzzer output. This +** can be either in the form of a LIMIT clause at the end of the query, +** or better, a "distance diff --git a/test/fuzzer1.test b/test/fuzzer1.test index 895d6b3b2a..d0575d2d00 100644 --- a/test/fuzzer1.test +++ b/test/fuzzer1.test @@ -43,5 +43,1340 @@ do_test fuzzer1-1.3 { } } {abcde 0 abcda 1 ebcde 10 ebcda 11 abcdo 100 ebcdo 110 obcde 110 obcda 111 obcdo 210} +do_test fuzzer1-2.0 { + execsql { + CREATE VIRTUAL TABLE temp.f2 USING fuzzer; + -- costs based on English letter frequencies + INSERT INTO f2(cFrom,cTo,cost) VALUES('a','e',24); + INSERT INTO f2(cFrom,cTo,cost) VALUES('a','o',47); + INSERT INTO f2(cFrom,cTo,cost) VALUES('a','u',50); + INSERT INTO f2(cFrom,cTo,cost) VALUES('e','a',23); + INSERT INTO f2(cFrom,cTo,cost) VALUES('e','i',33); + INSERT INTO f2(cFrom,cTo,cost) VALUES('e','o',37); + INSERT INTO f2(cFrom,cTo,cost) VALUES('i','e',33); + INSERT INTO f2(cFrom,cTo,cost) VALUES('i','y',33); + INSERT INTO f2(cFrom,cTo,cost) VALUES('o','a',41); + INSERT INTO f2(cFrom,cTo,cost) VALUES('o','e',46); + INSERT INTO f2(cFrom,cTo,cost) VALUES('o','u',57); + INSERT INTO f2(cFrom,cTo,cost) VALUES('u','o',58); + INSERT INTO f2(cFrom,cTo,cost) VALUES('y','i',33); + + INSERT INTO f2(cFrom,cTo,cost) VALUES('t','th',70); + INSERT INTO f2(cFrom,cTo,cost) VALUES('th','t',66); + + + INSERT INTO f2(cFrom,cTo,cost) VALUES('a','',84); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','b',106); + INSERT INTO f2(cFrom,cTo,cost) VALUES('b','',106); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','c',94); + INSERT INTO f2(cFrom,cTo,cost) VALUES('c','',94); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','d',89); + INSERT INTO f2(cFrom,cTo,cost) VALUES('d','',89); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','e',83); + INSERT INTO f2(cFrom,cTo,cost) VALUES('e','',83); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','f',97); + INSERT INTO f2(cFrom,cTo,cost) VALUES('f','',97); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','g',99); + INSERT INTO f2(cFrom,cTo,cost) VALUES('g','',99); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','h',86); + INSERT INTO f2(cFrom,cTo,cost) VALUES('h','',86); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','i',85); + INSERT INTO f2(cFrom,cTo,cost) VALUES('i','',85); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','j',120); + INSERT INTO f2(cFrom,cTo,cost) VALUES('j','',120); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','k',120); + INSERT INTO f2(cFrom,cTo,cost) VALUES('k','',120); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','l',89); + INSERT INTO f2(cFrom,cTo,cost) VALUES('l','',89); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','m',96); + INSERT INTO f2(cFrom,cTo,cost) VALUES('m','',96); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','n',85); + INSERT INTO f2(cFrom,cTo,cost) VALUES('n','',85); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','o',85); + INSERT INTO f2(cFrom,cTo,cost) VALUES('o','',85); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','p',100); + INSERT INTO f2(cFrom,cTo,cost) VALUES('p','',100); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','q',120); + INSERT INTO f2(cFrom,cTo,cost) VALUES('q','',120); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','r',86); + INSERT INTO f2(cFrom,cTo,cost) VALUES('r','',86); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','s',86); + INSERT INTO f2(cFrom,cTo,cost) VALUES('s','',86); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','t',84); + INSERT INTO f2(cFrom,cTo,cost) VALUES('t','',84); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','u',94); + INSERT INTO f2(cFrom,cTo,cost) VALUES('u','',94); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','v',120); + INSERT INTO f2(cFrom,cTo,cost) VALUES('v','',120); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','w',96); + INSERT INTO f2(cFrom,cTo,cost) VALUES('w','',96); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','x',120); + INSERT INTO f2(cFrom,cTo,cost) VALUES('x','',120); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','y',100); + INSERT INTO f2(cFrom,cTo,cost) VALUES('y','',100); + INSERT INTO f2(cFrom,cTo,cost) VALUES('','z',120); + INSERT INTO f2(cFrom,cTo,cost) VALUES('z','',120); + + -- Street names for the 28269 ZIPCODE. + -- + CREATE TEMP TABLE streetname(n TEXT UNIQUE); + INSERT INTO streetname VALUES('abbotsinch'); + INSERT INTO streetname VALUES('abbottsgate'); + INSERT INTO streetname VALUES('abbywood'); + INSERT INTO streetname VALUES('abner'); + INSERT INTO streetname VALUES('acacia ridge'); + INSERT INTO streetname VALUES('acorn creek'); + INSERT INTO streetname VALUES('acorn forest'); + INSERT INTO streetname VALUES('adel'); + INSERT INTO streetname VALUES('ainslie'); + INSERT INTO streetname VALUES('airways'); + INSERT INTO streetname VALUES('alabaster'); + INSERT INTO streetname VALUES('alba'); + INSERT INTO streetname VALUES('albertine'); + INSERT INTO streetname VALUES('alden glen'); + INSERT INTO streetname VALUES('alderson'); + INSERT INTO streetname VALUES('allen'); + INSERT INTO streetname VALUES('allen a brown'); + INSERT INTO streetname VALUES('allness glen'); + INSERT INTO streetname VALUES('aloysia'); + INSERT INTO streetname VALUES('alpine'); + INSERT INTO streetname VALUES('alwyn'); + INSERT INTO streetname VALUES('amaranthus'); + INSERT INTO streetname VALUES('amber glen'); + INSERT INTO streetname VALUES('amber leigh way'); + INSERT INTO streetname VALUES('amber meadows'); + INSERT INTO streetname VALUES('amberway'); + INSERT INTO streetname VALUES('ame'); + INSERT INTO streetname VALUES('amesbury hill'); + INSERT INTO streetname VALUES('anderson'); + INSERT INTO streetname VALUES('andrew thomas'); + INSERT INTO streetname VALUES('anduin falls'); + INSERT INTO streetname VALUES('ankeny'); + INSERT INTO streetname VALUES('annandale'); + INSERT INTO streetname VALUES('annbick'); + INSERT INTO streetname VALUES('antelope'); + INSERT INTO streetname VALUES('anzack'); + INSERT INTO streetname VALUES('apple glen'); + INSERT INTO streetname VALUES('applevalley'); + INSERT INTO streetname VALUES('appley mead'); + INSERT INTO streetname VALUES('aragorn'); + INSERT INTO streetname VALUES('arbor creek'); + INSERT INTO streetname VALUES('arbor day'); + INSERT INTO streetname VALUES('arbor meadows'); + INSERT INTO streetname VALUES('arbor spring'); + INSERT INTO streetname VALUES('arborview'); + INSERT INTO streetname VALUES('arklow'); + INSERT INTO streetname VALUES('armitage'); + INSERT INTO streetname VALUES('arvin'); + INSERT INTO streetname VALUES('ash cove'); + INSERT INTO streetname VALUES('ashford leigh'); + INSERT INTO streetname VALUES('ashmont'); + INSERT INTO streetname VALUES('atlas'); + INSERT INTO streetname VALUES('atwater'); + INSERT INTO streetname VALUES('auburn hill'); + INSERT INTO streetname VALUES('aulton link'); + INSERT INTO streetname VALUES('austin dekota'); + INSERT INTO streetname VALUES('austin knoll'); + INSERT INTO streetname VALUES('auten'); + INSERT INTO streetname VALUES('autumn harvest'); + INSERT INTO streetname VALUES('autumn oak'); + INSERT INTO streetname VALUES('autumn ridge'); + INSERT INTO streetname VALUES('avalon forest'); + INSERT INTO streetname VALUES('avalon loop'); + INSERT INTO streetname VALUES('avon farm'); + INSERT INTO streetname VALUES('avonhurst'); + INSERT INTO streetname VALUES('avonlea'); + INSERT INTO streetname VALUES('aynrand'); + INSERT INTO streetname VALUES('azure valley'); + INSERT INTO streetname VALUES('baberton'); + INSERT INTO streetname VALUES('baffin'); + INSERT INTO streetname VALUES('baggins'); + INSERT INTO streetname VALUES('balata'); + INSERT INTO streetname VALUES('ballantray'); + INSERT INTO streetname VALUES('ballston'); + INSERT INTO streetname VALUES('balsam tree'); + INSERT INTO streetname VALUES('bambi'); + INSERT INTO streetname VALUES('banwell'); + INSERT INTO streetname VALUES('barbee'); + INSERT INTO streetname VALUES('barefoot forest'); + INSERT INTO streetname VALUES('barnview'); + INSERT INTO streetname VALUES('baroda'); + INSERT INTO streetname VALUES('barson'); + INSERT INTO streetname VALUES('baskerville'); + INSERT INTO streetname VALUES('battle creek'); + INSERT INTO streetname VALUES('baucom'); + INSERT INTO streetname VALUES('bay pines'); + INSERT INTO streetname VALUES('beaker'); + INSERT INTO streetname VALUES('beard'); + INSERT INTO streetname VALUES('beardsley'); + INSERT INTO streetname VALUES('bearoak'); + INSERT INTO streetname VALUES('beauvista'); + INSERT INTO streetname VALUES('beaver creek'); + INSERT INTO streetname VALUES('beaver hollow'); + INSERT INTO streetname VALUES('bedlington'); + INSERT INTO streetname VALUES('beech cove'); + INSERT INTO streetname VALUES('beech crest'); + INSERT INTO streetname VALUES('beith'); + INSERT INTO streetname VALUES('bell glen'); + INSERT INTO streetname VALUES('bellmore'); + INSERT INTO streetname VALUES('bells mill'); + INSERT INTO streetname VALUES('bellville'); + INSERT INTO streetname VALUES('belmar place'); + INSERT INTO streetname VALUES('bembridge'); + INSERT INTO streetname VALUES('bennett neely'); + INSERT INTO streetname VALUES('bentgrass run'); + INSERT INTO streetname VALUES('benthaven'); + INSERT INTO streetname VALUES('bernardy'); + INSERT INTO streetname VALUES('bernbrook shadow'); + INSERT INTO streetname VALUES('berrybrook'); + INSERT INTO streetname VALUES('berrybush'); + INSERT INTO streetname VALUES('berwick'); + INSERT INTO streetname VALUES('betterton'); + INSERT INTO streetname VALUES('bickham'); + INSERT INTO streetname VALUES('billingham'); + INSERT INTO streetname VALUES('birchcroft'); + INSERT INTO streetname VALUES('birchstone'); + INSERT INTO streetname VALUES('birdwell'); + INSERT INTO streetname VALUES('bisaner'); + INSERT INTO streetname VALUES('bitterbush'); + INSERT INTO streetname VALUES('bitterroot'); + INSERT INTO streetname VALUES('black fox'); + INSERT INTO streetname VALUES('black maple'); + INSERT INTO streetname VALUES('black trail'); + INSERT INTO streetname VALUES('blackbird'); + INSERT INTO streetname VALUES('blake a dare'); + INSERT INTO streetname VALUES('blasdell'); + INSERT INTO streetname VALUES('blue aster'); + INSERT INTO streetname VALUES('blue finch'); + INSERT INTO streetname VALUES('blue lilac'); + INSERT INTO streetname VALUES('blue sky'); + INSERT INTO streetname VALUES('blue tick'); + INSERT INTO streetname VALUES('bob beatty'); + INSERT INTO streetname VALUES('bobcat'); + INSERT INTO streetname VALUES('bolton'); + INSERT INTO streetname VALUES('boomerang'); + INSERT INTO streetname VALUES('boulder'); + INSERT INTO streetname VALUES('boxer'); + INSERT INTO streetname VALUES('boxmeer'); + INSERT INTO streetname VALUES('brachnell view'); + INSERT INTO streetname VALUES('bradford lake'); + INSERT INTO streetname VALUES('bradwell'); + INSERT INTO streetname VALUES('brady'); + INSERT INTO streetname VALUES('braids bend'); + INSERT INTO streetname VALUES('bralers'); + INSERT INTO streetname VALUES('brandie glen'); + INSERT INTO streetname VALUES('brandy ridge'); + INSERT INTO streetname VALUES('brandybuck'); + INSERT INTO streetname VALUES('branthurst'); + INSERT INTO streetname VALUES('brassy creek'); + INSERT INTO streetname VALUES('brathay'); + INSERT INTO streetname VALUES('brawer farm'); + INSERT INTO streetname VALUES('breezy morn'); + INSERT INTO streetname VALUES('brenda'); + INSERT INTO streetname VALUES('brenly'); + INSERT INTO streetname VALUES('brenock'); + INSERT INTO streetname VALUES('brianwood'); + INSERT INTO streetname VALUES('briar rose'); + INSERT INTO streetname VALUES('briarcrest'); + INSERT INTO streetname VALUES('briarthorne'); + INSERT INTO streetname VALUES('brick dust'); + INSERT INTO streetname VALUES('bridgepath'); + INSERT INTO streetname VALUES('bridle ridge'); + INSERT INTO streetname VALUES('briggs'); + INSERT INTO streetname VALUES('brightleaf'); + INSERT INTO streetname VALUES('brigstock'); + INSERT INTO streetname VALUES('broad ridge'); + INSERT INTO streetname VALUES('brock'); + INSERT INTO streetname VALUES('brockhampton'); + INSERT INTO streetname VALUES('broken pine'); + INSERT INTO streetname VALUES('brompton'); + INSERT INTO streetname VALUES('brook falls'); + INSERT INTO streetname VALUES('brookings'); + INSERT INTO streetname VALUES('browne'); + INSERT INTO streetname VALUES('brownes creek'); + INSERT INTO streetname VALUES('brownes ferry'); + INSERT INTO streetname VALUES('brownestone view'); + INSERT INTO streetname VALUES('brumit'); + INSERT INTO streetname VALUES('bryn athyn'); + INSERT INTO streetname VALUES('buck'); + INSERT INTO streetname VALUES('bucklebury'); + INSERT INTO streetname VALUES('buckminister'); + INSERT INTO streetname VALUES('buckspring'); + INSERT INTO streetname VALUES('burch'); + INSERT INTO streetname VALUES('burch shire'); + INSERT INTO streetname VALUES('burkston'); + INSERT INTO streetname VALUES('burmith'); + INSERT INTO streetname VALUES('burnaby'); + INSERT INTO streetname VALUES('butterfly'); + INSERT INTO streetname VALUES('cabin creek'); + INSERT INTO streetname VALUES('cairns mill'); + INSERT INTO streetname VALUES('callender'); + INSERT INTO streetname VALUES('cambellton'); + INSERT INTO streetname VALUES('cambridge bay'); + INSERT INTO streetname VALUES('canary'); + INSERT INTO streetname VALUES('canbury'); + INSERT INTO streetname VALUES('candle leaf'); + INSERT INTO streetname VALUES('canipe'); + INSERT INTO streetname VALUES('canipe farm'); + INSERT INTO streetname VALUES('cannon'); + INSERT INTO streetname VALUES('canopy'); + INSERT INTO streetname VALUES('canso'); + INSERT INTO streetname VALUES('canterbrook'); + INSERT INTO streetname VALUES('cardinal glen'); + INSERT INTO streetname VALUES('cardinal point'); + INSERT INTO streetname VALUES('cardinals nest'); + INSERT INTO streetname VALUES('carlota'); + INSERT INTO streetname VALUES('carmathen'); + INSERT INTO streetname VALUES('carver'); + INSERT INTO streetname VALUES('carver pond'); + INSERT INTO streetname VALUES('casa loma'); + INSERT INTO streetname VALUES('caselton'); + INSERT INTO streetname VALUES('castello'); + INSERT INTO streetname VALUES('castle ridge'); + INSERT INTO streetname VALUES('castleglen'); + INSERT INTO streetname VALUES('castlemaine'); + INSERT INTO streetname VALUES('cavett'); + INSERT INTO streetname VALUES('caymus'); + INSERT INTO streetname VALUES('cedardale ridge'); + INSERT INTO streetname VALUES('cedarhurst'); + INSERT INTO streetname VALUES('cemkey way'); + INSERT INTO streetname VALUES('cerise'); + INSERT INTO streetname VALUES('chaceview'); + INSERT INTO streetname VALUES('chadsworth'); + INSERT INTO streetname VALUES('chadwell'); + INSERT INTO streetname VALUES('champions crest'); + INSERT INTO streetname VALUES('chandler haven'); + INSERT INTO streetname VALUES('chapel crossing'); + INSERT INTO streetname VALUES('chapel ridge'); + INSERT INTO streetname VALUES('charles crawford'); + INSERT INTO streetname VALUES('charminster'); + INSERT INTO streetname VALUES('chasewind'); + INSERT INTO streetname VALUES('chavel'); + INSERT INTO streetname VALUES('chelsea jade'); + INSERT INTO streetname VALUES('chestnut knoll'); + INSERT INTO streetname VALUES('cheviot'); + INSERT INTO streetname VALUES('chickadee'); + INSERT INTO streetname VALUES('chidley'); + INSERT INTO streetname VALUES('chimney ridge'); + INSERT INTO streetname VALUES('chimney springs'); + INSERT INTO streetname VALUES('chinaberry'); + INSERT INTO streetname VALUES('chinemist'); + INSERT INTO streetname VALUES('chinquapin'); + INSERT INTO streetname VALUES('chiswell'); + INSERT INTO streetname VALUES('christenbury'); + INSERT INTO streetname VALUES('christenbury hills'); + INSERT INTO streetname VALUES('churchill'); + INSERT INTO streetname VALUES('cindy'); + INSERT INTO streetname VALUES('cinnamon teal'); + INSERT INTO streetname VALUES('citadel'); + INSERT INTO streetname VALUES('clare olivia'); + INSERT INTO streetname VALUES('clarke creek'); + INSERT INTO streetname VALUES('clarke ridge'); + INSERT INTO streetname VALUES('clear day'); + INSERT INTO streetname VALUES('clear stream'); + INSERT INTO streetname VALUES('cleve brown'); + INSERT INTO streetname VALUES('cliff cameron'); + INSERT INTO streetname VALUES('cliffvale'); + INSERT INTO streetname VALUES('cloverside'); + INSERT INTO streetname VALUES('clymer'); + INSERT INTO streetname VALUES('coatbridge'); + INSERT INTO streetname VALUES('cobble glen'); + INSERT INTO streetname VALUES('cochran farm'); + INSERT INTO streetname VALUES('cochrane'); + INSERT INTO streetname VALUES('coleridge'); + INSERT INTO streetname VALUES('coleshire'); + INSERT INTO streetname VALUES('collins'); + INSERT INTO streetname VALUES('colvard'); + INSERT INTO streetname VALUES('colvard park'); + INSERT INTO streetname VALUES('condor'); + INSERT INTO streetname VALUES('conner ridge'); + INSERT INTO streetname VALUES('connery'); + INSERT INTO streetname VALUES('cooper run'); + INSERT INTO streetname VALUES('coopers ridge'); + INSERT INTO streetname VALUES('copper hill'); + INSERT INTO streetname VALUES('coppermine'); + INSERT INTO streetname VALUES('cornelia'); + INSERT INTO streetname VALUES('corner'); + INSERT INTO streetname VALUES('cornerstone'); + INSERT INTO streetname VALUES('cottage oaks'); + INSERT INTO streetname VALUES('cougar'); + INSERT INTO streetname VALUES('coves end'); + INSERT INTO streetname VALUES('cragland'); + INSERT INTO streetname VALUES('crail'); + INSERT INTO streetname VALUES('cranberry nook'); + INSERT INTO streetname VALUES('crawford brook'); + INSERT INTO streetname VALUES('crayton'); + INSERT INTO streetname VALUES('creek breeze'); + INSERT INTO streetname VALUES('crescent ridge'); + INSERT INTO streetname VALUES('crescent view'); + INSERT INTO streetname VALUES('cresta'); + INSERT INTO streetname VALUES('crestfield'); + INSERT INTO streetname VALUES('crestland'); + INSERT INTO streetname VALUES('crestwick'); + INSERT INTO streetname VALUES('crisfield'); + INSERT INTO streetname VALUES('crisp wood'); + INSERT INTO streetname VALUES('croft haven'); + INSERT INTO streetname VALUES('crofton springs'); + INSERT INTO streetname VALUES('cross'); + INSERT INTO streetname VALUES('crosspoint center'); + INSERT INTO streetname VALUES('crownvista'); + INSERT INTO streetname VALUES('crystal arms'); + INSERT INTO streetname VALUES('crystal crest'); + INSERT INTO streetname VALUES('crystal leaf'); + INSERT INTO streetname VALUES('cunningham park'); + INSERT INTO streetname VALUES('cypress pond'); + INSERT INTO streetname VALUES('daffodil'); + INSERT INTO streetname VALUES('daisyfield'); + INSERT INTO streetname VALUES('dalecrest'); + INSERT INTO streetname VALUES('dannelly park'); + INSERT INTO streetname VALUES('daphne'); + INSERT INTO streetname VALUES('daria'); + INSERT INTO streetname VALUES('dartmouth'); + INSERT INTO streetname VALUES('datha'); + INSERT INTO streetname VALUES('david cox'); + INSERT INTO streetname VALUES('davis'); + INSERT INTO streetname VALUES('davis crossing'); + INSERT INTO streetname VALUES('davis lake'); + INSERT INTO streetname VALUES('davis ridge'); + INSERT INTO streetname VALUES('dawnmist'); + INSERT INTO streetname VALUES('daybreak'); + INSERT INTO streetname VALUES('dearmon'); + INSERT INTO streetname VALUES('dearview'); + INSERT INTO streetname VALUES('deaton hill'); + INSERT INTO streetname VALUES('deer cross'); + INSERT INTO streetname VALUES('deerton'); + INSERT INTO streetname VALUES('degrasse'); + INSERT INTO streetname VALUES('delamere'); + INSERT INTO streetname VALUES('dellfield'); + INSERT INTO streetname VALUES('dellinger'); + INSERT INTO streetname VALUES('demington'); + INSERT INTO streetname VALUES('denmeade'); + INSERT INTO streetname VALUES('derita'); + INSERT INTO streetname VALUES('derita woods'); + INSERT INTO streetname VALUES('deruyter'); + INSERT INTO streetname VALUES('dervish'); + INSERT INTO streetname VALUES('devas'); + INSERT INTO streetname VALUES('devon croft'); + INSERT INTO streetname VALUES('devonbridge'); + INSERT INTO streetname VALUES('devongate'); + INSERT INTO streetname VALUES('devonhill'); + INSERT INTO streetname VALUES('dewmorn'); + INSERT INTO streetname VALUES('distribution center'); + INSERT INTO streetname VALUES('dominion crest'); + INSERT INTO streetname VALUES('dominion green'); + INSERT INTO streetname VALUES('dominion village'); + INSERT INTO streetname VALUES('dorshire'); + INSERT INTO streetname VALUES('double creek crossing'); + INSERT INTO streetname VALUES('dow'); + INSERT INTO streetname VALUES('downfield wood'); + INSERT INTO streetname VALUES('downing creek'); + INSERT INTO streetname VALUES('driscol'); + INSERT INTO streetname VALUES('driwood'); + INSERT INTO streetname VALUES('dry brook'); + INSERT INTO streetname VALUES('dumont'); + INSERT INTO streetname VALUES('dunblane'); + INSERT INTO streetname VALUES('dunfield'); + INSERT INTO streetname VALUES('dunoon'); + INSERT INTO streetname VALUES('dunslow'); + INSERT INTO streetname VALUES('dunstaff'); + INSERT INTO streetname VALUES('durham'); + INSERT INTO streetname VALUES('durston'); + INSERT INTO streetname VALUES('dusty cedar'); + INSERT INTO streetname VALUES('dusty trail'); + INSERT INTO streetname VALUES('dutchess'); + INSERT INTO streetname VALUES('duxford'); + INSERT INTO streetname VALUES('eagle creek'); + INSERT INTO streetname VALUES('eagles field'); + INSERT INTO streetname VALUES('eargle'); + INSERT INTO streetname VALUES('earlswood'); + INSERT INTO streetname VALUES('early mist'); + INSERT INTO streetname VALUES('earthenware'); + INSERT INTO streetname VALUES('eastfield park'); + INSERT INTO streetname VALUES('eastfield village'); + INSERT INTO streetname VALUES('easy'); + INSERT INTO streetname VALUES('eben'); + INSERT INTO streetname VALUES('edgepine'); + INSERT INTO streetname VALUES('edgewier'); + INSERT INTO streetname VALUES('edinburgh'); + INSERT INTO streetname VALUES('edinmeadow'); + INSERT INTO streetname VALUES('edmonton'); + INSERT INTO streetname VALUES('edwin jones'); + INSERT INTO streetname VALUES('elberon'); + INSERT INTO streetname VALUES('elderslie'); + INSERT INTO streetname VALUES('elementary view'); + INSERT INTO streetname VALUES('elendil'); + INSERT INTO streetname VALUES('elizabeth'); + INSERT INTO streetname VALUES('elm cove'); + INSERT INTO streetname VALUES('elrond'); + INSERT INTO streetname VALUES('elsenham'); + INSERT INTO streetname VALUES('elven'); + INSERT INTO streetname VALUES('emma lynn'); + INSERT INTO streetname VALUES('english setter'); + INSERT INTO streetname VALUES('enoch'); + INSERT INTO streetname VALUES('equipment'); + INSERT INTO streetname VALUES('ernest russell'); + INSERT INTO streetname VALUES('ernie'); + INSERT INTO streetname VALUES('esmeralda'); + INSERT INTO streetname VALUES('evergreen hollow'); + INSERT INTO streetname VALUES('eversfield'); + INSERT INTO streetname VALUES('ewen'); + INSERT INTO streetname VALUES('ewert cut'); + INSERT INTO streetname VALUES('exbury'); + INSERT INTO streetname VALUES('fair grounds park'); + INSERT INTO streetname VALUES('fairbourne'); + INSERT INTO streetname VALUES('fairchase'); + INSERT INTO streetname VALUES('faircreek'); + INSERT INTO streetname VALUES('fairglen'); + INSERT INTO streetname VALUES('fairlea'); + INSERT INTO streetname VALUES('fairmead'); + INSERT INTO streetname VALUES('fairmeadows'); + INSERT INTO streetname VALUES('fairstone'); + INSERT INTO streetname VALUES('fairvista'); + INSERT INTO streetname VALUES('fairway point'); + INSERT INTO streetname VALUES('falconcrest'); + INSERT INTO streetname VALUES('falls ridge'); + INSERT INTO streetname VALUES('falmouth'); + INSERT INTO streetname VALUES('far west'); + INSERT INTO streetname VALUES('farlow'); + INSERT INTO streetname VALUES('farris wheel'); + INSERT INTO streetname VALUES('fawndale'); + INSERT INTO streetname VALUES('feather bend'); + INSERT INTO streetname VALUES('fernledge'); + INSERT INTO streetname VALUES('fernmoss'); + INSERT INTO streetname VALUES('ferrell commons'); + INSERT INTO streetname VALUES('fieldstone'); + INSERT INTO streetname VALUES('fillian'); + INSERT INTO streetname VALUES('fincher'); + INSERT INTO streetname VALUES('foggy meadow'); + INSERT INTO streetname VALUES('fordyce'); + INSERT INTO streetname VALUES('forest grove'); + INSERT INTO streetname VALUES('forest path'); + INSERT INTO streetname VALUES('forestridge commons'); + INSERT INTO streetname VALUES('forestrock'); + INSERT INTO streetname VALUES('fortunes ridge'); + INSERT INTO streetname VALUES('founders club'); + INSERT INTO streetname VALUES('fountaingrass'); + INSERT INTO streetname VALUES('fox chase'); + INSERT INTO streetname VALUES('fox glen'); + INSERT INTO streetname VALUES('fox hill'); + INSERT INTO streetname VALUES('fox point'); + INSERT INTO streetname VALUES('fox trot'); + INSERT INTO streetname VALUES('foxbriar'); + INSERT INTO streetname VALUES('frank little'); + INSERT INTO streetname VALUES('franzia'); + INSERT INTO streetname VALUES('french woods'); + INSERT INTO streetname VALUES('frostmoor'); + INSERT INTO streetname VALUES('frye'); + INSERT INTO streetname VALUES('furlong'); + INSERT INTO streetname VALUES('galena view'); + INSERT INTO streetname VALUES('gallery pointe'); + INSERT INTO streetname VALUES('gammon'); + INSERT INTO streetname VALUES('garden grove'); + INSERT INTO streetname VALUES('gardendale'); + INSERT INTO streetname VALUES('garganey'); + INSERT INTO streetname VALUES('garnet field'); + INSERT INTO streetname VALUES('garrison'); + INSERT INTO streetname VALUES('garvin'); + INSERT INTO streetname VALUES('garvis'); + INSERT INTO streetname VALUES('gaskill'); + INSERT INTO streetname VALUES('gemstone'); + INSERT INTO streetname VALUES('gibbon'); + INSERT INTO streetname VALUES('gibbon terrace'); + INSERT INTO streetname VALUES('gibbons link'); + INSERT INTO streetname VALUES('gillman'); + INSERT INTO streetname VALUES('gladwood'); + INSERT INTO streetname VALUES('gladwyne'); + INSERT INTO streetname VALUES('glamorgan'); + INSERT INTO streetname VALUES('glaze'); + INSERT INTO streetname VALUES('glen brook'); + INSERT INTO streetname VALUES('glen cove'); + INSERT INTO streetname VALUES('glen hope'); + INSERT INTO streetname VALUES('glen manor'); + INSERT INTO streetname VALUES('glen olden'); + INSERT INTO streetname VALUES('glencairn'); + INSERT INTO streetname VALUES('glendock'); + INSERT INTO streetname VALUES('glenolden'); + INSERT INTO streetname VALUES('glenover'); + INSERT INTO streetname VALUES('glenshire'); + INSERT INTO streetname VALUES('glenstone'); + INSERT INTO streetname VALUES('gold dust'); + INSERT INTO streetname VALUES('golden pond'); + INSERT INTO streetname VALUES('goldenblush'); + INSERT INTO streetname VALUES('goldenfield'); + INSERT INTO streetname VALUES('goose landing'); + INSERT INTO streetname VALUES('gorham gate'); + INSERT INTO streetname VALUES('grabill'); + INSERT INTO streetname VALUES('graburns ford'); + INSERT INTO streetname VALUES('graham'); + INSERT INTO streetname VALUES('grahamson'); + INSERT INTO streetname VALUES('granard'); + INSERT INTO streetname VALUES('grand teton'); + INSERT INTO streetname VALUES('grande heights'); + INSERT INTO streetname VALUES('grandeur'); + INSERT INTO streetname VALUES('granite creek'); + INSERT INTO streetname VALUES('grasset'); + INSERT INTO streetname VALUES('graypark'); + INSERT INTO streetname VALUES('grays ridge'); + INSERT INTO streetname VALUES('great bear'); + INSERT INTO streetname VALUES('green clover'); + INSERT INTO streetname VALUES('green hedge'); + INSERT INTO streetname VALUES('green meadow'); + INSERT INTO streetname VALUES('green pasture'); + INSERT INTO streetname VALUES('greene'); + INSERT INTO streetname VALUES('greenloch'); + INSERT INTO streetname VALUES('greenock ridge'); + INSERT INTO streetname VALUES('greenware'); + INSERT INTO streetname VALUES('greenway village'); + INSERT INTO streetname VALUES('grenelefe village'); + INSERT INTO streetname VALUES('grey dogwood'); + INSERT INTO streetname VALUES('greyhound'); + INSERT INTO streetname VALUES('greylock ridge'); + INSERT INTO streetname VALUES('grosbeak'); + INSERT INTO streetname VALUES('grove'); + INSERT INTO streetname VALUES('groveton'); + INSERT INTO streetname VALUES('groveview'); + INSERT INTO streetname VALUES('hackberry creek'); + INSERT INTO streetname VALUES('hackberry grove'); + INSERT INTO streetname VALUES('hackett'); + INSERT INTO streetname VALUES('haddington'); + INSERT INTO streetname VALUES('hagler'); + INSERT INTO streetname VALUES('halcott'); + INSERT INTO streetname VALUES('half dome'); + INSERT INTO streetname VALUES('hallam'); + INSERT INTO streetname VALUES('hamilton russell'); + INSERT INTO streetname VALUES('hampton place'); + INSERT INTO streetname VALUES('hankins'); + INSERT INTO streetname VALUES('harburn forest'); + INSERT INTO streetname VALUES('harringham'); + INSERT INTO streetname VALUES('harrington woods'); + INSERT INTO streetname VALUES('harris corners'); + INSERT INTO streetname VALUES('harris cove'); + INSERT INTO streetname VALUES('harris glen'); + INSERT INTO streetname VALUES('harris hill'); + INSERT INTO streetname VALUES('harris oak'); + INSERT INTO streetname VALUES('harris pointe'); + INSERT INTO streetname VALUES('harris pond'); + INSERT INTO streetname VALUES('harris ridge'); + INSERT INTO streetname VALUES('harris technology'); + INSERT INTO streetname VALUES('harris woods'); + INSERT INTO streetname VALUES('hartfield downs'); + INSERT INTO streetname VALUES('hattie little'); + INSERT INTO streetname VALUES('hatwynn'); + INSERT INTO streetname VALUES('hawkins'); + INSERT INTO streetname VALUES('hawksnest'); + INSERT INTO streetname VALUES('haybridge'); + INSERT INTO streetname VALUES('hayden'); + INSERT INTO streetname VALUES('hazelcroft'); + INSERT INTO streetname VALUES('hazlitt'); + INSERT INTO streetname VALUES('hazy valley'); + INSERT INTO streetname VALUES('hearst'); + INSERT INTO streetname VALUES('heathcrest'); + INSERT INTO streetname VALUES('heathcroft'); + INSERT INTO streetname VALUES('hedge maple'); + INSERT INTO streetname VALUES('hedgecrest'); + INSERT INTO streetname VALUES('hedingham'); + INSERT INTO streetname VALUES('heman'); + INSERT INTO streetname VALUES('henderson'); + INSERT INTO streetname VALUES('henderson oaks'); + INSERT INTO streetname VALUES('henderson valley'); + INSERT INTO streetname VALUES('hendry'); + INSERT INTO streetname VALUES('heritage hills'); + INSERT INTO streetname VALUES('heritage woods'); + INSERT INTO streetname VALUES('heron cove'); + INSERT INTO streetname VALUES('heron glen'); + INSERT INTO streetname VALUES('hewitt'); + INSERT INTO streetname VALUES('hey rock'); + INSERT INTO streetname VALUES('heysham'); + INSERT INTO streetname VALUES('hickory cove'); + INSERT INTO streetname VALUES('hidden meadow'); + INSERT INTO streetname VALUES('high glen'); + INSERT INTO streetname VALUES('high laurel'); + INSERT INTO streetname VALUES('high valley'); + INSERT INTO streetname VALUES('highcroft'); + INSERT INTO streetname VALUES('highland'); + INSERT INTO streetname VALUES('highland commons'); + INSERT INTO streetname VALUES('highland creek'); + INSERT INTO streetname VALUES('highland glen'); + INSERT INTO streetname VALUES('highland park'); + INSERT INTO streetname VALUES('highlander'); + INSERT INTO streetname VALUES('highstream'); + INSERT INTO streetname VALUES('hilltop'); + INSERT INTO streetname VALUES('hobbitshire'); + INSERT INTO streetname VALUES('hoffman'); + INSERT INTO streetname VALUES('hogans way'); + INSERT INTO streetname VALUES('holbert'); + INSERT INTO streetname VALUES('hollow ridge'); + INSERT INTO streetname VALUES('holly vista'); + INSERT INTO streetname VALUES('hollywood'); + INSERT INTO streetname VALUES('hoover'); + INSERT INTO streetname VALUES('hopkins'); + INSERT INTO streetname VALUES('horace mann'); + INSERT INTO streetname VALUES('hornbeam'); + INSERT INTO streetname VALUES('horse pasture'); + INSERT INTO streetname VALUES('hosta'); + INSERT INTO streetname VALUES('howard'); + INSERT INTO streetname VALUES('hubbard'); + INSERT INTO streetname VALUES('hubbard falls'); + INSERT INTO streetname VALUES('hubbard woods'); + INSERT INTO streetname VALUES('hucks'); + INSERT INTO streetname VALUES('hunters creek'); + INSERT INTO streetname VALUES('hunters pointe'); + INSERT INTO streetname VALUES('hunters spring'); + INSERT INTO streetname VALUES('hunters whip'); + INSERT INTO streetname VALUES('huntmeadow'); + INSERT INTO streetname VALUES('hutchison mcdonald'); + INSERT INTO streetname VALUES('ingleton'); + INSERT INTO streetname VALUES('insdale'); + INSERT INTO streetname VALUES('interstate 85 service'); + INSERT INTO streetname VALUES('iola'); + INSERT INTO streetname VALUES('iredell'); + INSERT INTO streetname VALUES('iron brigade'); + INSERT INTO streetname VALUES('irwin valley'); + INSERT INTO streetname VALUES('irwin wood'); + INSERT INTO streetname VALUES('ivy brook'); + INSERT INTO streetname VALUES('ivy ridge'); + INSERT INTO streetname VALUES('jack russell'); + INSERT INTO streetname VALUES('jackson'); + INSERT INTO streetname VALUES('jacob martin'); + INSERT INTO streetname VALUES('jamison'); + INSERT INTO streetname VALUES('jane'); + INSERT INTO streetname VALUES('jaspar crest'); + INSERT INTO streetname VALUES('jessica'); + INSERT INTO streetname VALUES('jimmy oehler'); + INSERT INTO streetname VALUES('jocelyn'); + INSERT INTO streetname VALUES('johnston mill'); + INSERT INTO streetname VALUES('johnston oehler'); + INSERT INTO streetname VALUES('judal'); + INSERT INTO streetname VALUES('junipeous'); + INSERT INTO streetname VALUES('juniper'); + INSERT INTO streetname VALUES('juniperus'); + INSERT INTO streetname VALUES('kalispell'); + INSERT INTO streetname VALUES('karylsturn'); + INSERT INTO streetname VALUES('katelyn'); + INSERT INTO streetname VALUES('kayron'); + INSERT INTO streetname VALUES('keaton'); + INSERT INTO streetname VALUES('keble'); + INSERT INTO streetname VALUES('keels'); + INSERT INTO streetname VALUES('keith'); + INSERT INTO streetname VALUES('keithwood'); + INSERT INTO streetname VALUES('kelden walker'); + INSERT INTO streetname VALUES('kelsey emma'); + INSERT INTO streetname VALUES('kendrick'); + INSERT INTO streetname VALUES('kenmont'); + INSERT INTO streetname VALUES('kennerly cove'); + INSERT INTO streetname VALUES('kenninghall'); + INSERT INTO streetname VALUES('kent village'); + INSERT INTO streetname VALUES('kestral ridge'); + INSERT INTO streetname VALUES('kestrel'); + INSERT INTO streetname VALUES('kilmartin'); + INSERT INTO streetname VALUES('kilty'); + INSERT INTO streetname VALUES('kinglet'); + INSERT INTO streetname VALUES('kingsland'); + INSERT INTO streetname VALUES('kingsnorth'); + INSERT INTO streetname VALUES('kinsmore'); + INSERT INTO streetname VALUES('kirkgard'); + INSERT INTO streetname VALUES('kirkmont'); + INSERT INTO streetname VALUES('knightsgate'); + INSERT INTO streetname VALUES('kobuk'); + INSERT INTO streetname VALUES('kotlik'); + INSERT INTO streetname VALUES('kotz'); + INSERT INTO streetname VALUES('kyndall walk'); + INSERT INTO streetname VALUES('laborde'); + INSERT INTO streetname VALUES('lady bank'); + INSERT INTO streetname VALUES('lagrande'); + INSERT INTO streetname VALUES('lake'); + INSERT INTO streetname VALUES('lakeridge commons'); + INSERT INTO streetname VALUES('lakeview'); + INSERT INTO streetname VALUES('lakewood edge'); + INSERT INTO streetname VALUES('lakota'); + INSERT INTO streetname VALUES('lambrook'); + INSERT INTO streetname VALUES('lampkin'); + INSERT INTO streetname VALUES('lampkin park'); + INSERT INTO streetname VALUES('langham'); + INSERT INTO streetname VALUES('lanzerac manor'); + INSERT INTO streetname VALUES('larkmead forest'); + INSERT INTO streetname VALUES('lattice'); + INSERT INTO streetname VALUES('laurel crest'); + INSERT INTO streetname VALUES('laurel ridge'); + INSERT INTO streetname VALUES('laurel run'); + INSERT INTO streetname VALUES('laurenfield'); + INSERT INTO streetname VALUES('laveta'); + INSERT INTO streetname VALUES('lazy day'); + INSERT INTO streetname VALUES('leawood run'); + INSERT INTO streetname VALUES('lee marie'); + INSERT INTO streetname VALUES('legacy lake'); + INSERT INTO streetname VALUES('legacy park'); + INSERT INTO streetname VALUES('legato'); + INSERT INTO streetname VALUES('legolas'); + INSERT INTO streetname VALUES('leigh glen'); + INSERT INTO streetname VALUES('lence'); + INSERT INTO streetname VALUES('lenox hill'); + INSERT INTO streetname VALUES('leonine'); + INSERT INTO streetname VALUES('leslie'); + INSERT INTO streetname VALUES('lester hill'); + INSERT INTO streetname VALUES('levisey'); + INSERT INTO streetname VALUES('liberty bell'); + INSERT INTO streetname VALUES('linden berry'); + INSERT INTO streetname VALUES('lisbon'); + INSERT INTO streetname VALUES('little stoney'); + INSERT INTO streetname VALUES('livengood'); + INSERT INTO streetname VALUES('lochway'); + INSERT INTO streetname VALUES('lockman'); + INSERT INTO streetname VALUES('loganville'); + INSERT INTO streetname VALUES('lone tree'); + INSERT INTO streetname VALUES('long creek park'); + INSERT INTO streetname VALUES('long forest'); + INSERT INTO streetname VALUES('looking glass'); + INSERT INTO streetname VALUES('lookout point'); + INSERT INTO streetname VALUES('lowen'); + INSERT INTO streetname VALUES('lusby'); + INSERT INTO streetname VALUES('lyleton'); + INSERT INTO streetname VALUES('lynn lee'); + INSERT INTO streetname VALUES('lynnewood glen'); + INSERT INTO streetname VALUES('machrie'); + INSERT INTO streetname VALUES('mackinac'); + INSERT INTO streetname VALUES('maddox'); + INSERT INTO streetname VALUES('madison park'); + INSERT INTO streetname VALUES('mallard'); + INSERT INTO streetname VALUES('mallard cove'); + INSERT INTO streetname VALUES('mallard forest'); + INSERT INTO streetname VALUES('mallard grove'); + INSERT INTO streetname VALUES('mallard hill'); + INSERT INTO streetname VALUES('mallard park'); + INSERT INTO streetname VALUES('mallard ridge'); + INSERT INTO streetname VALUES('mallard view'); + INSERT INTO streetname VALUES('manbey'); + INSERT INTO streetname VALUES('manning'); + INSERT INTO streetname VALUES('mantario'); + INSERT INTO streetname VALUES('maple'); + INSERT INTO streetname VALUES('maple cove'); + INSERT INTO streetname VALUES('maple park'); + INSERT INTO streetname VALUES('marathon hill'); + INSERT INTO streetname VALUES('marbury'); + INSERT INTO streetname VALUES('marett'); + INSERT INTO streetname VALUES('marigold'); + INSERT INTO streetname VALUES('marionwood'); + INSERT INTO streetname VALUES('marshbank'); + INSERT INTO streetname VALUES('mason'); + INSERT INTO streetname VALUES('mayapple'); + INSERT INTO streetname VALUES('maylandia'); + INSERT INTO streetname VALUES('mayspring'); + INSERT INTO streetname VALUES('mcadam'); + INSERT INTO streetname VALUES('mcchesney'); + INSERT INTO streetname VALUES('mccurdy'); + INSERT INTO streetname VALUES('mcgrath'); + INSERT INTO streetname VALUES('mckendree'); + INSERT INTO streetname VALUES('mclaughlin'); + INSERT INTO streetname VALUES('mctaggart'); + INSERT INTO streetname VALUES('meadow green'); + INSERT INTO streetname VALUES('meadow knoll'); + INSERT INTO streetname VALUES('meadow post'); + INSERT INTO streetname VALUES('meadowmont'); + INSERT INTO streetname VALUES('meadowmont view'); + INSERT INTO streetname VALUES('meadowview hills'); + INSERT INTO streetname VALUES('melshire'); + INSERT INTO streetname VALUES('melstrand'); + INSERT INTO streetname VALUES('mentone'); + INSERT INTO streetname VALUES('meridale crossing'); + INSERT INTO streetname VALUES('merion hills'); + INSERT INTO streetname VALUES('merlot'); + INSERT INTO streetname VALUES('mersham'); + INSERT INTO streetname VALUES('metromont'); + INSERT INTO streetname VALUES('metromont industrial'); + INSERT INTO streetname VALUES('michaw'); + INSERT INTO streetname VALUES('milhaven'); + INSERT INTO streetname VALUES('milhof'); + INSERT INTO streetname VALUES('millstream ridge'); + INSERT INTO streetname VALUES('mineral ridge'); + INSERT INTO streetname VALUES('mint thistle'); + INSERT INTO streetname VALUES('mintleaf'); + INSERT INTO streetname VALUES('mintvale'); + INSERT INTO streetname VALUES('misty'); + INSERT INTO streetname VALUES('misty arbor'); + INSERT INTO streetname VALUES('misty creek'); + INSERT INTO streetname VALUES('misty oaks'); + INSERT INTO streetname VALUES('misty wood'); + INSERT INTO streetname VALUES('mitzi deborah'); + INSERT INTO streetname VALUES('mobile'); + INSERT INTO streetname VALUES('molly elizabeth'); + INSERT INTO streetname VALUES('monmouth'); + INSERT INTO streetname VALUES('montrose'); + INSERT INTO streetname VALUES('moonlight'); + INSERT INTO streetname VALUES('moose'); + INSERT INTO streetname VALUES('morning dew'); + INSERT INTO streetname VALUES('morningsong'); + INSERT INTO streetname VALUES('morningview'); + INSERT INTO streetname VALUES('morsey'); + INSERT INTO streetname VALUES('moss glen'); + INSERT INTO streetname VALUES('mossy bank'); + INSERT INTO streetname VALUES('motor sport'); + INSERT INTO streetname VALUES('mountain laurel'); + INSERT INTO streetname VALUES('mourning dove'); + INSERT INTO streetname VALUES('mozart'); + INSERT INTO streetname VALUES('munsing'); + INSERT INTO streetname VALUES('murray'); + INSERT INTO streetname VALUES('nathan'); + INSERT INTO streetname VALUES('netherhall'); + INSERT INTO streetname VALUES('netherton'); + INSERT INTO streetname VALUES('neuhoff'); + INSERT INTO streetname VALUES('nevin'); + INSERT INTO streetname VALUES('nevin brook'); + INSERT INTO streetname VALUES('nevin glen'); + INSERT INTO streetname VALUES('nevin place'); + INSERT INTO streetname VALUES('new england'); + INSERT INTO streetname VALUES('new house'); + INSERT INTO streetname VALUES('newbary'); + INSERT INTO streetname VALUES('newchurch'); + INSERT INTO streetname VALUES('newfane'); + INSERT INTO streetname VALUES('newgard'); + INSERT INTO streetname VALUES('nicholas'); + INSERT INTO streetname VALUES('nicole'); + INSERT INTO streetname VALUES('nobility'); + INSERT INTO streetname VALUES('norcroft'); + INSERT INTO streetname VALUES('northridge'); + INSERT INTO streetname VALUES('northside'); + INSERT INTO streetname VALUES('northwoods business'); + INSERT INTO streetname VALUES('norway'); + INSERT INTO streetname VALUES('nottinghill'); + INSERT INTO streetname VALUES('numenore'); + INSERT INTO streetname VALUES('nyewood'); + INSERT INTO streetname VALUES('oak'); + INSERT INTO streetname VALUES('oak cove'); + INSERT INTO streetname VALUES('oak pasture'); + INSERT INTO streetname VALUES('oakburn'); + INSERT INTO streetname VALUES('oakwinds'); + INSERT INTO streetname VALUES('oakwood'); + INSERT INTO streetname VALUES('obrien'); + INSERT INTO streetname VALUES('ocala'); + INSERT INTO streetname VALUES('old bridge'); + INSERT INTO streetname VALUES('old fox'); + INSERT INTO streetname VALUES('old potters'); + INSERT INTO streetname VALUES('old statesville'); + INSERT INTO streetname VALUES('old steine'); + INSERT INTO streetname VALUES('old stoney creek'); + INSERT INTO streetname VALUES('old sugar creek'); + INSERT INTO streetname VALUES('old timber'); + INSERT INTO streetname VALUES('old wagon'); + INSERT INTO streetname VALUES('old willow'); + INSERT INTO streetname VALUES('oldenway'); + INSERT INTO streetname VALUES('oneida'); + INSERT INTO streetname VALUES('ontario'); + INSERT INTO streetname VALUES('oriole'); + INSERT INTO streetname VALUES('orofino'); + INSERT INTO streetname VALUES('orr'); + INSERT INTO streetname VALUES('osage'); + INSERT INTO streetname VALUES('osceola'); + INSERT INTO streetname VALUES('osprey knoll'); + INSERT INTO streetname VALUES('oxford hill'); + INSERT INTO streetname VALUES('painted fern'); + INSERT INTO streetname VALUES('painted pony'); + INSERT INTO streetname VALUES('paisley'); + INSERT INTO streetname VALUES('pale moss'); + INSERT INTO streetname VALUES('palladium'); + INSERT INTO streetname VALUES('palmutum'); + INSERT INTO streetname VALUES('palustris'); + INSERT INTO streetname VALUES('panglemont'); + INSERT INTO streetname VALUES('panther'); + INSERT INTO streetname VALUES('panthersville'); + INSERT INTO streetname VALUES('paper whites'); + INSERT INTO streetname VALUES('park'); + INSERT INTO streetname VALUES('parker green'); + INSERT INTO streetname VALUES('parkhouse'); + INSERT INTO streetname VALUES('passour ridge'); + INSERT INTO streetname VALUES('pasture view'); + INSERT INTO streetname VALUES('patricia ann'); + INSERT INTO streetname VALUES('patton'); + INSERT INTO streetname VALUES('patton ridge'); + INSERT INTO streetname VALUES('pawpaw'); + INSERT INTO streetname VALUES('peach'); + INSERT INTO streetname VALUES('peakwood'); + INSERT INTO streetname VALUES('pebble creek'); + INSERT INTO streetname VALUES('pecan cove'); + INSERT INTO streetname VALUES('pedigree'); + INSERT INTO streetname VALUES('pelorus'); + INSERT INTO streetname VALUES('penmore'); + INSERT INTO streetname VALUES('pensfold'); + INSERT INTO streetname VALUES('pepperstone'); + INSERT INTO streetname VALUES('peregrine'); + INSERT INTO streetname VALUES('periwinkle'); + INSERT INTO streetname VALUES('perkins'); + INSERT INTO streetname VALUES('pete brown'); + INSERT INTO streetname VALUES('phillips'); + INSERT INTO streetname VALUES('pickway'); + INSERT INTO streetname VALUES('piercy woods'); + INSERT INTO streetname VALUES('pierpoint'); + INSERT INTO streetname VALUES('pine'); + INSERT INTO streetname VALUES('pine branch'); + INSERT INTO streetname VALUES('pine meadow'); + INSERT INTO streetname VALUES('pineleaf'); + INSERT INTO streetname VALUES('pinewood'); + INSERT INTO streetname VALUES('pintail'); + INSERT INTO streetname VALUES('pipestone'); + INSERT INTO streetname VALUES('placer maple'); + INSERT INTO streetname VALUES('plover'); + INSERT INTO streetname VALUES('plum'); + INSERT INTO streetname VALUES('po box'); + INSERT INTO streetname VALUES('pochard'); + INSERT INTO streetname VALUES('pointview'); + INSERT INTO streetname VALUES('polk and white'); + INSERT INTO streetname VALUES('pond valley'); + INSERT INTO streetname VALUES('pondridge'); + INSERT INTO streetname VALUES('pope farm'); + INSERT INTO streetname VALUES('poplar grove'); + INSERT INTO streetname VALUES('poplar springs'); + INSERT INTO streetname VALUES('portola'); + INSERT INTO streetname VALUES('potters glen'); + INSERT INTO streetname VALUES('powatan'); + INSERT INTO streetname VALUES('prairie valley'); + INSERT INTO streetname VALUES('prescott'); + INSERT INTO streetname VALUES('presmann'); + INSERT INTO streetname VALUES('prestigious'); + INSERT INTO streetname VALUES('princess'); + INSERT INTO streetname VALUES('prosperity'); + INSERT INTO streetname VALUES('prosperity church'); + INSERT INTO streetname VALUES('prosperity commons'); + INSERT INTO streetname VALUES('prosperity park'); + INSERT INTO streetname VALUES('prosperity point'); + INSERT INTO streetname VALUES('prosperity ridge'); + INSERT INTO streetname VALUES('prosperity view'); + INSERT INTO streetname VALUES('purple finch'); + INSERT INTO streetname VALUES('quail'); + INSERT INTO streetname VALUES('queensbury'); + INSERT INTO streetname VALUES('quinn'); + INSERT INTO streetname VALUES('racine'); + INSERT INTO streetname VALUES('radbourne'); + INSERT INTO streetname VALUES('raddington'); + INSERT INTO streetname VALUES('raku'); + INSERT INTO streetname VALUES('rancliffe'); + INSERT INTO streetname VALUES('ravencrest'); + INSERT INTO streetname VALUES('reames'); + INSERT INTO streetname VALUES('rebecca run'); + INSERT INTO streetname VALUES('red bluff'); + INSERT INTO streetname VALUES('red clay'); + INSERT INTO streetname VALUES('red clover'); + INSERT INTO streetname VALUES('red rose'); + INSERT INTO streetname VALUES('red shed'); + INSERT INTO streetname VALUES('red tail'); + INSERT INTO streetname VALUES('redbridge'); + INSERT INTO streetname VALUES('redstart'); + INSERT INTO streetname VALUES('redstone view'); + INSERT INTO streetname VALUES('reedmont'); + INSERT INTO streetname VALUES('reeves'); + INSERT INTO streetname VALUES('regal'); + INSERT INTO streetname VALUES('reinbeck'); + INSERT INTO streetname VALUES('retriever'); + INSERT INTO streetname VALUES('ribbonwalk'); + INSERT INTO streetname VALUES('richardson park'); + INSERT INTO streetname VALUES('richfield'); + INSERT INTO streetname VALUES('riddings'); + INSERT INTO streetname VALUES('ridge'); + INSERT INTO streetname VALUES('ridge cliff'); + INSERT INTO streetname VALUES('ridge path'); + INSERT INTO streetname VALUES('ridge peak'); + INSERT INTO streetname VALUES('ridgefield'); + INSERT INTO streetname VALUES('ridgeline'); + INSERT INTO streetname VALUES('ridgeview commons'); + INSERT INTO streetname VALUES('riley'); + INSERT INTO streetname VALUES('riley woods'); + INSERT INTO streetname VALUES('rillet'); + INSERT INTO streetname VALUES('rindle'); + INSERT INTO streetname VALUES('rivendell'); + INSERT INTO streetname VALUES('robin'); + INSERT INTO streetname VALUES('robins nest'); + INSERT INTO streetname VALUES('robur'); + INSERT INTO streetname VALUES('robyns glen'); + INSERT INTO streetname VALUES('rock stream'); + INSERT INTO streetname VALUES('rockwell'); + INSERT INTO streetname VALUES('rockwell church'); + INSERT INTO streetname VALUES('rocky brook'); + INSERT INTO streetname VALUES('rocky ford club'); + INSERT INTO streetname VALUES('rotary'); + INSERT INTO streetname VALUES('rouda'); + INSERT INTO streetname VALUES('royal bluff'); + INSERT INTO streetname VALUES('royal celadon'); + INSERT INTO streetname VALUES('rubin lura'); + INSERT INTO streetname VALUES('runswyck'); + INSERT INTO streetname VALUES('ruth ferrell'); + INSERT INTO streetname VALUES('ruth polk'); + INSERT INTO streetname VALUES('ryan jay'); + INSERT INTO streetname VALUES('sackett'); + INSERT INTO streetname VALUES('saddle pace'); + INSERT INTO streetname VALUES('saddle run'); + INSERT INTO streetname VALUES('saddle trail'); + INSERT INTO streetname VALUES('saguaro'); + INSERT INTO streetname VALUES('saint audrey'); + INSERT INTO streetname VALUES('saint bernard'); + INSERT INTO streetname VALUES('saint frances'); + INSERT INTO streetname VALUES('sam roper'); + INSERT INTO streetname VALUES('samara'); + INSERT INTO streetname VALUES('sanders creek'); + INSERT INTO streetname VALUES('saquache'); + INSERT INTO streetname VALUES('sarnia'); + INSERT INTO streetname VALUES('savannah springs'); + INSERT INTO streetname VALUES('sawgrass ridge'); + INSERT INTO streetname VALUES('saxonbury'); + INSERT INTO streetname VALUES('scotch moss'); + INSERT INTO streetname VALUES('seasons'); + INSERT INTO streetname VALUES('serenity'); + INSERT INTO streetname VALUES('seths'); + INSERT INTO streetname VALUES('shadow lawn'); + INSERT INTO streetname VALUES('shadow oaks'); + INSERT INTO streetname VALUES('shadow pine'); + INSERT INTO streetname VALUES('shadyside'); + INSERT INTO streetname VALUES('shallow oak'); + INSERT INTO streetname VALUES('shelley'); + INSERT INTO streetname VALUES('shining oak'); + INSERT INTO streetname VALUES('ship'); + INSERT INTO streetname VALUES('shore haven'); + INSERT INTO streetname VALUES('shuman'); + INSERT INTO streetname VALUES('sidney'); + INSERT INTO streetname VALUES('silver birch'); + INSERT INTO streetname VALUES('silvermere'); + INSERT INTO streetname VALUES('simonton'); + INSERT INTO streetname VALUES('singing hills'); + INSERT INTO streetname VALUES('singing oak'); + INSERT INTO streetname VALUES('sipes'); + INSERT INTO streetname VALUES('six point'); + INSERT INTO streetname VALUES('skycrest'); + INSERT INTO streetname VALUES('skyline'); + INSERT INTO streetname VALUES('small'); + INSERT INTO streetname VALUES('smith corners'); + INSERT INTO streetname VALUES('smithwood'); + INSERT INTO streetname VALUES('snow hill'); + INSERT INTO streetname VALUES('soapstone'); + INSERT INTO streetname VALUES('sobeck'); + INSERT INTO streetname VALUES('socata'); + INSERT INTO streetname VALUES('solace'); + INSERT INTO streetname VALUES('solway'); + INSERT INTO streetname VALUES('song sparrow'); + INSERT INTO streetname VALUES('sorrento'); + INSERT INTO streetname VALUES('spector'); + INSERT INTO streetname VALUES('spin drift'); + INSERT INTO streetname VALUES('spring crest'); + INSERT INTO streetname VALUES('spring lee'); + INSERT INTO streetname VALUES('spring park'); + INSERT INTO streetname VALUES('spring terrace'); + INSERT INTO streetname VALUES('spring trace'); + INSERT INTO streetname VALUES('springhaven'); + INSERT INTO streetname VALUES('squirrel trail'); + INSERT INTO streetname VALUES('stardust'); + INSERT INTO streetname VALUES('stargaze'); + INSERT INTO streetname VALUES('starita'); + INSERT INTO streetname VALUES('starmount'); + INSERT INTO streetname VALUES('statesville'); + INSERT INTO streetname VALUES('steed'); + INSERT INTO streetname VALUES('steelewood'); + INSERT INTO streetname VALUES('steepleglen'); + INSERT INTO streetname VALUES('stephens farm'); + INSERT INTO streetname VALUES('stewarton'); + INSERT INTO streetname VALUES('stone park'); + INSERT INTO streetname VALUES('stonebrook'); + INSERT INTO streetname VALUES('stonefield'); + INSERT INTO streetname VALUES('stoneglen'); + INSERT INTO streetname VALUES('stonemarsh'); + INSERT INTO streetname VALUES('stoney garden'); + INSERT INTO streetname VALUES('stoney run'); + INSERT INTO streetname VALUES('stoney valley'); + INSERT INTO streetname VALUES('stoneykirk'); + INSERT INTO streetname VALUES('stream bank'); + INSERT INTO streetname VALUES('stream ridge'); + INSERT INTO streetname VALUES('suburban'); + INSERT INTO streetname VALUES('suffield'); + INSERT INTO streetname VALUES('sugar creek'); + INSERT INTO streetname VALUES('sugarberry'); + INSERT INTO streetname VALUES('sugarstone'); + INSERT INTO streetname VALUES('summer creek'); + INSERT INTO streetname VALUES('summer valley'); + INSERT INTO streetname VALUES('summercrest'); + INSERT INTO streetname VALUES('summercroft'); + INSERT INTO streetname VALUES('summerford'); + INSERT INTO streetname VALUES('summergold'); + INSERT INTO streetname VALUES('sunbeam'); + INSERT INTO streetname VALUES('sunbridge'); + INSERT INTO streetname VALUES('sunpath'); + INSERT INTO streetname VALUES('sunset'); + INSERT INTO streetname VALUES('sunset ridge'); + INSERT INTO streetname VALUES('sunstone'); + INSERT INTO streetname VALUES('suntrace'); + INSERT INTO streetname VALUES('sunwalk'); + INSERT INTO streetname VALUES('sutters hill'); + INSERT INTO streetname VALUES('suttonview'); + INSERT INTO streetname VALUES('swallow tail'); + INSERT INTO streetname VALUES('swanston'); + INSERT INTO streetname VALUES('sweet grove'); + INSERT INTO streetname VALUES('sweet rose'); + INSERT INTO streetname VALUES('sweetbriar ridge'); + INSERT INTO streetname VALUES('sweetfield'); + INSERT INTO streetname VALUES('sydney overlook'); + INSERT INTO streetname VALUES('sylvan'); + INSERT INTO streetname VALUES('symphony woods'); + INSERT INTO streetname VALUES('tallia'); + INSERT INTO streetname VALUES('tallu'); + INSERT INTO streetname VALUES('talwyn'); + INSERT INTO streetname VALUES('tanager'); + INSERT INTO streetname VALUES('tanager park'); + INSERT INTO streetname VALUES('tangley'); + INSERT INTO streetname VALUES('taranasay'); + INSERT INTO streetname VALUES('tarby'); + INSERT INTO streetname VALUES('tarland'); + INSERT INTO streetname VALUES('tarpway'); + INSERT INTO streetname VALUES('tauten'); + INSERT INTO streetname VALUES('taymouth'); + INSERT INTO streetname VALUES('ten trees'); + INSERT INTO streetname VALUES('terrace view'); + INSERT INTO streetname VALUES('terrier'); + INSERT INTO streetname VALUES('tesh'); + INSERT INTO streetname VALUES('teton'); + INSERT INTO streetname VALUES('tewkesbury'); + INSERT INTO streetname VALUES('thelema'); + INSERT INTO streetname VALUES('thistle bloom'); + INSERT INTO streetname VALUES('thistledown'); + INSERT INTO streetname VALUES('thomas ridge'); + INSERT INTO streetname VALUES('thornbrook'); + INSERT INTO streetname VALUES('tifton grass'); + INSERT INTO streetname VALUES('tigerton'); + INSERT INTO streetname VALUES('tomsie efird'); + INSERT INTO streetname VALUES('tor'); + INSERT INTO streetname VALUES('torphin'); + INSERT INTO streetname VALUES('torrence'); + INSERT INTO streetname VALUES('towering pine'); + INSERT INTO streetname VALUES('towhee'); + INSERT INTO streetname VALUES('toxaway'); + INSERT INTO streetname VALUES('tracy glenn'); + INSERT INTO streetname VALUES('tradition view'); + INSERT INTO streetname VALUES('trailer'); + INSERT INTO streetname VALUES('transport'); + INSERT INTO streetname VALUES('trehurst'); + INSERT INTO streetname VALUES('trexler'); + INSERT INTO streetname VALUES('trillium fields'); + INSERT INTO streetname VALUES('trimbach'); + INSERT INTO streetname VALUES('tucker'); + INSERT INTO streetname VALUES('tullamore'); + INSERT INTO streetname VALUES('tullock creek'); + INSERT INTO streetname VALUES('tunston'); + INSERT INTO streetname VALUES('tupelo'); + INSERT INTO streetname VALUES('turnabout'); + INSERT INTO streetname VALUES('turney'); + INSERT INTO streetname VALUES('turtle cross'); + INSERT INTO streetname VALUES('turtleback'); + INSERT INTO streetname VALUES('twelvestone'); + INSERT INTO streetname VALUES('twin'); + INSERT INTO streetname VALUES('twin brook'); + INSERT INTO streetname VALUES('twin lakes'); + INSERT INTO streetname VALUES('twisted pine'); + INSERT INTO streetname VALUES('tyler finley'); + INSERT INTO streetname VALUES('university station'); + INSERT INTO streetname VALUES('uphill'); + INSERT INTO streetname VALUES('valeview'); + INSERT INTO streetname VALUES('valhalla'); + INSERT INTO streetname VALUES('van'); + INSERT INTO streetname VALUES('vance davis'); + INSERT INTO streetname VALUES('vanhoy'); + INSERT INTO streetname VALUES('veckman'); + INSERT INTO streetname VALUES('victoria'); + INSERT INTO streetname VALUES('victory'); + INSERT INTO streetname VALUES('village glen'); + INSERT INTO streetname VALUES('vireo'); + INSERT INTO streetname VALUES('viscount'); + INSERT INTO streetname VALUES('voeltz'); + INSERT INTO streetname VALUES('wade e morgan'); + INSERT INTO streetname VALUES('wake'); + INSERT INTO streetname VALUES('wales'); + INSERT INTO streetname VALUES('wallace ridge'); + INSERT INTO streetname VALUES('waltham'); + INSERT INTO streetname VALUES('wanamassa'); + INSERT INTO streetname VALUES('warbler wood'); + INSERT INTO streetname VALUES('washington'); + INSERT INTO streetname VALUES('water'); + INSERT INTO streetname VALUES('waterelm'); + INSERT INTO streetname VALUES('waterford hills'); + INSERT INTO streetname VALUES('waterford valley'); + INSERT INTO streetname VALUES('waterloo'); + INSERT INTO streetname VALUES('waterton leas'); + INSERT INTO streetname VALUES('waverly lynn'); + INSERT INTO streetname VALUES('waverlyglen'); + INSERT INTO streetname VALUES('wayside'); + INSERT INTO streetname VALUES('westbury lake'); + INSERT INTO streetname VALUES('westray'); + INSERT INTO streetname VALUES('whistlers chase'); + INSERT INTO streetname VALUES('whistley green'); + INSERT INTO streetname VALUES('whistling oak'); + INSERT INTO streetname VALUES('whitcomb'); + INSERT INTO streetname VALUES('white aspen'); + INSERT INTO streetname VALUES('white cascade'); + INSERT INTO streetname VALUES('white mist'); + INSERT INTO streetname VALUES('white rock'); + INSERT INTO streetname VALUES('white stag'); + INSERT INTO streetname VALUES('whitegate'); + INSERT INTO streetname VALUES('whitehill'); + INSERT INTO streetname VALUES('whitetail'); + INSERT INTO streetname VALUES('whitewood'); + INSERT INTO streetname VALUES('wilburn park'); + INSERT INTO streetname VALUES('wild garden'); + INSERT INTO streetname VALUES('wild rose'); + INSERT INTO streetname VALUES('wilkins terrace'); + INSERT INTO streetname VALUES('william ficklen'); + INSERT INTO streetname VALUES('wiltshire ridge'); + INSERT INTO streetname VALUES('windchase'); + INSERT INTO streetname VALUES('winding jordan'); + INSERT INTO streetname VALUES('windy meadow'); + INSERT INTO streetname VALUES('winghaven'); + INSERT INTO streetname VALUES('wingmont'); + INSERT INTO streetname VALUES('winslow'); + INSERT INTO streetname VALUES('winter pine'); + INSERT INTO streetname VALUES('winter view'); + INSERT INTO streetname VALUES('wolf creek'); + INSERT INTO streetname VALUES('wondering oak'); + INSERT INTO streetname VALUES('woodard'); + INSERT INTO streetname VALUES('woodfire'); + INSERT INTO streetname VALUES('woodland commons'); + INSERT INTO streetname VALUES('woodland hills'); + INSERT INTO streetname VALUES('woodnotch'); + INSERT INTO streetname VALUES('woodstone'); + INSERT INTO streetname VALUES('worsley'); + INSERT INTO streetname VALUES('wren creek'); + INSERT INTO streetname VALUES('wrens nest'); + INSERT INTO streetname VALUES('wrexham'); + INSERT INTO streetname VALUES('wt harris'); + INSERT INTO streetname VALUES('wylie meadow'); + INSERT INTO streetname VALUES('wynborough'); + INSERT INTO streetname VALUES('wynbrook'); + INSERT INTO streetname VALUES('wyndham hill'); + INSERT INTO streetname VALUES('yandem'); + INSERT INTO streetname VALUES('yellow rose'); + INSERT INTO streetname VALUES('yellow spaniel'); + INSERT INTO streetname VALUES('yorkford'); + INSERT INTO streetname VALUES('ziegler'); + INSERT INTO streetname VALUES('zion renaissance'); + + SELECT count(*) FROM streetname; + } +} {1228} + +do_test fuzzer1-2.1 { + execsql { + SELECT n, distance FROM f2, streetname + WHERE f2.word MATCH 'wersley' + AND f2.distance<=150 + AND f2.word=streetname.n + } +} {worsley 37} +do_test fuzzer1-2.2 { + execsql { + SELECT n, distance FROM f2, streetname + WHERE f2.word MATCH 'testledown' + AND f2.distance<=150 + AND f2.word=streetname.n + } +} {thistledown 103} +do_test fuzzer1-2.3 { + execsql { + SELECT DISTINCT streetname.n FROM f2, streetname + WHERE f2.word MATCH 'tayle' + AND f2.distance<=200 + AND streetname.n>=f2.word AND streetname.n<=(f2.word || x'F7BFBFBF') + } +} {steelewood tallia tallu talwyn taymouth thelema trailer {tyler finley}} + finish_test diff --git a/tool/mkopts.tcl b/tool/mkopts.tcl old mode 100755 new mode 100644