]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add built-in functions numeric(), text(), and blob() that coerce types.
authordrh <drh@noemail.net>
Wed, 22 Jun 2005 10:53:59 +0000 (10:53 +0000)
committerdrh <drh@noemail.net>
Wed, 22 Jun 2005 10:53:59 +0000 (10:53 +0000)
Ticket #1287. (CVS 2524)

FossilOrigin-Name: affb0fa2e8c5ff497838ba3c2994cdb1f6f50c68

manifest
manifest.uuid
src/func.c
src/vdbeapi.c
test/func.test

index 519fcc2e7301fe07178d0e75026d82c5f0efdb5a..c2a3bda2253ad624c1aabe5a0b3e897d5229e8e5 100644 (file)
--- a/manifest
+++ b/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)
-D 2005-06-22T08:48:06
+C Add\sbuilt-in\sfunctions\snumeric(),\stext(),\sand\sblob()\sthat\scoerce\stypes.\r\nTicket\s#1287.\s(CVS\s2524)
+D 2005-06-22T10:53:59
 F Makefile.in 64a6635ef44a98325e0cffe8d67669920a3dad47
 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -38,7 +38,7 @@ F src/date.c 2134ef4388256e8247405178df8a61bd60dc180a
 F src/delete.c 4b68127f55971c7fb459146e0b6cf3bd70cfffe9
 F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
 F src/expr.c 4d6e26da200e0d08233df52fd8d07916d24a6926
-F src/func.c f208d71f741d47b63277530939f552815af8ce35
+F src/func.c 301b81af2e831b2e929f0ba252739c32a0c756e5
 F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f
 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
 F src/insert.c 8c0868a975fe37366ed92e1b976853be96284607
@@ -80,7 +80,7 @@ F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
 F src/vdbe.c 4745b575d9f23a960da0ce8334f99b98ea855265
 F src/vdbe.h 75e466d84d362b0c4498978a9d6b1e6bd32ecf3b
 F src/vdbeInt.h 4312faf41630a6c215924b6c7c2f39ebb1af8ffb
-F src/vdbeapi.c 3f858d2236df0d127249a6a166e0e25b5de650ed
+F src/vdbeapi.c 5025a9163107e0a4964212d16e1c4defa13dc5c2
 F src/vdbeaux.c 38332d91887817a2146f46b58fff2a8a88ed0278
 F src/vdbemem.c 48a64ae95a9edc6e8d940300dad15d70d1670398
 F src/where.c 3a9a2258ab3364655e9ea215ad5ae7bf41813f54
@@ -132,7 +132,7 @@ F test/enc2.test d1ab077b84f4d3099246915422b1ab6b81481e0a
 F test/enc3.test f6a5f0b7b7f3a88f030d3143729b87cd5c86d837
 F test/expr.test 54d9d1cc05eb731fa62daa70f2d7163f8a03c54d
 F test/fkey1.test 81bb13caaa78f58d7d191d7f535529f7c91d821a
-F test/func.test 7d2d8489bede4495feca427c5efc7b7a2f3b1e94
+F test/func.test f5f9f2bd3f1121ae82eb4d6b3f48b8c52f597895
 F test/hook.test f8605cde4c77b2c6a4a73723bf6c507796a64dda
 F test/in.test ed134f8d477a6280297ced1646de83cccf8f196d
 F test/index.test 51e01a0928b4b61228917ddd8c6c0e2466547f6f
@@ -281,7 +281,7 @@ F www/tclsqlite.tcl 425be741b8ae664f55cb1ef2371aab0a75109cf9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
 F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
-P 60f752ed1817e6710c13c2ce393c3bf51dae76ad
-R 0728a1fdbaca12bf5f29cdb10e76a914
+P f3427a139c3bd4faf9134ec6290b3eb829c0a19f
+R 71ae20ec723bd0f4ef99d2a15e3563f6
 U drh
-Z 6446212b902f4acbac0e5ce1e2a10f05
+Z 9f6943b255fa6f70bc55d3e3a0442f66
index 9c51dfed70f1aee732c6a8c7b79576790da3e7f8..31646f254598583f9d6c87aa41927a951241295a 100644 (file)
@@ -1 +1 @@
-f3427a139c3bd4faf9134ec6290b3eb829c0a19f
\ No newline at end of file
+affb0fa2e8c5ff497838ba3c2994cdb1f6f50c68
\ No newline at end of file
index e1b2195e89517b472859369e9243647f0b1ef26f..d13ba437cb0cfa65e9252015ea145f64c1de2f5f 100644 (file)
@@ -16,7 +16,7 @@
 ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
 ** 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 <ctype.h>
@@ -78,6 +78,93 @@ static void typeofFunc(
   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
 */
@@ -971,6 +1058,9 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
     { "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 },
+    { "text",               1, 0, SQLITE_UTF8,    0, textFunc      },
+    { "numeric",            1, 0, SQLITE_UTF8,    0, numericFunc   },
+    { "blob",               1, 0, SQLITE_UTF8,    0, blobFunc      },
 #ifdef SQLITE_SOUNDEX
     { "soundex",            1, 0, SQLITE_UTF8, 0, soundexFunc},
 #endif
index f07bc889924be2fc43caffd72f95206f903db3d8..99da1c30bc7bbcaa95713031e21738c29fd02671 100644 (file)
@@ -84,7 +84,7 @@ void sqlite3_result_blob(
   int n, 
   void (*xDel)(void *)
 ){
-  assert( n>0 );
+  assert( n>=0 );
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel);
 }
 void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
index feed0d03b16999169567810f8d57ec53d9277399..ab8b6f6df78dcca1565f53d7ef099f25d0a845ce 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # 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]
 source $testdir/tester.tcl
@@ -485,5 +485,134 @@ do_test func-16.1 {
   }
 } {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