/ Check-in [a6001589]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the randomhex() function as a built-in. (CVS 3619)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:a6001589ab1349f7a6b4af941e9e0fd73d13c1c0
User & Date: drh 2007-01-29 15:50:06
Context
2007-01-29
17:58
Replace the randomHex() function with separate functions randomBlob() and hex(). (CVS 3620) check-in: f5ad74a9 user: drh tags: trunk
15:50
Add the randomhex() function as a built-in. (CVS 3619) check-in: a6001589 user: drh tags: trunk
2007-01-28
21:42
Implement the platform specific part of the shared library interface on OS/2 (CVS 3618) check-in: 027251a6 user: pweilbacher tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
267
268
269
270
271
272
273



























274
275
276
277
278
279
280
....
1020
1021
1022
1023
1024
1025
1026

1027
1028
1029
1030
1031
1032
1033
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.134 2006/09/16 21:45:14 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
................................................................................
){
  sqlite_int64 r;
  sqlite3Randomness(sizeof(r), &r);
  if( (r<<1)==0 ) r = 0;  /* Prevent 0x8000.... as the result so that we */
                          /* can always do abs() of the result */
  sqlite3_result_int64(context, r);
}




























/*
** Implementation of the last_insert_rowid() SQL function.  The return
** value is the same as the sqlite3_last_insert_rowid() API function.
*/
static void last_insert_rowid(
  sqlite3_context *context, 
................................................................................
    { "upper",              1, 0, SQLITE_UTF8,    0, upperFunc  },
    { "lower",              1, 0, SQLITE_UTF8,    0, lowerFunc  },
    { "coalesce",          -1, 0, SQLITE_UTF8,    0, ifnullFunc },
    { "coalesce",           0, 0, SQLITE_UTF8,    0, 0          },
    { "coalesce",           1, 0, SQLITE_UTF8,    0, 0          },
    { "ifnull",             2, 0, SQLITE_UTF8,    1, ifnullFunc },
    { "random",            -1, 0, SQLITE_UTF8,    0, randomFunc },

    { "nullif",             2, 0, SQLITE_UTF8,    1, nullifFunc },
    { "sqlite_version",     0, 0, SQLITE_UTF8,    0, versionFunc},
    { "quote",              1, 0, SQLITE_UTF8,    0, quoteFunc  },
    { "last_insert_rowid",  0, 1, SQLITE_UTF8,    0, last_insert_rowid },
    { "changes",            0, 1, SQLITE_UTF8,    0, changes    },
    { "total_changes",      0, 1, SQLITE_UTF8,    0, total_changes },
#ifdef SQLITE_SOUNDEX







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
....
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
** This file contains the C functions that implement various SQL
** functions of SQLite.  
**
** There is only one exported symbol in this file - the function
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope.
**
** $Id: func.c,v 1.135 2007/01/29 15:50:06 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
/* #include <math.h> */
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
................................................................................
){
  sqlite_int64 r;
  sqlite3Randomness(sizeof(r), &r);
  if( (r<<1)==0 ) r = 0;  /* Prevent 0x8000.... as the result so that we */
                          /* can always do abs() of the result */
  sqlite3_result_int64(context, r);
}

/*
** Implementation of randomhex(N).  Return a random hexadecimal string
** that is N characters long.
*/
static void randomHex(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int n, i, j;
  unsigned char c, zBuf[1001];
  assert( argc==1 );
  n = sqlite3_value_int(argv[0]);
  if( n&1 ) n++;
  if( n<2 ) n = 2;
  if( n>sizeof(zBuf)-1 )  n = sizeof(zBuf)-1;
  sqlite3Randomness(n/2, zBuf);
  for(i=n-1, j=n/2-1; i>=1; i-=2, j--){
    static const char zDigits[] = "0123456789ABCDEF";
    c = zBuf[j];
    zBuf[i] = zDigits[c&0xf];
    zBuf[i-1] = zDigits[c>>4];
  }
  zBuf[n] = 0;
  sqlite3_result_text(context, (char*)zBuf, n, SQLITE_TRANSIENT);
}

/*
** Implementation of the last_insert_rowid() SQL function.  The return
** value is the same as the sqlite3_last_insert_rowid() API function.
*/
static void last_insert_rowid(
  sqlite3_context *context, 
................................................................................
    { "upper",              1, 0, SQLITE_UTF8,    0, upperFunc  },
    { "lower",              1, 0, SQLITE_UTF8,    0, lowerFunc  },
    { "coalesce",          -1, 0, SQLITE_UTF8,    0, ifnullFunc },
    { "coalesce",           0, 0, SQLITE_UTF8,    0, 0          },
    { "coalesce",           1, 0, SQLITE_UTF8,    0, 0          },
    { "ifnull",             2, 0, SQLITE_UTF8,    1, ifnullFunc },
    { "random",            -1, 0, SQLITE_UTF8,    0, randomFunc },
    { "randomhex",          1, 0, SQLITE_UTF8,    0, randomHex  },
    { "nullif",             2, 0, SQLITE_UTF8,    1, nullifFunc },
    { "sqlite_version",     0, 0, SQLITE_UTF8,    0, versionFunc},
    { "quote",              1, 0, SQLITE_UTF8,    0, quoteFunc  },
    { "last_insert_rowid",  0, 1, SQLITE_UTF8,    0, last_insert_rowid },
    { "changes",            0, 1, SQLITE_UTF8,    0, changes    },
    { "total_changes",      0, 1, SQLITE_UTF8,    0, total_changes },
#ifdef SQLITE_SOUNDEX

Changes to test/func.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
292
293
294
295
296
297
298






















299
300
301
302
303
304
305
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.55 2006/09/16 21:45:14 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
# How do you test the random() function in a meaningful, deterministic way?
#
do_test func-9.1 {
  execsql {
    SELECT random() is not null;
  }
} {1}























# Use the "sqlite_register_test_function" TCL command which is part of
# the text fixture in order to verify correct operation of some of
# the user-defined SQL function APIs that are not used by the built-in
# functions.
#
set ::DB [sqlite3_connection_pointer db]







|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.56 2007/01/29 15:50:06 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
# How do you test the random() function in a meaningful, deterministic way?
#
do_test func-9.1 {
  execsql {
    SELECT random() is not null;
  }
} {1}
do_test func-9.2 {
  execsql {
    SELECT typeof(random());
  }
} {integer}
do_test func-9.3 {
  execsql {
    SELECT randomhex(32) is not null;
  }
} {1}
do_test func-9.4 {
  execsql {
    SELECT typeof(randomhex(32));
  }
} {text}
do_test func-9.5 {
  execsql {
    SELECT length(randomhex(32)), length(randomhex(-5)),
           length(randomhex(2000)), length(randomhex(31));
  }
} {32 2 1000 32}


# Use the "sqlite_register_test_function" TCL command which is part of
# the text fixture in order to verify correct operation of some of
# the user-defined SQL function APIs that are not used by the built-in
# functions.
#
set ::DB [sqlite3_connection_pointer db]

Changes to www/lang.tcl.

1
2
3
4
5
6
7
8
9
10
11
....
1369
1370
1371
1372
1373
1374
1375









1376
1377
1378
1379
1380
1381
1382
#
# Run this Tcl script to generate the lang-*.html files.
#
set rcsid {$Id: lang.tcl,v 1.118 2006/09/23 20:46:23 drh Exp $}
source common.tcl

if {[llength $argv]>0} {
  set outputdir [lindex $argv 0]
} else {
  set outputdir ""
}
................................................................................

<tr>
<td valign="top" align="right">random(*)</td>
<td valign="top">Return a pseudo-random integer
between -9223372036854775808 and +9223372036854775807.</td>
</tr>










<tr>
<td valign="top" align="right">round(<i>X</i>)<br>round(<i>X</i>,<i>Y</i>)</td>
<td valign="top">Round off the number <i>X</i> to <i>Y</i> digits to the
right of the decimal point.  If the <i>Y</i> argument is omitted, 0 is 
assumed.</td>
</tr>




|







 







>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
....
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
#
# Run this Tcl script to generate the lang-*.html files.
#
set rcsid {$Id: lang.tcl,v 1.119 2007/01/29 15:50:06 drh Exp $}
source common.tcl

if {[llength $argv]>0} {
  set outputdir [lindex $argv 0]
} else {
  set outputdir ""
}
................................................................................

<tr>
<td valign="top" align="right">random(*)</td>
<td valign="top">Return a pseudo-random integer
between -9223372036854775808 and +9223372036854775807.</td>
</tr>

<tr>
<td valign="top" align="right">randomhex(<i>N</i>)</td>
<td valign="top">Return a pseudo-random hexadecimal string that is
<i>N</i> characters in length.  <i>N</i> should be an even integer between
2 and 1000.  The intended use of this function is to generate
universally unique identifiers (UUID).  For that purpose, it is recommended
that <i>N</i> be at least 32.</td>
</tr>

<tr>
<td valign="top" align="right">round(<i>X</i>)<br>round(<i>X</i>,<i>Y</i>)</td>
<td valign="top">Round off the number <i>X</i> to <i>Y</i> digits to the
right of the decimal point.  If the <i>Y</i> argument is omitted, 0 is 
assumed.</td>
</tr>