]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Remove the blob(), text() and numeric() functions added in (2524) and
authordrh <drh@noemail.net>
Sat, 25 Jun 2005 18:42:14 +0000 (18:42 +0000)
committerdrh <drh@noemail.net>
Sat, 25 Jun 2005 18:42:14 +0000 (18:42 +0000)
replace them with the standard CAST operator.
Ticket #1287. (CVS 2527)

FossilOrigin-Name: 17631785f9ee8ab280c82677eb53886912e085bc

16 files changed:
manifest
manifest.uuid
src/build.c
src/date.c
src/expr.c
src/func.c
src/parse.y
src/sqliteInt.h
src/test1.c
src/util.c
src/vdbe.c
src/vdbemem.c
test/cast.test [new file with mode: 0644]
test/func.test
tool/mkkeywordhash.c
www/lang.tcl

index 941ee16017802b0844be3d897bc2d93b00e40ff1..b1f1d545ec8a821588e4423852a173914c04b49b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C NULL\svalues\sin\sa\srow\sof\sa\sunique\sindex\scause\sthe\srow\sto\sbe\sdistinct.\nTicket\s#1301.\s\sMore\stesting\sand\soptimization\sneeds\sto\sbe\sdone\son\sthis\nbefore\sclosing\sthe\sticket.\s(CVS\s2526)
-D 2005-06-24T03:53:06
+C Remove\sthe\sblob(),\stext()\sand\snumeric()\sfunctions\sadded\sin\s(2524)\sand\r\nreplace\sthem\swith\sthe\sstandard\sCAST\soperator.\r\nTicket\s#1287.\s(CVS\s2527)
+D 2005-06-25T18:42:14
 F Makefile.in 64a6635ef44a98325e0cffe8d67669920a3dad47
 F Makefile.linux-gcc 06be33b2a9ad4f005a5f42b22c4a19dab3cbb5c7
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -32,13 +32,13 @@ F src/attach.c 3615dbe960cbee4aa5ea300b8a213dad36527b0f
 F src/auth.c 18c5a0befe20f3a58a41e3ddd78f372faeeefe1f
 F src/btree.c a167f412cf5b269bffba925ac55a1c0a2f749e29
 F src/btree.h 41a71ce027db9ddee72cb43df2316bbe3a1d92af
-F src/build.c 3b64205934761976857ed3fe884854eb4c3b856a
+F src/build.c f2f12fcb4455e247e6fabc46d7168eb42f7194df
 F src/callback.c 0910b611e0c158f107ee3ff86f8a371654971e2b
-F src/date.c 2134ef4388256e8247405178df8a61bd60dc180a
+F src/date.c 7444b0900a28da77e57e3337a636873cff0ae940
 F src/delete.c 9bb19ede439cf325bc6d6f5995b6393fb85b5162
 F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
-F src/expr.c 4d6e26da200e0d08233df52fd8d07916d24a6926
-F src/func.c 301b81af2e831b2e929f0ba252739c32a0c756e5
+F src/expr.c 8d4f5e3d06107e1932b534a45bea848aad6b8612
+F src/func.c cbdf7256400ac7d5f020d131261bb2bd41bb631f
 F src/hash.c 2b1b13f7400e179631c83a1be0c664608c8f021f
 F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
 F src/insert.c d61752504f8a67e28a3bd45288051a587ba899cd
@@ -55,7 +55,7 @@ F src/os_win.c fe7b99cfcfb61d9bf54493ddf5857885a657fb89
 F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
 F src/pager.c 841a2cdddd4275de36cda26ed9dc54ae942660ce
 F src/pager.h 0d9153d6269d60d04af3dd84a0cc0a96253cf4a4
-F src/parse.y 72cd7553f05fbc7b63ea9476108d0da6237f2818
+F src/parse.y 562246a70c5e4a6bf1ed203119db0843bc926c11
 F src/pragma.c dea86dad2f0e872b29632ae9fba526e539a4ddd8
 F src/prepare.c d53602d2f8e097225ae7c76ec764ae68f759ba47
 F src/printf.c 3d20b21cfecadacecac3fb7274e746cb81d3d357
@@ -63,10 +63,10 @@ F src/random.c 90adff4e73a3b249eb4f1fc2a6ff9cf78c7233a4
 F src/select.c 28b752e58955c7920711fbdbfdcd369a2bd09448
 F src/shell.c 25b3217d7c64e6497225439d261a253a23efff26
 F src/sqlite.h.in e06d5774e9cfa5962376ae988300a9f114a3e3d7
-F src/sqliteInt.h c620e07e0c7e6e09d8623d165427f0f1f659aad5
+F src/sqliteInt.h 2135a5bab820af868bf308f51cdf1adbcb3a85b7
 F src/table.c 25b3ff2b39b7d87e8d4a5da0713d68dfc06cbee9
 F src/tclsqlite.c af0f002d9d6ab4f7f32b9bee5b57665946e76ad9
-F src/test1.c 5956d1c61b89d84c2b2ab01f065b1cd878917213
+F src/test1.c 96314a056763107646223779bcb2b987944944dd
 F src/test2.c 716c1809dba8e5be6093703e9cada99d627542dc
 F src/test3.c 683e1e3819152ffd35da2f201e507228921148d0
 F src/test4.c 7c6b9fc33dd1f3f93c7f1ee6e5e6d016afa6c1df
@@ -75,14 +75,14 @@ F src/tokenize.c 57ec9926612fb9e325b57a141303573bc20c79bf
 F src/trigger.c f51dec15921629591cb98bf2e350018e268b109a
 F src/update.c e96c7b342cd8903c672162f4cf84d2c737943347
 F src/utf.c bda5eb85039ef16f2d17004c1e18c96e1ab0a80c
-F src/util.c 1cdce9ae9fd17307e00848d63e3bc3300ca7c9fc
+F src/util.c 54d5b4d56f0d14d4ff60881b145d1d3d664bb623
 F src/vacuum.c 829d9e1a6d7c094b80e0899686670932eafd768c
-F src/vdbe.c 5c1f7ccd6a75aa2cf211a9864ff511e15e86957c
+F src/vdbe.c 56e892e351eb3ed634c3c239e4ad5c03aecfc2bf
 F src/vdbe.h 75e466d84d362b0c4498978a9d6b1e6bd32ecf3b
 F src/vdbeInt.h 4312faf41630a6c215924b6c7c2f39ebb1af8ffb
 F src/vdbeapi.c 5025a9163107e0a4964212d16e1c4defa13dc5c2
 F src/vdbeaux.c 38332d91887817a2146f46b58fff2a8a88ed0278
-F src/vdbemem.c 48a64ae95a9edc6e8d940300dad15d70d1670398
+F src/vdbemem.c da8e8d6f29dd1323f782f000d7cd120027c9ff03
 F src/where.c 3a9a2258ab3364655e9ea215ad5ae7bf41813f54
 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
 F test/all.test 7f0988442ab811dfa41793b5b550f5828ce316f3
@@ -112,6 +112,7 @@ F test/btree7.test a6d3b842db22af97dd14b989e90a2fd96066b72f
 F test/capi2.test f897209386fb21cfdc9267595e0c667ebaca9164
 F test/capi3.test 4d848cc55ad6e5f68cf2712716e9fc1fa55d7635
 F test/capi3b.test 5b6a66f9f295f79f443b5d3f33187fa5ef6cf336
+F test/cast.test 5c5ebb3edadb04eb0bb172d0e48d52642480e004
 F test/collate1.test f79736d2ebf5492167ee4d1f4ab4c09dda776b03
 F test/collate2.test 224a632ba04907c049804b08162efd234aa7871f
 F test/collate3.test 51362bdfb43a72bd2b087d90b2623b0695538e7a
@@ -132,7 +133,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 f5f9f2bd3f1121ae82eb4d6b3f48b8c52f597895
+F test/func.test b062105b45cf8fb5b386ba137180c0f439eea0c9
 F test/hook.test f8605cde4c77b2c6a4a73723bf6c507796a64dda
 F test/in.test ed134f8d477a6280297ced1646de83cccf8f196d
 F test/index.test 51e01a0928b4b61228917ddd8c6c0e2466547f6f
@@ -225,7 +226,7 @@ F tool/lempar.c f0c30abcae762a7d1eb37cd88b2232ab8dd625fb
 F tool/memleak.awk 4e7690a51bf3ed757e611273d43fe3f65b510133
 F tool/memleak2.awk 9cc20c8e8f3c675efac71ea0721ee6874a1566e8
 F tool/memleak3.tcl 009da0ea82dc5893edca76cf1a21fb7260e9412e
-F tool/mkkeywordhash.c 596389943f516bf6eaddd46659e7b87b16ea7c33
+F tool/mkkeywordhash.c e4ba5010348303b1dbab41326191e7f37f8a036f
 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
 F tool/report1.txt 9eae07f26a8fc53889b45fc833a66a33daa22816
@@ -264,7 +265,7 @@ F www/faq.tcl 49f31a703f74c71ce66da646aaf18b07a5042672
 F www/fileformat.tcl 900c95b9633abc3dcfc384d9ddd8eb4876793059
 F www/formatchng.tcl 053ddb73646701353a5b1c9ca6274d5900739b45
 F www/index.tcl 9527f4eed69739cf5f81b3d75e0478d1c84d0a8a
-F www/lang.tcl 727b4769fbad2727b0f867acaeb8706d554edb35
+F www/lang.tcl be57d5f23a46b8afa3753b38f65ea22d26499b80
 F www/lockingv3.tcl f59b19d6c8920a931f096699d6faaf61c05db55f
 F www/mingw.tcl d96b451568c5d28545fefe0c80bee3431c73f69c
 F www/nulls.tcl ec35193f92485b87b90a994a01d0171b58823fcf
@@ -281,7 +282,7 @@ F www/tclsqlite.tcl 425be741b8ae664f55cb1ef2371aab0a75109cf9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
 F www/whentouse.tcl 528299b8316726dbcc5548e9aa0648c8b1bd055b
-P bcf62dc7a1e8e7a3180138cf9b8944eb8fbd5490
-R fa67143595d3d7217f6f8facb2f20078
+P 06a71b162b032fc5b56d18919a784d4ee94dde7c
+R 232a3463ca338974c39f0662b7bf2007
 U drh
-Z 382ef1453175c5aaab493342b42488e6
+Z 47d0af1509bc0a39043a3f760e0ac13b
index d8b0fd2cd56dfdaf5a416a2ce9ff6576d02d2c8f..de827addf7f4e502c80933c4822f43792c28db29 100644 (file)
@@ -1 +1 @@
-06a71b162b032fc5b56d18919a784d4ee94dde7c
\ No newline at end of file
+17631785f9ee8ab280c82677eb53886912e085bc
\ No newline at end of file
index e0a6e5953b4ba5dcd220158f31882076fdac4660..d9d5bb43ba8c63f4aa17ba1e1082fe9fdd0cf91f 100644 (file)
@@ -22,7 +22,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.328 2005/06/24 03:53:06 drh Exp $
+** $Id: build.c,v 1.329 2005/06/25 18:42:14 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -902,11 +902,11 @@ void sqlite3AddNotNull(Parse *pParse, int onError){
 ** If none of the substrings in the above table are found,
 ** SQLITE_AFF_NUMERIC is returned.
 */
-static char sqlite3AffinityType(const char *zType, int nType){
+char sqlite3AffinityType(const Token *pType){
   u32 h = 0;
   char aff = SQLITE_AFF_NUMERIC;
-  const unsigned char *zIn = zType;
-  const unsigned char *zEnd = (zIn+nType);
+  const unsigned char *zIn = pType->z;
+  const unsigned char *zEnd = &pType->z[pType->n];
 
   while( zIn!=zEnd ){
     h = (h<<8) + sqlite3UpperToLower[*zIn];
@@ -938,21 +938,17 @@ static char sqlite3AffinityType(const char *zType, int nType){
 ** that contains the typename of the column and store that string
 ** in zType.
 */ 
-void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){
+void sqlite3AddColumnType(Parse *pParse, Token *pType){
   Table *p;
-  int i, j;
-  int n;
-  char *z;
-  const unsigned char *zIn;
-
+  int i;
   Column *pCol;
+
   if( (p = pParse->pNewTable)==0 ) return;
   i = p->nCol-1;
   if( i<0 ) return;
   pCol = &p->aCol[i];
-  zIn = pFirst->z;
-  n = pLast->n + (pLast->z - zIn);
   assert( pCol->zType==0 );
+#if 0
   z = pCol->zType = sqliteMallocRaw(n+1);
   if( z==0 ) return;
   for(i=j=0; i<n; i++){
@@ -961,7 +957,9 @@ void sqlite3AddColumnType(Parse *pParse, Token *pFirst, Token *pLast){
     z[j++] = c;
   }
   z[j] = 0;
-  pCol->affinity = sqlite3AffinityType(z, n);
+#endif
+  pCol->zType = sqlite3NameFromToken(pType);
+  pCol->affinity = sqlite3AffinityType(pType);
 }
 
 /*
index 52075691616bafb4b626e605f5d33b9aa22ce466..35c0bf64a8319857fbdd6ed462e51aa07e1ca135 100644 (file)
@@ -16,7 +16,7 @@
 ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: date.c,v 1.44 2005/03/21 00:43:44 drh Exp $
+** $Id: date.c,v 1.45 2005/06/25 18:42:14 drh Exp $
 **
 ** NOTES:
 **
@@ -124,11 +124,7 @@ static int getDigits(const char *zDate, ...){
 ** Read text from z[] and convert into a floating point number.  Return
 ** the number of digits converted.
 */
-static int getValue(const char *z, double *pR){
-  const char *zEnd;
-  *pR = sqlite3AtoF(z, &zEnd);
-  return zEnd - z;
-}
+#define getValue sqlite3AtoF
 
 /*
 ** Parse a timezone extension on the end of a date-time.
@@ -320,7 +316,7 @@ static int parseDateOrTime(const char *zDate, DateTime *p){
     p->validJD = 1;
     return 0;
   }else if( sqlite3IsNumber(zDate, 0, SQLITE_UTF8) ){
-    p->rJD = sqlite3AtoF(zDate, 0);
+    getValue(zDate, &p->rJD);
     p->validJD = 1;
     return 0;
   }
index 4f21800e55ca6c4636124d52475aa3023d9da23d..efac9776609c8be86767b1a03aca2d0e97e0a4eb 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.207 2005/06/22 08:48:06 drh Exp $
+** $Id: expr.c,v 1.208 2005/06/25 18:42:14 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
 ** SELECT * FROM t1 WHERE (select a from t1);
 */
 char sqlite3ExprAffinity(Expr *pExpr){
-  if( pExpr->op==TK_AS ){
+  int op = pExpr->op;
+  if( op==TK_AS ){
     return sqlite3ExprAffinity(pExpr->pLeft);
   }
-  if( pExpr->op==TK_SELECT ){
+  if( op==TK_SELECT ){
     return sqlite3ExprAffinity(pExpr->pSelect->pEList->a[0].pExpr);
   }
+#ifndef SQLITE_OMIT_CAST
+  if( op==TK_CAST ){
+    return sqlite3AffinityType(&pExpr->token);
+  }
+#endif
   return pExpr->affinity;
 }
 
@@ -51,7 +57,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
   CollSeq *pColl = 0;
   if( pExpr ){
     pColl = pExpr->pColl;
-    if( pExpr->op==TK_AS && !pColl ){
+    if( (pExpr->op==TK_AS || pExpr->op==TK_CAST) && !pColl ){
       return sqlite3ExprCollSeq(pParse, pExpr->pLeft);
     }
   }
@@ -1427,6 +1433,22 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
       sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iTable, 0);
       break;
     }
+#ifndef SQLITE_OMIT_CAST
+    case TK_CAST: {
+      /* Expressions of the form:   CAST(pLeft AS token) */
+      int aff, op;
+      sqlite3ExprCode(pParse, pExpr->pLeft);
+      aff = sqlite3AffinityType(&pExpr->token);
+      switch( aff ){
+        case SQLITE_AFF_INTEGER:   op = OP_ToInt;      break;
+        case SQLITE_AFF_NUMERIC:   op = OP_ToNumeric;  break;
+        case SQLITE_AFF_TEXT:      op = OP_ToText;     break;
+        case SQLITE_AFF_NONE:      op = OP_ToBlob;     break;
+      }
+      sqlite3VdbeAddOp(v, op, 0, 0);
+      break;
+    }
+#endif /* SQLITE_OMIT_CAST */
     case TK_LT:
     case TK_LE:
     case TK_GT:
index d13ba437cb0cfa65e9252015ea145f64c1de2f5f..7e8feadc0dc7ff9569e898b63e175271ff901ed8 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.99 2005/06/22 10:53:59 drh Exp $
+** $Id: func.c,v 1.100 2005/06/25 18:42:14 drh Exp $
 */
 #include "sqliteInt.h"
 #include <ctype.h>
@@ -78,92 +78,6 @@ 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
@@ -1058,9 +972,6 @@ 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 1f7c8af33381588e5480514c9fe09ff2a2be4771..bcb0014a33ef480111f6bd6f61cfde583f6e9996 100644 (file)
 ** the parser.  Lemon will also generate a header file containing
 ** numeric codes for all of the tokens.
 **
-** @(#) $Id: parse.y,v 1.172 2005/05/23 17:26:51 drh Exp $
+** @(#) $Id: parse.y,v 1.173 2005/06/25 18:42:14 drh Exp $
 */
+
+// All token codes are small integers with #defines that begin with "TK_"
 %token_prefix TK_
+
+// The type of the data attached to each token is Token.  This is also the
+// default type for non-terminals.
+//
 %token_type {Token}
 %default_type {Token}
+
+// The generated parser function takes a 4th argument as follows:
 %extra_argument {Parse *pParse}
+
+// This code runs whenever there is a syntax error
+//
 %syntax_error {
   if( pParse->zErrMsg==0 ){
     if( TOKEN.z[0] ){
     }
   }
 }
+
+// The name of the generated procedure that implements the parser
+// is as follows:
 %name sqlite3Parser
+
+// The following text is included near the beginning of the C source
+// code file that implements the parser.
+//
 %include {
 #include "sqliteInt.h"
 #include "parse.h"
@@ -126,9 +144,10 @@ create_table_args ::= AS select(S). {
 columnlist ::= columnlist COMMA column.
 columnlist ::= column.
 
-// About the only information used for a column is the name of the
-// column.  The type is always just "text".  But the code will accept
-// an elaborate typename.  Perhaps someday we'll do something with it.
+// A "column" is a complete description of a single column in a
+// CREATE TABLE statement.  This includes the column name, its
+// datatype, and other keywords such as PRIMARY KEY, UNIQUE, REFERENCES,
+// NOT NULL and so forth.
 //
 column(A) ::= columnid(X) type carglist. {
   A.z = X.z;
@@ -151,7 +170,7 @@ id(A) ::= ID(X).         {A = X;}
 // This obviates the need for the "id" nonterminal.
 //
 %fallback ID
-  ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CONFLICT
+  ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CAST CONFLICT
   DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL FOR
   IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH KEY
   OF OFFSET PRAGMA RAISE REPLACE RESTRICT ROW STATEMENT
@@ -198,17 +217,32 @@ nm(A) ::= ID(X).         {A = X;}
 nm(A) ::= STRING(X).     {A = X;}
 nm(A) ::= JOIN_KW(X).    {A = X;}
 
+// A typetoken is really one or more tokens that form a type name such
+// as can be found after the column name in a CREATE TABLE statement.
+// Multiple tokens are concatenated to form the value of the typetoken.
+//
+%type typetoken {Token}
 type ::= .
-type ::= typename(X).                    {sqlite3AddColumnType(pParse,&X,&X);}
-type ::= typename(X) LP signed RP(Y).    {sqlite3AddColumnType(pParse,&X,&Y);}
-type ::= typename(X) LP signed COMMA signed RP(Y).
-                                         {sqlite3AddColumnType(pParse,&X,&Y);}
+type ::= typetoken(X).                   {sqlite3AddColumnType(pParse,&X);}
+typetoken(A) ::= typename(X).   {A = X;}
+typetoken(A) ::= typename(X) LP signed RP(Y). {
+  A.z = X.z;
+  A.n = &Y.z[Y.n] - X.z;
+}
+typetoken(A) ::= typename(X) LP signed COMMA signed RP(Y). {
+  A.z = X.z;
+  A.n = &Y.z[Y.n] - X.z;
+}
 %type typename {Token}
 typename(A) ::= ids(X).             {A = X;}
 typename(A) ::= typename(X) ids(Y). {A.z=X.z; A.n=Y.n+(Y.z-X.z);}
 %type signed {int}
 signed(A) ::= plus_num(X).    { A = atoi(X.z); }
 signed(A) ::= minus_num(X).   { A = -atoi(X.z); }
+
+// "carglist" is a list of additional constraints that come after the
+// column name and column type in a CREATE TABLE statement.
+//
 carglist ::= carglist carg.
 carglist ::= .
 carg ::= CONSTRAINT nm ccons.
@@ -619,6 +653,12 @@ expr(A) ::= VARIABLE(X).     {
   Expr *pExpr = A = sqlite3Expr(TK_VARIABLE, 0, 0, pToken);
   sqlite3ExprAssignVarNumber(pParse, pExpr);
 }
+%ifndef SQLITE_OMIT_CAST
+expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). {
+  A = sqlite3Expr(TK_CAST, E, 0, &T);
+  sqlite3ExprSpan(A,&X,&Y);
+}
+%endif // SQLITE_OMIT_CAST
 expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
   A = sqlite3ExprFunction(Y, &X);
   sqlite3ExprSpan(A,&X,&E);
index 966090dc0e981baa2ad0c7c6db09adeb0645c193..cac864c430b2fbf41f52587018c8894f0bc61af6 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.387 2005/06/12 21:35:52 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.388 2005/06/25 18:42:14 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -1369,7 +1369,7 @@ void sqlite3StartTable(Parse*,Token*,Token*,Token*,int,int);
 void sqlite3AddColumn(Parse*,Token*);
 void sqlite3AddNotNull(Parse*, int);
 void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int);
-void sqlite3AddColumnType(Parse*,Token*,Token*);
+void sqlite3AddColumnType(Parse*,Token*);
 void sqlite3AddDefaultValue(Parse*,Expr*);
 void sqlite3AddCollateType(Parse*, const char*, int);
 void sqlite3EndTable(Parse*,Token*,Token*,Select*);
@@ -1508,7 +1508,7 @@ int sqlite3FixSelect(DbFixer*, Select*);
 int sqlite3FixExpr(DbFixer*, Expr*);
 int sqlite3FixExprList(DbFixer*, ExprList*);
 int sqlite3FixTriggerStep(DbFixer*, TriggerStep*);
-double sqlite3AtoF(const char *z, const char **);
+int sqlite3AtoF(const char *z, double*);
 char *sqlite3_snprintf(int,char*,const char*,...);
 int sqlite3GetInt32(const char *, int*);
 int sqlite3FitsIn64Bits(const char *);
@@ -1563,6 +1563,7 @@ void sqlite3AlterFinishAddColumn(Parse *, Token *);
 void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
 const char *sqlite3TestErrorName(int);
 CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char *, int);
+char sqlite3AffinityType(const Token*);
 
 #ifdef SQLITE_SSE
 #include "sseInt.h"
index 73159910f26ef2ef61fe293a3d028a12ad5d0da6..dd7e06cd929651b664f101bbd6bc8a6908a037d9 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.144 2005/06/12 22:01:43 drh Exp $
+** $Id: test1.c,v 1.145 2005/06/25 18:42:14 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -2794,6 +2794,12 @@ static void set_options(Tcl_Interp *interp){
   Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY);
 #endif
 
+#ifdef SQLITE_OMIT_CAST
+  Tcl_SetVar2(interp, "sqlite_options", "cast", "0", TCL_GLOBAL_ONLY);
+#else
+  Tcl_SetVar2(interp, "sqlite_options", "cast", "1", TCL_GLOBAL_ONLY);
+#endif
+
 #ifdef SQLITE_OMIT_COMPLETE
   Tcl_SetVar2(interp, "sqlite_options", "complete", "0", TCL_GLOBAL_ONLY);
 #else
index 23794123eaf0326746630a76b18769e26c94d65f..80fc41da26878d4a22b6817e24a590b5126abd38 100644 (file)
@@ -14,7 +14,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.137 2005/06/14 16:04:06 drh Exp $
+** $Id: util.c,v 1.138 2005/06/25 18:42:15 drh Exp $
 */
 #include "sqliteInt.h"
 #include <stdarg.h>
@@ -565,8 +565,9 @@ int sqlite3IsNumber(const char *z, int *realnum, u8 enc){
 ** of "." depending on how locale is set.  But that would cause problems
 ** for SQL.  So this routine always uses "." regardless of locale.
 */
-double sqlite3AtoF(const char *z, const char **pzEnd){
+int sqlite3AtoF(const char *z, double *pResult){
   int sign = 1;
+  const char *zBegin = z;
   LONGDOUBLE_TYPE v1 = 0.0;
   if( *z=='-' ){
     sign = -1;
@@ -613,8 +614,8 @@ double sqlite3AtoF(const char *z, const char **pzEnd){
       v1 *= scale;
     }
   }
-  if( pzEnd ) *pzEnd = z;
-  return sign<0 ? -v1 : v1;
+  *pResult = sign<0 ? -v1 : v1;
+  return z - zBegin;
 }
 
 /*
index 4d0124153a7767ff1895dc2eb18a9fdc8273a2ff..15305116c3d784fd2db64f9f44b3e5246447bb0a 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.471 2005/06/24 03:53:06 drh Exp $
+** $Id: vdbe.c,v 1.472 2005/06/25 18:42:15 drh Exp $
 */
 #include "sqliteInt.h"
 #include "os.h"
@@ -1379,6 +1379,94 @@ case OP_MustBeInt: {            /* no-push */
   break;
 }
 
+#ifndef SQLITE_OMIT_CAST
+/* Opcode: ToInt * * *
+**
+** Force the value on the top of the stack to be an integer.  If
+** The value is currently a real number, drop its fractional part.
+** If the value is text or blob, try to convert it to an integer using the
+** equivalent of atoi() and store 0 if no such conversion is possible.
+**
+** A NULL value is not changed by this routine.  It remains NULL.
+*/
+case OP_ToInt: {                  /* no-push */
+  assert( pTos>=p->aStack );
+  if( pTos->flags & MEM_Null ) break;
+  assert( MEM_Str==(MEM_Blob>>3) );
+  pTos->flags |= (pTos->flags&MEM_Blob)>>3;
+  applyAffinity(pTos, SQLITE_AFF_INTEGER, db->enc);
+  sqlite3VdbeMemIntegerify(pTos);
+  break;
+}
+
+/* Opcode: ToNumeric * * *
+**
+** Force the value on the top of the stack to be numeric (either an
+** integer or a floating-point number.
+** If the value is text or blob, try to convert it to an using the
+** equivalent of atoi() or atof() and store 0 if no such conversion 
+** is possible.
+**
+** A NULL value is not changed by this routine.  It remains NULL.
+*/
+case OP_ToNumeric: {                  /* no-push */
+  assert( pTos>=p->aStack );
+  if( pTos->flags & MEM_Null ) break;
+  assert( MEM_Str==(MEM_Blob>>3) );
+  pTos->flags |= (pTos->flags&MEM_Blob)>>3;
+  applyAffinity(pTos, SQLITE_AFF_NUMERIC, db->enc);
+  if( (pTos->flags & (MEM_Int|MEM_Real))==0 ){
+    sqlite3VdbeMemRealify(pTos);
+  }else{
+    sqlite3VdbeMemRelease(pTos);
+  }
+  assert( (pTos->flags & MEM_Dyn)==0 );
+  pTos->flags &= (MEM_Int|MEM_Real);
+  break;
+}
+
+/* Opcode: ToText * * *
+**
+** Force the value on the top of the stack to be text.
+** If the value is numeric, convert it to an using the
+** equivalent of printf().  Blob values are unchanged and
+** are afterwards simply interpreted as text.
+**
+** A NULL value is not changed by this routine.  It remains NULL.
+*/
+case OP_ToText: {                  /* no-push */
+  assert( pTos>=p->aStack );
+  if( pTos->flags & MEM_Null ) break;
+  assert( MEM_Str==(MEM_Blob>>3) );
+  pTos->flags |= (pTos->flags&MEM_Blob)>>3;
+  applyAffinity(pTos, SQLITE_AFF_TEXT, db->enc);
+  assert( pTos->flags & MEM_Str );
+  pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Blob);
+  break;
+}
+
+/* Opcode: ToBlob * * *
+**
+** Force the value on the top of the stack to be a BLOB.
+** If the value is numeric, convert it to a string first.
+** Strings are simply reinterpreted as blobs with no change
+** to the underlying data.
+**
+** A NULL value is not changed by this routine.  It remains NULL.
+*/
+case OP_ToBlob: {                  /* no-push */
+  assert( pTos>=p->aStack );
+  if( pTos->flags & MEM_Null ) break;
+  if( (pTos->flags & MEM_Blob)==0 ){
+    applyAffinity(pTos, SQLITE_AFF_TEXT, db->enc);
+    assert( pTos->flags & MEM_Str );
+    pTos->flags |= MEM_Blob;
+  }
+  pTos->flags &= ~(MEM_Int|MEM_Real|MEM_Str);
+  break;
+}
+#endif /* SQLITE_OMIT_CAST */
+
 /* Opcode: Eq P1 P2 P3
 **
 ** Pop the top two elements from the stack.  If they are equal, then
@@ -2154,6 +2242,7 @@ case OP_MakeRecord: {
     pTos->flags = MEM_Blob | MEM_Dyn;
     pTos->xDel = 0;
   }
+  pTos->enc = SQLITE_UTF8;  /* In case the blob is ever converted to text */
 
   /* If a NULL was encountered and jumpIfNull is non-zero, take the jump. */
   if( jumpIfNull && containsNull ){
@@ -3289,6 +3378,7 @@ case OP_RowData: {
   }else{
     pTos->flags = MEM_Null;
   }
+  pTos->enc = SQLITE_UTF8;  /* In case the blob is ever cast to text */
   break;
 }
 
index f08671f249c473e9b92f783347857018134578a9..37113b90d85e724685dead0eb8446d59fc980128 100644 (file)
@@ -256,12 +256,14 @@ double sqlite3VdbeRealValue(Mem *pMem){
   }else if( pMem->flags & MEM_Int ){
     return (double)pMem->i;
   }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
+    double val = 0.0;
     if( sqlite3VdbeChangeEncoding(pMem, SQLITE_UTF8)
        || sqlite3VdbeMemNulTerminate(pMem) ){
       return SQLITE_NOMEM;
     }
     assert( pMem->z );
-    return sqlite3AtoF(pMem->z, 0);
+    sqlite3AtoF(pMem->z, &val);
+    return val;
   }else{
     return 0.0;
   }
@@ -406,6 +408,7 @@ int sqlite3VdbeMemSetStr(
   switch( enc ){
     case 0:
       pMem->flags |= MEM_Blob;
+      pMem->enc = SQLITE_UTF8;
       break;
 
     case SQLITE_UTF8:
diff --git a/test/cast.test b/test/cast.test
new file mode 100644 (file)
index 0000000..04a36c4
--- /dev/null
@@ -0,0 +1,184 @@
+# 2001 September 15
+#
+# The author disclaims copyright to this source code.  In place of
+# a legal notice, here is a blessing:
+#
+#    May you do good and not evil.
+#    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 the CAST operator.
+#
+# $Id: cast.test,v 1.1 2005/06/25 18:42:16 drh Exp $
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+# Only run these tests if the build includes the CAST operator
+ifcapable !cast {
+  finish_test
+  return
+}
+
+# Tests for the CAST( AS blob), CAST( AS text) and CAST( AS numeric) built-ins
+#
+do_test cast-1.1 {
+  execsql {SELECT x'616263'}
+} abc
+do_test cast-1.2 {
+  execsql {SELECT typeof(x'616263')}
+} blob
+do_test cast-1.3 {
+  execsql {SELECT CAST(x'616263' AS text)}
+} abc
+do_test cast-1.4 {
+  execsql {SELECT typeof(CAST(x'616263' AS text))}
+} text
+do_test cast-1.5 {
+  execsql {SELECT CAST(x'616263' AS numeric)}
+} 0.0
+do_test cast-1.6 {
+  execsql {SELECT typeof(CAST(x'616263' AS numeric))}
+} real
+do_test cast-1.7 {
+  execsql {SELECT CAST(x'616263' AS blob)}
+} abc
+do_test cast-1.8 {
+  execsql {SELECT typeof(CAST(x'616263' AS blob))}
+} blob
+do_test cast-1.9 {
+  execsql {SELECT CAST(x'616263' AS integer)}
+} 0
+do_test cast-1.10 {
+  execsql {SELECT typeof(CAST(x'616263' AS integer))}
+} integer
+do_test cast-1.11 {
+  execsql {SELECT null}
+} {{}}
+do_test cast-1.12 {
+  execsql {SELECT typeof(NULL)}
+} null
+do_test cast-1.13 {
+  execsql {SELECT CAST(NULL AS text)}
+} {{}}
+do_test cast-1.14 {
+  execsql {SELECT typeof(CAST(NULL AS text))}
+} null
+do_test cast-1.15 {
+  execsql {SELECT CAST(NULL AS numeric)}
+} {{}}
+do_test cast-1.16 {
+  execsql {SELECT typeof(CAST(NULL AS numeric))}
+} null
+do_test cast-1.17 {
+  execsql {SELECT CAST(NULL AS blob)}
+} {{}}
+do_test cast-1.18 {
+  execsql {SELECT typeof(CAST(NULL AS blob))}
+} null
+do_test cast-1.19 {
+  execsql {SELECT CAST(NULL AS integer)}
+} {{}}
+do_test cast-1.20 {
+  execsql {SELECT typeof(CAST(NULL AS integer))}
+} null
+do_test cast-1.21 {
+  execsql {SELECT 123}
+} {123}
+do_test cast-1.22 {
+  execsql {SELECT typeof(123)}
+} integer
+do_test cast-1.23 {
+  execsql {SELECT CAST(123 AS text)}
+} {123}
+do_test cast-1.24 {
+  execsql {SELECT typeof(CAST(123 AS text))}
+} text
+do_test cast-1.25 {
+  execsql {SELECT CAST(123 AS numeric)}
+} 123
+do_test cast-1.26 {
+  execsql {SELECT typeof(CAST(123 AS numeric))}
+} integer
+do_test cast-1.27 {
+  execsql {SELECT CAST(123 AS blob)}
+} {123}
+do_test cast-1.28 {
+  execsql {SELECT typeof(CAST(123 AS blob))}
+} blob
+do_test cast-1.29 {
+  execsql {SELECT CAST(123 AS integer)}
+} {123}
+do_test cast-1.30 {
+  execsql {SELECT typeof(CAST(123 AS integer))}
+} integer
+do_test cast-1.31 {
+  execsql {SELECT 123.456}
+} {123.456}
+do_test cast-1.32 {
+  execsql {SELECT typeof(123.456)}
+} real
+do_test cast-1.33 {
+  execsql {SELECT CAST(123.456 AS text)}
+} {123.456}
+do_test cast-1.34 {
+  execsql {SELECT typeof(CAST(123.456 AS text))}
+} text
+do_test cast-1.35 {
+  execsql {SELECT CAST(123.456 AS numeric)}
+} 123.456
+do_test cast-1.36 {
+  execsql {SELECT typeof(CAST(123.456 AS numeric))}
+} real
+do_test cast-1.37 {
+  execsql {SELECT CAST(123.456 AS blob)}
+} {123.456}
+do_test cast-1.38 {
+  execsql {SELECT typeof(CAST(123.456 AS blob))}
+} blob
+do_test cast-1.39 {
+  execsql {SELECT CAST(123.456 AS integer)}
+} {123}
+do_test cast-1.38 {
+  execsql {SELECT typeof(CAST(123.456 AS integer))}
+} integer
+do_test cast-1.41 {
+  execsql {SELECT '123abc'}
+} {123abc}
+do_test cast-1.42 {
+  execsql {SELECT typeof('123abc')}
+} text
+do_test cast-1.43 {
+  execsql {SELECT CAST('123abc' AS text)}
+} {123abc}
+do_test cast-1.44 {
+  execsql {SELECT typeof(CAST('123abc' AS text))}
+} text
+do_test cast-1.45 {
+  execsql {SELECT CAST('123abc' AS numeric)}
+} 123.0
+do_test cast-1.46 {
+  execsql {SELECT typeof(CAST('123abc' AS numeric))}
+} real
+do_test cast-1.47 {
+  execsql {SELECT CAST('123abc' AS blob)}
+} {123abc}
+do_test cast-1.48 {
+  execsql {SELECT typeof(CAST('123abc' AS blob))}
+} blob
+do_test cast-1.49 {
+  execsql {SELECT CAST('123abc' AS integer)}
+} 123
+do_test cast-1.50 {
+  execsql {SELECT typeof(CAST('123abc' AS integer))}
+} integer
+do_test cast-1.51 {
+  execsql {SELECT CAST('123.5abc' AS numeric)}
+} 123.5
+do_test cast-1.53 {
+  execsql {SELECT CAST('123.5abc' AS integer)}
+} 123
+
+finish_test
index ab8b6f6df78dcca1565f53d7ef099f25d0a845ce..d8e5c3f09d35280abedea01a9fa553292524e520 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.35 2005/06/22 10:53:59 drh Exp $
+# $Id: func.test,v 1.36 2005/06/25 18:42:16 drh Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -485,134 +485,6 @@ do_test func-16.1 {
   }
 } {X'616263' NULL}
 
-# 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
index 5d3425709155d622bcfcb267fc8b09455057fee0..44cff22ce1378005a27009b03919f4f65ddb9ac8 100644 (file)
@@ -95,6 +95,11 @@ struct Keyword {
 #else
 #  define VIEW       16384
 #endif
+#ifdef SQLITE_OMIT_CAST
+#  define CAST       0
+#else
+#  define CAST       32768
+#endif
 
 
 /*
@@ -117,6 +122,7 @@ static Keyword aKeywordTable[] = {
   { "BY",               "TK_BY",           ALWAYS                 },
   { "CASCADE",          "TK_CASCADE",      FKEY                   },
   { "CASE",             "TK_CASE",         ALWAYS                 },
+  { "CAST",             "TK_CAST",         CAST                   },
   { "CHECK",            "TK_CHECK",        ALWAYS                 },
   { "COLLATE",          "TK_COLLATE",      ALWAYS                 },
   { "COLUMN",           "TK_COLUMNKW",     ALTER                  },
index 9a0b0e19829f03059a6cb1ea363bb719abeadfa2..2deac5439ff394a9bf4a99b67a3b76dab17a2fa8 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Run this Tcl script to generate the lang-*.html files.
 #
-set rcsid {$Id: lang.tcl,v 1.90 2005/05/10 16:11:41 drh Exp $}
+set rcsid {$Id: lang.tcl,v 1.91 2005/06/25 18:42:16 drh Exp $}
 source common.tcl
 
 if {[llength $argv]>0} {
@@ -1099,7 +1099,7 @@ all arguments are NULL then NULL is returned.  There must be at least
 <a href="capi3ref.html#sqlite3_create_function">sqlite3_create_function()</a> 
 interface can
 be used to override this function and thereby change the operation
-of the <a href="#glob">GLOB</a> operator.</td>
+of the <a href="#globFunc">GLOB</a> operator.</td>
 </tr>
 
 <tr>