Add the SQLITE_TESTCTRL_PRNG_SEED test control.

FossilOrigin-Name: 3ac5723164ae801e209ce525a5d94692767136f9d06be2a84883dcea677d02da
diff --git a/manifest b/manifest
index bfde79b..47da76a 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C If\sa\squery\slike\s"SELECT\smin(a),\sb\sFROM\st1"\svisits\sno\srows\swhere\s"a"\sis\snot\snull,\sextract\sa\svalue\sfor\s"b"\sfrom\sone\sof\sthe\srows\swhere\s"a"\sis\snull.\sFix\sfor\sticket\s[41866dc37].
-D 2019-08-02T19:40:01.648
+C Add\sthe\sSQLITE_TESTCTRL_PRNG_SEED\stest\scontrol.
+D 2019-08-02T20:45:04.317
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -479,7 +479,7 @@
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c ab1971900477e93b6aaabf160d2d1c79c06edd9227441ccfaf0de7e7431d7f48
 F src/func.c 905c0424900979fade3731b4a271592059425c988cb7d5b245032253712dd7c8
-F src/global.c 1e942b1e6fb6a2a15e6015bda72be0abefc4b1339a8640a47b1b71b7f317917b
+F src/global.c 0c9c45844ae182b458610e4d427834deffcdcd45fbc8c957f6ad82051b8f161f
 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da
@@ -487,7 +487,7 @@
 F src/insert.c f20925c2c08144442dabeb73dcd0f5026f5f085d827f3d5635f7c45e5d195320
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c
-F src/main.c 591a0084b1a6b0ed6741f77181bd1a630ca10bb460420f00e8c11809da7df5b9
+F src/main.c e30b0b22666f7e1e0bb6c8d051d5201bd85419eca8c2423ffe7b1bce6364653a
 F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de
@@ -503,7 +503,7 @@
 F src/mutex_unix.c aaf9ebc3f89df28483c52208497a99a02cc3650011422fc9d4c57e4392f7fe58
 F src/mutex_w32.c 7670d770c94bbfe8289bec9d7f1394c5a00a57c37f892aab6b6612d085255235
 F src/notify.c 9711a7575036f0d3040ba61bc6e217f13a9888e7
-F src/os.c 8aeb0b0f40f8f5b0da03fe49706695adaf42d2f516ab95abc72e86c245e119de
+F src/os.c 033039bb9b6da7d163c1806ba0d4dc0be9748ed78d8490c018bfd2346b774c1e
 F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432
 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85
 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
@@ -524,16 +524,16 @@
 F src/resolve.c 6d57cfcb728fe1513fcbfb2bbd4192838b8cfe094616f72c7a54be55a550cc84
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
 F src/select.c 1b8b5afee76e7d662b34c61705a638f7a6a20d5109515ca973c12343c84fb2d6
-F src/shell.c.in 9c203a8c643fd638ab67a911e1fad1f51138c13a4d0ea3cedf7526fba5de60f2
-F src/sqlite.h.in 83ebc8ab1a2e82d92214006ea2c15bf8a0604f3fac2c31dd9ce9021f568c71f2
+F src/shell.c.in 5ab94c68a555b573a28e2ccdd811cc9ab8e0dd79274dad52567056fa6830d061
+F src/sqlite.h.in dfe86c132b5085e00cf0539c78510b75e60d740191804c9848e8bb7aa850fff5
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5
-F src/sqliteInt.h 122621557d07c6102d5a41897fe50eabe9767ca7db8ded6746de0446225d03d3
+F src/sqliteInt.h c4e5e98e0eddb78a3594603f57dd720f63660add5bd117f6e55ce39120313036
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
 F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424
-F src/test1.c 118945bc3c2aabe4528ef2ddb412868e29f5addfb76252b77d441e7b0d67043c
+F src/test1.c fd8a05277bebf42cea5d8c8d1f272cf8dc69e838bbc4f14f547b9810f2d689fb
 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5
 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644
 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb
@@ -1838,8 +1838,10 @@
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 961e2f08c35238bcb1d32430d16451a96807b2c4bbb194ee621128dd09cd3981 a7277ed0623dccdbf775ae6127611d6bc6e150f6942a048ab4281e5136c0e98d
-R 967b7339813b309eb9b996030fc19505
-T +closed a7277ed0623dccdbf775ae6127611d6bc6e150f6942a048ab4281e5136c0e98d
-U dan
-Z d74453ebc37fff244bf6e5db95a7c365
+P faaaae4940b5f4f70e4988ad5b45582410b381ace0031e6abcde0b9217c06796
+R cc4f195b7834252acf2666d4e1ada0cd
+T *branch * prng-seed-test-control
+T *sym-prng-seed-test-control *
+T -sym-trunk *
+U drh
+Z 787ec1171fdf2c223779ee565290b12f
diff --git a/manifest.uuid b/manifest.uuid
index 686ba2c..31a6151 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-faaaae4940b5f4f70e4988ad5b45582410b381ace0031e6abcde0b9217c06796
\ No newline at end of file
+3ac5723164ae801e209ce525a5d94692767136f9d06be2a84883dcea677d02da
\ No newline at end of file
diff --git a/src/global.c b/src/global.c
index b512e6f..79b1d42 100644
--- a/src/global.c
+++ b/src/global.c
@@ -260,6 +260,7 @@
    0,                         /* bInternalFunctions */
    0x7ffffffe,                /* iOnceResetThreshold */
    SQLITE_DEFAULT_SORTERREF_SIZE,   /* szSorterRef */
+   0,                         /* iPrngSeed */
 };
 
 /*
diff --git a/src/main.c b/src/main.c
index 6127006..81a76aa 100644
--- a/src/main.c
+++ b/src/main.c
@@ -3824,13 +3824,13 @@
       break;
     }
 
-    /*
-    ** Reset the PRNG back to its uninitialized state.  The next call
-    ** to sqlite3_randomness() will reseed the PRNG using a single call
-    ** to the xRandomness method of the default VFS.
+    /*  sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, unsigned int);
+    **
+    ** Use the integer value as the seed for SQLite's internal PRNG.
+    ** rather than the VFS xRandomness() function.
     */
-    case SQLITE_TESTCTRL_PRNG_RESET: {
-      sqlite3_randomness(0,0);
+    case SQLITE_TESTCTRL_PRNG_SEED: {
+      sqlite3Config.iPrngSeed = va_arg(ap, unsigned int);
       break;
     }
 
diff --git a/src/os.c b/src/os.c
index 54b7fcf..0870102 100644
--- a/src/os.c
+++ b/src/os.c
@@ -258,7 +258,15 @@
 }
 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
 int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
-  return pVfs->xRandomness(pVfs, nByte, zBufOut);
+  if( sqlite3Config.iPrngSeed ){
+    memset(zBufOut, 0, nByte);
+    if( nByte>sizeof(unsigned) ) nByte = sizeof(unsigned int);
+    memcpy(zBufOut, &sqlite3Config.iPrngSeed, nByte);
+    return SQLITE_OK;
+  }else{
+    return pVfs->xRandomness(pVfs, nByte, zBufOut);
+  }
+  
 }
 int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){
   return pVfs->xSleep(pVfs, nMicro);
diff --git a/src/shell.c.in b/src/shell.c.in
index c5ca924..fa82cf2 100644
--- a/src/shell.c.in
+++ b/src/shell.c.in
@@ -9150,9 +9150,9 @@
       { "parser_coverage",    SQLITE_TESTCTRL_PARSER_COVERAGE, ""                 },
 #endif
       { "pending_byte",       SQLITE_TESTCTRL_PENDING_BYTE,  "OFFSET  "           },
-      { "prng_reset",         SQLITE_TESTCTRL_PRNG_RESET,    ""                   },
       { "prng_restore",       SQLITE_TESTCTRL_PRNG_RESTORE,  ""                   },
       { "prng_save",          SQLITE_TESTCTRL_PRNG_SAVE,     ""                   },
+      { "prng_seed",          SQLITE_TESTCTRL_PRNG_SEED,     "SEED"               },
       { "reserve",            SQLITE_TESTCTRL_RESERVE,       "BYTES-OF-RESERVE"   },
     };
     int testctrl = -1;
@@ -9227,6 +9227,7 @@
 
         /* sqlite3_test_control(int, uint) */
         case SQLITE_TESTCTRL_PENDING_BYTE:
+        case SQLITE_TESTCTRL_PRNG_SEED:
           if( nArg==3 ){
             unsigned int opt = (unsigned int)integerValue(azArg[2]);
             rc2 = sqlite3_test_control(testctrl, opt);
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 4dd14ac..5b3e5a1 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -7335,7 +7335,7 @@
 #define SQLITE_TESTCTRL_FIRST                    5
 #define SQLITE_TESTCTRL_PRNG_SAVE                5
 #define SQLITE_TESTCTRL_PRNG_RESTORE             6
-#define SQLITE_TESTCTRL_PRNG_RESET               7
+#define SQLITE_TESTCTRL_PRNG_RESET               7  /* NOT USED */
 #define SQLITE_TESTCTRL_BITVEC_TEST              8
 #define SQLITE_TESTCTRL_FAULT_INSTALL            9
 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10
@@ -7358,7 +7358,8 @@
 #define SQLITE_TESTCTRL_IMPOSTER                25
 #define SQLITE_TESTCTRL_PARSER_COVERAGE         26
 #define SQLITE_TESTCTRL_RESULT_INTREAL          27
-#define SQLITE_TESTCTRL_LAST                    27  /* Largest TESTCTRL */
+#define SQLITE_TESTCTRL_PRNG_SEED               28
+#define SQLITE_TESTCTRL_LAST                    28  /* Largest TESTCTRL */
 
 /*
 ** CAPI3REF: SQL Keyword Checking
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index b41ba4e..166c465 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3464,6 +3464,7 @@
   int bInternalFunctions;           /* Internal SQL functions are visible */
   int iOnceResetThreshold;          /* When to reset OP_Once counters */
   u32 szSorterRef;                  /* Min size in bytes to use sorter-refs */
+  unsigned int iPrngSeed;           /* Alternative fixed seed for the PRNG */
 };
 
 /*
diff --git a/src/test1.c b/src/test1.c
index 02a7aad..c582bb3 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -6373,7 +6373,28 @@
   int objc,              /* Number of arguments */
   Tcl_Obj *CONST objv[]  /* Command arguments */
 ){
-  sqlite3_test_control(SQLITE_TESTCTRL_PRNG_RESET);
+  sqlite3_randomness(0,0);
+  return TCL_OK;
+}
+/*
+** tclcmd:  prng_seed INT
+**
+** Establish TEXT as the seed for the PRNG
+*/
+static int SQLITE_TCLAPI prng_seed(
+  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 */
+){
+  unsigned int i;
+  if( objc!=2 ){
+    Tcl_WrongNumArgs(interp, 1, objv, "PRNG-SEED-TEXT");
+    return TCL_ERROR;
+  }
+  if( Tcl_GetIntFromObj(objv[0],&i) ) return TCL_ERROR;
+  sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, (unsigned int)i);
+  sqlite3_randomness(0,0);
   return TCL_OK;
 }
 
@@ -7923,6 +7944,7 @@
      { "save_prng_state",               save_prng_state,    0 },
      { "restore_prng_state",            restore_prng_state, 0 },
      { "reset_prng_state",              reset_prng_state,   0 },
+     { "prng_seed",                     prng_seed,          0 },
      { "database_never_corrupt",        database_never_corrupt, 0},
      { "database_may_be_corrupt",       database_may_be_corrupt, 0},
      { "optimization_control",          optimization_control,0},