randomjson.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*
  2. ** 2023-04-28
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. ******************************************************************************
  12. **
  13. ** This SQLite extension implements a the random_json(SEED) and
  14. ** random_json5(SEED) functions. Given a numeric SEED value, these
  15. ** routines generate pseudo-random JSON or JSON5, respectively. The
  16. ** same value is always generated for the same seed.
  17. **
  18. ** These SQL functions are intended for testing. They do not have any
  19. ** practical real-world use, that we know of.
  20. **
  21. ** COMPILE:
  22. **
  23. ** gcc --shared -fPIC -o randomjson.so -I. ext/misc/randomjson.c
  24. **
  25. ** USING FROM THE CLI:
  26. **
  27. ** .load ./randomjson
  28. ** SELECT random_json(1);
  29. ** SELECT random_json5(1);
  30. */
  31. #ifdef SQLITE_STATIC_RANDOMJSON
  32. # include "sqlite3.h"
  33. #else
  34. # include "sqlite3ext.h"
  35. SQLITE_EXTENSION_INIT1
  36. #endif
  37. #include <assert.h>
  38. #include <string.h>
  39. #include <stdlib.h>
  40. /* Pseudo-random number generator */
  41. typedef struct Prng {
  42. unsigned int x, y;
  43. } Prng;
  44. /* Reseed the PRNG */
  45. static void prngSeed(Prng *p, unsigned int iSeed){
  46. p->x = iSeed | 1;
  47. p->y = iSeed;
  48. }
  49. /* Extract a random number */
  50. static unsigned int prngInt(Prng *p){
  51. p->x = (p->x>>1) ^ ((1+~(p->x&1)) & 0xd0000001);
  52. p->y = p->y*1103515245 + 12345;
  53. return p->x ^ p->y;
  54. }
  55. static char *azJsonAtoms[] = {
  56. /* JSON JSON-5 */
  57. "0", "0",
  58. "1", "1",
  59. "-1", "-1",
  60. "2", "+2",
  61. "3DDDD", "3DDDD",
  62. "2.5DD", "2.5DD",
  63. "0.75", ".75",
  64. "-4.0e2", "-4.e2",
  65. "5.0e-3", "+5e-3",
  66. "6.DDe+0DD", "6.DDe+0DD",
  67. "0", "0x0",
  68. "512", "0x200",
  69. "256", "+0x100",
  70. "-2748", "-0xabc",
  71. "true", "true",
  72. "false", "false",
  73. "null", "null",
  74. "9.0e999", "Infinity",
  75. "-9.0e999", "-Infinity",
  76. "9.0e999", "+Infinity",
  77. "null", "NaN",
  78. "-0.0005DD", "-0.0005DD",
  79. "4.35e-3", "+4.35e-3",
  80. "\"gem\\\"hay\"", "\"gem\\\"hay\"",
  81. "\"icy'joy\"", "'icy\\'joy\'",
  82. "\"keylog\"", "\"key\\\nlog\"",
  83. "\"mix\\\\\\tnet\"", "\"mix\\\\\\tnet\"",
  84. "\"oat\\r\\n\"", "\"oat\\r\\n\"",
  85. "\"\\fpan\\b\"", "\"\\fpan\\b\"",
  86. "{}", "{}",
  87. "[]", "[]",
  88. "[]", "[/*empty*/]",
  89. "{}", "{//empty\n}",
  90. "\"ask\"", "\"ask\"",
  91. "\"bag\"", "\"bag\"",
  92. "\"can\"", "\"can\"",
  93. "\"day\"", "\"day\"",
  94. "\"end\"", "'end'",
  95. "\"fly\"", "\"fly\"",
  96. "\"\\u00XX\\u00XX\"", "\"\\xXX\\xXX\"",
  97. "\"y\\uXXXXz\"", "\"y\\uXXXXz\"",
  98. "\"\"", "\"\"",
  99. };
  100. static char *azJsonTemplate[] = {
  101. /* JSON JSON-5 */
  102. "{\"a\":%,\"b\":%,\"cDD\":%}", "{a:%,b:%,cDD:%}",
  103. "{\"a\":%,\"b\":%,\"c\":%,\"d\":%,\"e\":%}", "{a:%,b:%,c:%,d:%,e:%}",
  104. "{\"a\":%,\"b\":%,\"c\":%,\"d\":%,\"\":%}", "{a:%,b:%,c:%,d:%,'':%}",
  105. "{\"d\":%}", "{d:%}",
  106. "{\"eeee\":%, \"ffff\":%}", "{eeee:% /*and*/, ffff:%}",
  107. "{\"$g\":%,\"_h_\":%,\"a b c d\":%}", "{$g:%,_h_:%,\"a b c d\":%}",
  108. "{\"x\":%,\n \"y\":%}", "{\"x\":%,\n \"y\":%}",
  109. "{\"\\u00XX\":%,\"\\uXXXX\":%}", "{\"\\xXX\":%,\"\\uXXXX\":%}",
  110. "{\"Z\":%}", "{Z:%,}",
  111. "[%]", "[%,]",
  112. "[%,%]", "[%,%]",
  113. "[%,%,%]", "[%,%,%,]",
  114. "[%,%,%,%]", "[%,%,%,%]",
  115. "[%,%,%,%,%]", "[%,%,%,%,%]",
  116. };
  117. #define count(X) (sizeof(X)/sizeof(X[0]))
  118. #define STRSZ 10000
  119. static void jsonExpand(
  120. const char *zSrc,
  121. char *zDest,
  122. Prng *p,
  123. int eType, /* 0 for JSON, 1 for JSON5 */
  124. unsigned int r /* Growth probability 0..1000. 0 means no growth */
  125. ){
  126. unsigned int i, j, k;
  127. char *z;
  128. char *zX;
  129. size_t n;
  130. char zBuf[200];
  131. j = 0;
  132. if( zSrc==0 ) zSrc = "%";
  133. if( strlen(zSrc)>=STRSZ/10 ) r = 0;
  134. for(i=0; zSrc[i]; i++){
  135. if( zSrc[i]!='%' ){
  136. if( j<STRSZ ) zDest[j++] = zSrc[i];
  137. continue;
  138. }
  139. if( r==0 || (r<1000 && (prngInt(p)%1000)<=r) ){
  140. /* Fill in without values without any new % */
  141. k = prngInt(p)%(count(azJsonAtoms)/2);
  142. k = k*2 + eType;
  143. z = azJsonAtoms[k];
  144. }else{
  145. /* Add new % terms */
  146. k = prngInt(p)%(count(azJsonTemplate)/2);
  147. k = k*2 + eType;
  148. z = azJsonTemplate[k];
  149. }
  150. n = strlen(z);
  151. if( (zX = strstr(z,"XX"))!=0 ){
  152. unsigned int y = prngInt(p);
  153. if( (y&0xff)==((y>>8)&0xff) ) y += 0x100;
  154. while( (y&0xff)==((y>>16)&0xff) || ((y>>8)&0xff)==((y>>16)&0xff) ){
  155. y += 0x10000;
  156. }
  157. memcpy(zBuf, z, n+1);
  158. z = zBuf;
  159. zX = strstr(z,"XX");
  160. while( zX!=0 ){
  161. zX[0] = "0123456789abcdef"[y%16]; y /= 16;
  162. zX[1] = "0123456789abcdef"[y%16]; y /= 16;
  163. zX = strstr(zX, "XX");
  164. }
  165. }else if( (zX = strstr(z,"DD"))!=0 ){
  166. unsigned int y = prngInt(p);
  167. memcpy(zBuf, z, n+1);
  168. z = zBuf;
  169. zX = strstr(z,"DD");
  170. while( zX!=0 ){
  171. zX[0] = "0123456789"[y%10]; y /= 10;
  172. zX[1] = "0123456789"[y%10]; y /= 10;
  173. zX = strstr(zX, "DD");
  174. }
  175. }
  176. assert( strstr(z, "XX")==0 );
  177. assert( strstr(z, "DD")==0 );
  178. if( j+n<STRSZ ){
  179. memcpy(&zDest[j], z, n);
  180. j += (int)n;
  181. }
  182. }
  183. zDest[STRSZ-1] = 0;
  184. if( j<STRSZ ) zDest[j] = 0;
  185. }
  186. static void randJsonFunc(
  187. sqlite3_context *context,
  188. int argc,
  189. sqlite3_value **argv
  190. ){
  191. unsigned int iSeed;
  192. int eType = *(int*)sqlite3_user_data(context);
  193. Prng prng;
  194. char z1[STRSZ+1], z2[STRSZ+1];
  195. iSeed = (unsigned int)sqlite3_value_int(argv[0]);
  196. prngSeed(&prng, iSeed);
  197. jsonExpand(0, z2, &prng, eType, 1000);
  198. jsonExpand(z2, z1, &prng, eType, 1000);
  199. jsonExpand(z1, z2, &prng, eType, 100);
  200. jsonExpand(z2, z1, &prng, eType, 0);
  201. sqlite3_result_text(context, z1, -1, SQLITE_TRANSIENT);
  202. }
  203. #ifdef _WIN32
  204. __declspec(dllexport)
  205. #endif
  206. int sqlite3_randomjson_init(
  207. sqlite3 *db,
  208. char **pzErrMsg,
  209. const sqlite3_api_routines *pApi
  210. ){
  211. static int cOne = 1;
  212. static int cZero = 0;
  213. int rc = SQLITE_OK;
  214. #ifdef SQLITE_STATIC_RANDOMJSON
  215. (void)pApi; /* Unused parameter */
  216. #else
  217. SQLITE_EXTENSION_INIT2(pApi);
  218. #endif
  219. (void)pzErrMsg; /* Unused parameter */
  220. rc = sqlite3_create_function(db, "random_json", 1,
  221. SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
  222. &cZero, randJsonFunc, 0, 0);
  223. if( rc==SQLITE_OK ){
  224. rc = sqlite3_create_function(db, "random_json5", 1,
  225. SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
  226. &cOne, randJsonFunc, 0, 0);
  227. }
  228. return rc;
  229. }