1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Add built-in functions numeric(), text(), and blob() that coerce types.

Ticket #1287. (CVS 2524)

FossilOrigin-Name: affb0fa2e8c5ff497838ba3c2994cdb1f6f50c68
This commit is contained in:
drh
2005-06-22 10:53:59 +00:00
parent 288d37f1b4
commit 5708d2deac
5 changed files with 232 additions and 13 deletions

View File

@ -1,5 +1,5 @@
C Allow\sparameters\sto\sbe\sintroduced\sby\scharacters\s':',\s'$'\sand\s'#'.\s\sThis\nis\san\sexperimental\schange.\s(CVS\s2523) C Add\sbuilt-in\sfunctions\snumeric(),\stext(),\sand\sblob()\sthat\scoerce\stypes.\r\nTicket\s#1287.\s(CVS\s2524)
D 2005-06-22T08:48:06 D 2005-06-22T10:53:59
F Makefile.in 64a6635ef44a98325e0cffe8d67669920a3dad47 F Makefile.in 64a6635ef44a98325e0cffe8d67669920a3dad47
F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -38,7 +38,7 @@ F src/date.c 2134ef4388256e8247405178df8a61bd60dc180a
F src/delete.c 4b68127f55971c7fb459146e0b6cf3bd70cfffe9 F src/delete.c 4b68127f55971c7fb459146e0b6cf3bd70cfffe9
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
F src/expr.c 4d6e26da200e0d08233df52fd8d07916d24a6926 F src/expr.c 4d6e26da200e0d08233df52fd8d07916d24a6926
F src/func.c f208d71f741d47b63277530939f552815af8ce35 F src/func.c 301b81af2e831b2e929f0ba252739c32a0c756e5
F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
F src/insert.c 8c0868a975fe37366ed92e1b976853be96284607 F src/insert.c 8c0868a975fe37366ed92e1b976853be96284607
@ -80,7 +80,7 @@ F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
F src/vdbe.c 4745b575d9f23a960da0ce8334f99b98ea855265 F src/vdbe.c 4745b575d9f23a960da0ce8334f99b98ea855265
F src/vdbe.h 75e466d84d362b0c4498978a9d6b1e6bd32ecf3b F src/vdbe.h 75e466d84d362b0c4498978a9d6b1e6bd32ecf3b
F src/vdbeInt.h 4312faf41630a6c215924b6c7c2f39ebb1af8ffb F src/vdbeInt.h 4312faf41630a6c215924b6c7c2f39ebb1af8ffb
F src/vdbeapi.c 3f858d2236df0d127249a6a166e0e25b5de650ed F src/vdbeapi.c 5025a9163107e0a4964212d16e1c4defa13dc5c2
F src/vdbeaux.c 38332d91887817a2146f46b58fff2a8a88ed0278 F src/vdbeaux.c 38332d91887817a2146f46b58fff2a8a88ed0278
F src/vdbemem.c 48a64ae95a9edc6e8d940300dad15d70d1670398 F src/vdbemem.c 48a64ae95a9edc6e8d940300dad15d70d1670398
F src/where.c 3a9a2258ab3364655e9ea215ad5ae7bf41813f54 F src/where.c 3a9a2258ab3364655e9ea215ad5ae7bf41813f54
@ -132,7 +132,7 @@ F test/enc2.test d1ab077b84f4d3099246915422b1ab6b81481e0a
F test/enc3.test f6a5f0b7b7f3a88f030d3143729b87cd5c86d837 F test/enc3.test f6a5f0b7b7f3a88f030d3143729b87cd5c86d837
F test/expr.test 54d9d1cc05eb731fa62daa70f2d7163f8a03c54d F test/expr.test 54d9d1cc05eb731fa62daa70f2d7163f8a03c54d
F test/fkey1.test 81bb13caaa78f58d7d191d7f535529f7c91d821a F test/fkey1.test 81bb13caaa78f58d7d191d7f535529f7c91d821a
F test/func.test 7d2d8489bede4495feca427c5efc7b7a2f3b1e94 F test/func.test f5f9f2bd3f1121ae82eb4d6b3f48b8c52f597895
F test/hook.test f8605cde4c77b2c6a4a73723bf6c507796a64dda F test/hook.test f8605cde4c77b2c6a4a73723bf6c507796a64dda
F test/in.test ed134f8d477a6280297ced1646de83cccf8f196d F test/in.test ed134f8d477a6280297ced1646de83cccf8f196d
F test/index.test 51e01a0928b4b61228917ddd8c6c0e2466547f6f F test/index.test 51e01a0928b4b61228917ddd8c6c0e2466547f6f
@ -281,7 +281,7 @@ F www/tclsqlite.tcl 425be741b8ae664f55cb1ef2371aab0a75109cf9
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
P 60f752ed1817e6710c13c2ce393c3bf51dae76ad P f3427a139c3bd4faf9134ec6290b3eb829c0a19f
R 0728a1fdbaca12bf5f29cdb10e76a914 R 71ae20ec723bd0f4ef99d2a15e3563f6
U drh U drh
Z 6446212b902f4acbac0e5ce1e2a10f05 Z 9f6943b255fa6f70bc55d3e3a0442f66

View File

@ -1 +1 @@
f3427a139c3bd4faf9134ec6290b3eb829c0a19f affb0fa2e8c5ff497838ba3c2994cdb1f6f50c68

View File

@ -16,7 +16,7 @@
** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
** All other code has file scope. ** All other code has file scope.
** **
** $Id: func.c,v 1.98 2005/05/24 12:01:02 danielk1977 Exp $ ** $Id: func.c,v 1.99 2005/06/22 10:53:59 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@ -78,6 +78,93 @@ static void typeofFunc(
sqlite3_result_text(context, z, -1, SQLITE_STATIC); sqlite3_result_text(context, z, -1, SQLITE_STATIC);
} }
/*
** Convert the argument to a numeric type.
*/
static void numericFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *z = 0;
switch( sqlite3_value_type(argv[0]) ){
case SQLITE_NULL: {
sqlite3_result_int(context, 0);
break;
}
case SQLITE_INTEGER:
case SQLITE_FLOAT: {
sqlite3_result_value(context, argv[0]);
break;
}
case SQLITE_TEXT:
case SQLITE_BLOB: {
z = sqlite3_value_text(argv[0]);
while( *z && *z!='.' ){ z++; }
if( *z ){
sqlite3_result_double(context, sqlite3_value_double(argv[0]));
}else{
sqlite3_result_int64(context, sqlite3_value_int64(argv[0]));
}
break;
}
}
}
/*
** Convert the argument to TEXT
*/
static void textFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
switch( sqlite3_value_type(argv[0]) ){
case SQLITE_NULL: {
sqlite3_result_text(context, "", 0, SQLITE_STATIC);
break;
}
case SQLITE_BLOB:
case SQLITE_INTEGER:
case SQLITE_FLOAT: {
sqlite3_result_text(context, sqlite3_value_text(argv[0]),
sqlite3_value_bytes(argv[0]), SQLITE_TRANSIENT);
break;
}
case SQLITE_TEXT: {
sqlite3_result_value(context, argv[0]);
break;
}
}
}
/*
** Convert the argument to TEXT
*/
static void blobFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
switch( sqlite3_value_type(argv[0]) ){
case SQLITE_NULL: {
sqlite3_result_blob(context, "", 0, SQLITE_STATIC);
break;
}
case SQLITE_TEXT:
case SQLITE_INTEGER:
case SQLITE_FLOAT: {
sqlite3_result_blob(context, sqlite3_value_text(argv[0]),
sqlite3_value_bytes(argv[0]), SQLITE_TRANSIENT);
break;
}
case SQLITE_BLOB: {
sqlite3_result_value(context, argv[0]);
break;
}
}
}
/* /*
** Implementation of the length() function ** Implementation of the length() function
*/ */
@ -971,6 +1058,9 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
{ "last_insert_rowid", 0, 1, SQLITE_UTF8, 0, last_insert_rowid }, { "last_insert_rowid", 0, 1, SQLITE_UTF8, 0, last_insert_rowid },
{ "changes", 0, 1, SQLITE_UTF8, 0, changes }, { "changes", 0, 1, SQLITE_UTF8, 0, changes },
{ "total_changes", 0, 1, SQLITE_UTF8, 0, total_changes }, { "total_changes", 0, 1, SQLITE_UTF8, 0, total_changes },
{ "text", 1, 0, SQLITE_UTF8, 0, textFunc },
{ "numeric", 1, 0, SQLITE_UTF8, 0, numericFunc },
{ "blob", 1, 0, SQLITE_UTF8, 0, blobFunc },
#ifdef SQLITE_SOUNDEX #ifdef SQLITE_SOUNDEX
{ "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc}, { "soundex", 1, 0, SQLITE_UTF8, 0, soundexFunc},
#endif #endif

View File

@ -84,7 +84,7 @@ void sqlite3_result_blob(
int n, int n,
void (*xDel)(void *) void (*xDel)(void *)
){ ){
assert( n>0 ); assert( n>=0 );
sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel); sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel);
} }
void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ void sqlite3_result_double(sqlite3_context *pCtx, double rVal){

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The # This file implements regression tests for SQLite library. The
# focus of this file is testing built-in functions. # focus of this file is testing built-in functions.
# #
# $Id: func.test,v 1.34 2005/03/29 03:11:00 danielk1977 Exp $ # $Id: func.test,v 1.35 2005/06/22 10:53:59 drh Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@ -485,5 +485,134 @@ do_test func-16.1 {
} }
} {X'616263' NULL} } {X'616263' NULL}
finish_test # Tests for the blob(), text() and numeric() built-ins
#
do_test func-17.1 {
execsql {SELECT x'616263'}
} abc
do_test func-17.2 {
execsql {SELECT typeof(x'616263')}
} blob
do_test func-17.3 {
execsql {SELECT text(x'616263')}
} abc
do_test func-17.4 {
execsql {SELECT typeof(text(x'616263'))}
} text
do_test func-17.5 {
execsql {SELECT numeric(x'616263')}
} 0
do_test func-17.6 {
execsql {SELECT typeof(numeric(x'616263'))}
} integer
do_test func-17.7 {
execsql {SELECT blob(x'616263')}
} abc
do_test func-17.8 {
execsql {SELECT typeof(blob(x'616263'))}
} blob
do_test func-17.11 {
execsql {SELECT null}
} {{}}
do_test func-17.12 {
execsql {SELECT typeof(NULL)}
} null
do_test func-17.13 {
execsql {SELECT text(NULL)}
} {{}}
do_test func-17.14 {
execsql {SELECT typeof(text(NULL))}
} text
do_test func-17.15 {
execsql {SELECT numeric(NULL)}
} 0
do_test func-17.16 {
execsql {SELECT typeof(numeric(NULL))}
} integer
do_test func-17.17 {
execsql {SELECT blob(NULL)}
} {{}}
do_test func-17.18 {
execsql {SELECT typeof(blob(NULL))}
} blob
do_test func-17.21 {
execsql {SELECT 123}
} {123}
do_test func-17.22 {
execsql {SELECT typeof(123)}
} integer
do_test func-17.23 {
execsql {SELECT text(123)}
} {123}
do_test func-17.24 {
execsql {SELECT typeof(text(123))}
} text
do_test func-17.25 {
execsql {SELECT numeric(123)}
} 123
do_test func-17.26 {
execsql {SELECT typeof(numeric(123))}
} integer
do_test func-17.27 {
execsql {SELECT blob(123)}
} {123}
do_test func-17.28 {
execsql {SELECT typeof(blob(123))}
} blob
do_test func-17.31 {
execsql {SELECT 123.456}
} {123.456}
do_test func-17.32 {
execsql {SELECT typeof(123.456)}
} real
do_test func-17.33 {
execsql {SELECT text(123.456)}
} {123.456}
do_test func-17.34 {
execsql {SELECT typeof(text(123.456))}
} text
do_test func-17.35 {
execsql {SELECT numeric(123.456)}
} 123.456
do_test func-17.36 {
execsql {SELECT typeof(numeric(123.456))}
} real
do_test func-17.37 {
execsql {SELECT blob(123.456)}
} {123.456}
do_test func-17.38 {
execsql {SELECT typeof(blob(123.456))}
} blob
do_test func-17.41 {
execsql {SELECT '123abc'}
} {123abc}
do_test func-17.42 {
execsql {SELECT typeof('123abc')}
} text
do_test func-17.43 {
execsql {SELECT text('123abc')}
} {123abc}
do_test func-17.44 {
execsql {SELECT typeof(text('123abc'))}
} text
do_test func-17.45 {
execsql {SELECT numeric('123abc')}
} 123
do_test func-17.46 {
execsql {SELECT typeof(numeric('123abc'))}
} integer
do_test func-17.47 {
execsql {SELECT blob('123abc')}
} {123abc}
do_test func-17.48 {
execsql {SELECT typeof(blob('123abc'))}
} blob
do_test func-17.49 {
execsql {SELECT numeric('123.5abc')}
} 123.5
do_test func-17.49b {
execsql {SELECT typeof(numeric('123.5abc'))}
} real
finish_test