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:
16
manifest
16
manifest
@ -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
|
||||||
|
@ -1 +1 @@
|
|||||||
f3427a139c3bd4faf9134ec6290b3eb829c0a19f
|
affb0fa2e8c5ff497838ba3c2994cdb1f6f50c68
|
92
src/func.c
92
src/func.c
@ -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
|
||||||
|
@ -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){
|
||||||
|
133
test/func.test
133
test/func.test
@ -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
|
||||||
|
Reference in New Issue
Block a user