1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Remove dataType and includeTypes flags from function definitions. Added new

P3_FUNCDEF type for P3 arguments on opcodes.  Fixes to several user functions.
28 tests fail now. (CVS 1464)

FossilOrigin-Name: 36e031625995b2f7baf7654d771ca8fb764a0085
This commit is contained in:
drh
2004-05-26 16:54:42 +00:00
parent b77f5dadbf
commit f9b596ebc0
13 changed files with 271 additions and 291 deletions

View File

@@ -1,5 +1,5 @@
C Ensure\sthe\stype\sof\san\ssqlite3_value*\sis\snot\smodified\sby\scalls\sto\nsqlite3_value_*()\scalls.\s(CVS\s1463) C Remove\sdataType\sand\sincludeTypes\sflags\sfrom\sfunction\sdefinitions.\s\sAdded\snew\nP3_FUNCDEF\stype\sfor\sP3\sarguments\son\sopcodes.\s\sFixes\sto\sseveral\suser\sfunctions.\n28\stests\sfail\snow.\s(CVS\s1464)
D 2004-05-26T13:27:00 D 2004-05-26T16:54:42
F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -28,16 +28,16 @@ F src/btree.c 6db76fbf63efd6008c5e6cb038ea40f94abffcf7
F src/btree.h b65140b5ae891f30d2a39e64b9f0343225553545 F src/btree.h b65140b5ae891f30d2a39e64b9f0343225553545
F src/build.c 35cbeb439b49cca5eb5e8a1de010a5194f4523e8 F src/build.c 35cbeb439b49cca5eb5e8a1de010a5194f4523e8
F src/copy.c 6eb7cc08ae6dc60bf83ecadf4508a0bef909dbd2 F src/copy.c 6eb7cc08ae6dc60bf83ecadf4508a0bef909dbd2
F src/date.c 1a6a72549e1eb8454b8bacb1734892cdcd78cebb F src/date.c 37bb5784da38457d0762281e0176b27e5aa00cf5
F src/delete.c 66c5ab98cbad7e6b315fc997bfe6c8080784a701 F src/delete.c 66c5ab98cbad7e6b315fc997bfe6c8080784a701
F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37 F src/encode.c a876af473d1d636faa3dca51c7571f2e007eea37
F src/expr.c 5b283e68bd6df365b7c2ad10bd04cc54c2b4b07c F src/expr.c 90573f18f946c94848d5ca1c925a141ef5dfe111
F src/func.c ddd86cbd438e385123785b67bd6c37a40a3c92bd F src/func.c 6274bceb41a032ff60297a992f54861e9d63cb20
F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f F src/hash.c 440c2f8cb373ee1b4e13a0988489c7cd95d55b6f
F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb F src/hash.h 762d95f1e567664d1eafc1687de755626be962fb
F src/insert.c dd117e8b3f50e943e6cf5fbcf4bbdc0b907b0b4c F src/insert.c dd117e8b3f50e943e6cf5fbcf4bbdc0b907b0b4c
F src/legacy.c a856d2d5317ed2ac93c2c6cbba7d4faa564a5b20 F src/legacy.c a856d2d5317ed2ac93c2c6cbba7d4faa564a5b20
F src/main.c 6a583e9d92dbc5b1371c3a4a35c398e5253327a5 F src/main.c 488ec788a06019521e53ffd25c4af97943937fb5
F src/md5.c 833671b541a76fc0e62404433c9176706eeacdf0 F src/md5.c 833671b541a76fc0e62404433c9176706eeacdf0
F src/os.h ab42f4a7c4c716f26b988e759b6e12085a3bfc67 F src/os.h ab42f4a7c4c716f26b988e759b6e12085a3bfc67
F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f F src/os_common.h 744286a27de55c52f1b18921e8d17abbf7fafc0f
@@ -53,12 +53,12 @@ F src/parse.y 567718866b94d58a6c7681cc45ba7987771d583a
F src/pragma.c f2b05b087a5764802296a28d7abdd75728beedee F src/pragma.c f2b05b087a5764802296a28d7abdd75728beedee
F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53 F src/printf.c ef750e8e2398ca7e8b58be991075f08c6a7f0e53
F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3 F src/random.c eff68e3f257e05e81eae6c4d50a51eb88beb4ff3
F src/select.c 53f1aea3fabf51d22e6efa5662ccd7b0b7368179 F src/select.c e90e2a147273cdcdb1ee9e14574ab28f04382e63
F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f F src/shell.c ed4d237b3e52a0a42512bfcc53530e46de20c28f
F src/sqlite.h.in c36ab3d4dc1b863ba0cf79905210180b8059a839 F src/sqlite.h.in 91a42246b390974361fdf8daf273d6c3bbf95e85
F src/sqliteInt.h 323281bd04c7f988c6873777750acaa1f6b3b9a6 F src/sqliteInt.h 6b0d8d856c4af325eb5a00d1c32d89aacf432875
F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2 F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
F src/tclsqlite.c 2700a35f494e8fc5ad2742bcae09d2cb66a295ab F src/tclsqlite.c b9386659cec1eac402ac7a2371deefe70709bf6a
F src/test1.c f8dacbbdfa206ed975c02842c52dee0c97952817 F src/test1.c f8dacbbdfa206ed975c02842c52dee0c97952817
F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872 F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968 F src/test3.c 5e4a6d596f982f6f47a5f9f75ede9b4a3b739968
@@ -70,10 +70,10 @@ F src/update.c 96461bcf4e946697e83c09c77c7e61b545a2f66e
F src/utf.c 1d38da85bffb928fb0d9f301e7db913a6df486ce F src/utf.c 1d38da85bffb928fb0d9f301e7db913a6df486ce
F src/util.c 4c0adcbc9ce6678dd046931253e45d623c6d279f F src/util.c 4c0adcbc9ce6678dd046931253e45d623c6d279f
F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad F src/vacuum.c 8734f89742f246abd91dbd3e087fc153bddbfbad
F src/vdbe.c 0853b13a1b799eb54a1f6bae3f17cb1a1fc76164 F src/vdbe.c a4b2f800137c652433b786537f1750ee769b2014
F src/vdbe.h 948cafed61e827967e07b44d51009c0e48ce168e F src/vdbe.h e73f890e0f2a6c42b183d7d6937947930fe4fdeb
F src/vdbeInt.h 1064ce1723c9c739772af2903e7e06ad2b214be1 F src/vdbeInt.h 1064ce1723c9c739772af2903e7e06ad2b214be1
F src/vdbeaux.c be599d276d25f04c5a8c26e8e270e3909f6c3c05 F src/vdbeaux.c 951985ea55c6bac6dcd0041ee652a4eec2a65b06
F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c F src/where.c efe5d25fe18cd7381722457898cd863e84097a0c
F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83 F test/attach.test cb9b884344e6cfa5e165965d5b1adea679a24c83
@@ -203,7 +203,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
P d5659f2ee6788e0205fb5e03eeaf64e6c0aa9bed P ce8b15203413f38a8b7127eb08ae5db1c1eb164a
R 0555bbc2774c833810e9e473c1000890 R d2e1633ebc6abb34ef4a297a6d817967
U danielk1977 U drh
Z c2aca9fbc64ca791014e235f1a4d9491 Z 933339c84dc9b3a3ef071d1cac60a7a8

View File

@@ -1 +1 @@
ce8b15203413f38a8b7127eb08ae5db1c1eb164a 36e031625995b2f7baf7654d771ca8fb764a0085

View File

@@ -16,7 +16,7 @@
** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
** All other code has file scope. ** All other code has file scope.
** **
** $Id: date.c,v 1.24 2004/05/26 06:18:37 danielk1977 Exp $ ** $Id: date.c,v 1.25 2004/05/26 16:54:42 drh Exp $
** **
** NOTES: ** NOTES:
** **
@@ -664,7 +664,11 @@ static int isDate(int argc, sqlite3_value **argv, DateTime *p){
** **
** Return the julian day number of the date specified in the arguments ** Return the julian day number of the date specified in the arguments
*/ */
static void juliandayFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void juliandayFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
DateTime x; DateTime x;
if( isDate(argc, argv, &x)==0 ){ if( isDate(argc, argv, &x)==0 ){
computeJD(&x); computeJD(&x);
@@ -677,7 +681,11 @@ static void juliandayFunc(sqlite3_context *context, int argc, sqlite3_value **ar
** **
** Return YYYY-MM-DD HH:MM:SS ** Return YYYY-MM-DD HH:MM:SS
*/ */
static void datetimeFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void datetimeFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
DateTime x; DateTime x;
if( isDate(argc, argv, &x)==0 ){ if( isDate(argc, argv, &x)==0 ){
char zBuf[100]; char zBuf[100];
@@ -693,7 +701,11 @@ static void datetimeFunc(sqlite3_context *context, int argc, sqlite3_value **arg
** **
** Return HH:MM:SS ** Return HH:MM:SS
*/ */
static void timeFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void timeFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
DateTime x; DateTime x;
if( isDate(argc, argv, &x)==0 ){ if( isDate(argc, argv, &x)==0 ){
char zBuf[100]; char zBuf[100];
@@ -708,7 +720,11 @@ static void timeFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
** **
** Return YYYY-MM-DD ** Return YYYY-MM-DD
*/ */
static void dateFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void dateFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
DateTime x; DateTime x;
if( isDate(argc, argv, &x)==0 ){ if( isDate(argc, argv, &x)==0 ){
char zBuf[100]; char zBuf[100];
@@ -737,7 +753,11 @@ static void dateFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
** %Y year 0000-9999 ** %Y year 0000-9999
** %% % ** %% %
*/ */
static void strftimeFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void strftimeFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
DateTime x; DateTime x;
int n, i, j; int n, i, j;
char *z; char *z;
@@ -852,15 +872,14 @@ void sqlite3RegisterDateTimeFunctions(sqlite *db){
static struct { static struct {
char *zName; char *zName;
int nArg; int nArg;
int dataType;
void (*xFunc)(sqlite3_context*,int,sqlite3_value**); void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
} aFuncs[] = { } aFuncs[] = {
#ifndef SQLITE_OMIT_DATETIME_FUNCS #ifndef SQLITE_OMIT_DATETIME_FUNCS
{ "julianday", -1, SQLITE_NUMERIC, juliandayFunc }, { "julianday", -1, juliandayFunc },
{ "date", -1, SQLITE_TEXT, dateFunc }, { "date", -1, dateFunc },
{ "time", -1, SQLITE_TEXT, timeFunc }, { "time", -1, timeFunc },
{ "datetime", -1, SQLITE_TEXT, datetimeFunc }, { "datetime", -1, datetimeFunc },
{ "strftime", -1, SQLITE_TEXT, strftimeFunc }, { "strftime", -1, strftimeFunc },
#endif #endif
}; };
int i; int i;
@@ -868,11 +887,5 @@ void sqlite3RegisterDateTimeFunctions(sqlite *db){
for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){ for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, 0, 0, 0, sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, 0, 0, 0,
aFuncs[i].xFunc, 0, 0); aFuncs[i].xFunc, 0, 0);
if( aFuncs[i].xFunc ){
sqlite3_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
}
} }
} }

View File

@@ -12,7 +12,7 @@
** This file contains routines used for analyzing expressions and ** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite. ** for generating VDBE code that evaluates expressions in SQLite.
** **
** $Id: expr.c,v 1.127 2004/05/21 13:39:51 drh Exp $ ** $Id: expr.c,v 1.128 2004/05/26 16:54:43 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include <ctype.h> #include <ctype.h>
@@ -503,7 +503,6 @@ int sqlite3IsRowid(const char *z){
** pExpr->iTable Set to the cursor number for the table obtained ** pExpr->iTable Set to the cursor number for the table obtained
** from pSrcList. ** from pSrcList.
** pExpr->iColumn Set to the column number within the table. ** pExpr->iColumn Set to the column number within the table.
** pExpr->dataType Set to the appropriate data type for the column.
** pExpr->op Set to TK_COLUMN. ** pExpr->op Set to TK_COLUMN.
** pExpr->pLeft Any expression this points to is deleted ** pExpr->pLeft Any expression this points to is deleted
** pExpr->pRight Any expression this points to is deleted. ** pExpr->pRight Any expression this points to is deleted.
@@ -1224,13 +1223,13 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
getFunctionName(pExpr, &zId, &nId); getFunctionName(pExpr, &zId, &nId);
pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, 0); pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, 0);
assert( pDef!=0 ); assert( pDef!=0 );
nExpr = sqlite3ExprCodeExprList(pParse, pList, pDef->includeTypes); nExpr = sqlite3ExprCodeExprList(pParse, pList);
/* FIX ME: The following is a temporary hack. */ /* FIX ME: The following is a temporary hack. */
if( 0==sqlite3StrNICmp(zId, "classof", nId) ){ if( 0==sqlite3StrNICmp(zId, "classof", nId) ){
assert( nExpr==1 ); assert( nExpr==1 );
sqlite3VdbeAddOp(v, OP_Class, nExpr, 0); sqlite3VdbeAddOp(v, OP_Class, nExpr, 0);
}else{ }else{
sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER); sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_FUNCDEF);
} }
break; break;
} }
@@ -1346,16 +1345,13 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
/* /*
** Generate code that pushes the value of every element of the given ** Generate code that pushes the value of every element of the given
** expression list onto the stack. If the includeTypes flag is true, ** expression list onto the stack.
** then also push a string that is the datatype of each element onto
** the stack after the value.
** **
** Return the number of elements pushed onto the stack. ** Return the number of elements pushed onto the stack.
*/ */
int sqlite3ExprCodeExprList( int sqlite3ExprCodeExprList(
Parse *pParse, /* Parsing context */ Parse *pParse, /* Parsing context */
ExprList *pList, /* The expression list to be coded */ ExprList *pList /* The expression list to be coded */
int includeTypes /* TRUE to put datatypes on the stack too */
){ ){
struct ExprList_item *pItem; struct ExprList_item *pItem;
int i, n; int i, n;
@@ -1365,12 +1361,8 @@ int sqlite3ExprCodeExprList(
n = pList->nExpr; n = pList->nExpr;
for(pItem=pList->a, i=0; i<n; i++, pItem++){ for(pItem=pList->a, i=0; i<n; i++, pItem++){
sqlite3ExprCode(pParse, pItem->pExpr); sqlite3ExprCode(pParse, pItem->pExpr);
if( includeTypes ){
/** DEPRECATED. This will go away with the new function interface **/
sqlite3VdbeOp3(v, OP_String, 0, 0, "numeric", P3_STATIC);
} }
} return n;
return includeTypes ? n*2 : n;
} }
/* /*
@@ -1714,11 +1706,13 @@ FuncDef *sqlite3FindFunction(
assert( createFlag==0 ); assert( createFlag==0 );
return pMaybe; return pMaybe;
} }
if( p==0 && createFlag && (p = sqliteMalloc(sizeof(*p)))!=0 ){ if( p==0 && createFlag && (p = sqliteMalloc(sizeof(*p)+nName+1))!=0 ){
p->nArg = nArg; p->nArg = nArg;
p->pNext = pFirst; p->pNext = pFirst;
p->dataType = pFirst ? pFirst->dataType : SQLITE_NUMERIC; p->zName = (char*)&p[1];
sqlite3HashInsert(&db->aFunc, zName, nName, (void*)p); memcpy(p->zName, zName, nName);
p->zName[nName] = 0;
sqlite3HashInsert(&db->aFunc, p->zName, nName, (void*)p);
} }
return p; return p;
} }

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.56 2004/05/26 06:18:37 danielk1977 Exp $ ** $Id: func.c,v 1.57 2004/05/26 16:54:43 drh Exp $
*/ */
#include <ctype.h> #include <ctype.h>
#include <math.h> #include <math.h>
@@ -29,45 +29,41 @@
/* /*
** Implementation of the non-aggregate min() and max() functions ** Implementation of the non-aggregate min() and max() functions
*/ */
static void minmaxFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void minmaxFunc(
const char *zBest; sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int i; int i;
int (*xCompare)(const char*, const char*);
int mask; /* 0 for min() or 0xffffffff for max() */ int mask; /* 0 for min() or 0xffffffff for max() */
const char *zArg; int iBest;
if( argc==0 ) return; if( argc==0 ) return;
mask = (int)sqlite3_user_data(context); mask = (int)sqlite3_user_data(context);
zBest = sqlite3_value_data(argv[0]); iBest = 0;
if( zBest==0 ) return; for(i=1; i<argc; i++){
zArg = sqlite3_value_data(argv[1]); if( (sqlite3MemCompare(argv[iBest], argv[i], 0)^mask)<0 ){
if( zArg[0]=='n' ){ iBest = i;
xCompare = sqlite3Compare;
}else{
xCompare = strcmp;
}
for(i=2; i<argc; i+=2){
zArg = sqlite3_value_data(argv[i]);
if( zArg==0 ) return;
if( (xCompare(zArg, zBest)^mask)<0 ){
zBest = zArg;
} }
} }
sqlite3_result_text(context, zBest, -1, 1); sqlite3_result(context, argv[iBest]);
} }
/* /*
** Return the type of the argument. ** Return the type of the argument.
*/ */
static void typeofFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void typeofFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *z = 0; const char *z = 0;
assert( argc==2 );
switch( sqlite3_value_type(argv[0]) ){ switch( sqlite3_value_type(argv[0]) ){
case SQLITE3_NULL: z = "null" ; break; case SQLITE3_NULL: z = "null"; break;
case SQLITE3_INTEGER: z = "integer" ; break; case SQLITE3_INTEGER: z = "integer"; break;
case SQLITE3_TEXT: z = "text" ; break; case SQLITE3_TEXT: z = "text"; break;
case SQLITE3_FLOAT: z = "real" ; break; case SQLITE3_FLOAT: z = "real"; break;
case SQLITE3_BLOB: z = "blob" ; break; case SQLITE3_BLOB: z = "blob"; break;
} }
sqlite3_result_text(context, z, -1, 0); sqlite3_result_text(context, z, -1, 0);
} }
@@ -75,19 +71,33 @@ static void typeofFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
/* /*
** Implementation of the length() function ** Implementation of the length() function
*/ */
static void lengthFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void lengthFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *z; const char *z;
int len; int len;
assert( argc==1 ); assert( argc==1 );
z = sqlite3_value_data(argv[0]); switch( sqlite3_value_type(argv[0]) ){
if( z==0 ) return; case SQLITE3_BLOB:
#ifdef SQLITE_UTF8 case SQLITE3_INTEGER:
case SQLITE3_FLOAT: {
sqlite3_result_int32(context, sqlite3_value_bytes(argv[0]));
break;
}
case SQLITE3_TEXT: {
const char *z = sqlite3_value_data(argv[0]);
for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; } for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
#else
len = strlen(z);
#endif
sqlite3_result_int32(context, len); sqlite3_result_int32(context, len);
break;
}
default: {
sqlite3_result_null(context);
break;
}
}
} }
/* /*
@@ -96,32 +106,41 @@ static void lengthFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
const char *z; const char *z;
assert( argc==1 ); assert( argc==1 );
z = sqlite3_value_data(argv[0]); switch( sqlite3_value_type(argv[0]) ){
if( z==0 ) return; case SQLITE3_INTEGER: {
if( z[0]=='-' && isdigit(z[1]) ) z++; sqlite3_result_int64(context, -sqlite3_value_int(argv[0]));
sqlite3_result_text(context, z, -1, 1); break;
}
case SQLITE3_NULL: {
sqlite3_result_null(context);
break;
}
default: {
sqlite3_result_double(context, -sqlite3_value_float(argv[0]));
break;
}
}
} }
/* /*
** Implementation of the substr() function ** Implementation of the substr() function
*/ */
static void substrFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void substrFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *z; const char *z;
#ifdef SQLITE_UTF8
const char *z2; const char *z2;
int i; int i;
#endif
int p1, p2, len; int p1, p2, len;
assert( argc==3 ); assert( argc==3 );
z = sqlite3_value_data(argv[0]); z = sqlite3_value_data(argv[0]);
if( z==0 ) return; if( z==0 ) return;
p1 = sqlite3_value_int(argv[1]); p1 = sqlite3_value_int(argv[1]);
p2 = sqlite3_value_int(argv[2]); p2 = sqlite3_value_int(argv[2]);
#ifdef SQLITE_UTF8
for(len=0, z2=z; *z2; z2++){ if( (0xc0&*z2)!=0x80 ) len++; } for(len=0, z2=z; *z2; z2++){ if( (0xc0&*z2)!=0x80 ) len++; }
#else
len = strlen(z);
#endif
if( p1<0 ){ if( p1<0 ){
p1 += len; p1 += len;
if( p1<0 ){ if( p1<0 ){
@@ -134,7 +153,6 @@ static void substrFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
if( p1+p2>len ){ if( p1+p2>len ){
p2 = len-p1; p2 = len-p1;
} }
#ifdef SQLITE_UTF8
for(i=0; i<p1 && z[i]; i++){ for(i=0; i<p1 && z[i]; i++){
if( (z[i]&0xc0)==0x80 ) p1++; if( (z[i]&0xc0)==0x80 ) p1++;
} }
@@ -143,7 +161,6 @@ static void substrFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
if( (z[i]&0xc0)==0x80 ) p2++; if( (z[i]&0xc0)==0x80 ) p2++;
} }
while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; } while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; }
#endif
if( p2<0 ) p2 = 0; if( p2<0 ) p2 = 0;
sqlite3_result_text(context, &z[p1], p2, 1); sqlite3_result_text(context, &z[p1], p2, 1);
} }
@@ -203,11 +220,15 @@ static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
** All three do the same thing. They return the first non-NULL ** All three do the same thing. They return the first non-NULL
** argument. ** argument.
*/ */
static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void ifnullFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int i; int i;
for(i=0; i<argc; i++){ for(i=0; i<argc; i++){
if( SQLITE3_NULL!=sqlite3_value_type(argv[i]) ){ if( SQLITE3_NULL!=sqlite3_value_type(argv[i]) ){
sqlite3_result_text(context, sqlite3_value_data(argv[i]), -1, 1); sqlite3_result(context, argv[i]);
break; break;
} }
} }
@@ -216,7 +237,11 @@ static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
/* /*
** Implementation of random(). Return a random integer. ** Implementation of random(). Return a random integer.
*/ */
static void randomFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void randomFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
int r; int r;
sqlite3Randomness(sizeof(r), &r); sqlite3Randomness(sizeof(r), &r);
sqlite3_result_int32(context, r); sqlite3_result_int32(context, r);
@@ -232,14 +257,18 @@ static void last_insert_rowid(
sqlite3_value **argv sqlite3_value **argv
){ ){
sqlite *db = sqlite3_user_data(context); sqlite *db = sqlite3_user_data(context);
sqlite3_result_int32(context, sqlite3_last_insert_rowid(db)); sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
} }
/* /*
** Implementation of the change_count() SQL function. The return ** Implementation of the change_count() SQL function. The return
** value is the same as the sqlite3_changes() API function. ** value is the same as the sqlite3_changes() API function.
*/ */
static void change_count(sqlite3_context *context, int arg, sqlite3_value **argv){ static void change_count(
sqlite3_context *context,
int arg,
sqlite3_value **argv
){
sqlite *db = sqlite3_user_data(context); sqlite *db = sqlite3_user_data(context);
sqlite3_result_int32(context, sqlite3_changes(db)); sqlite3_result_int32(context, sqlite3_changes(db));
} }
@@ -301,11 +330,13 @@ static void globFunc(sqlite3_context *context, int arg, sqlite3_value **argv){
** argument if the arguments are different. The result is NULL if the ** argument if the arguments are different. The result is NULL if the
** arguments are equal to each other. ** arguments are equal to each other.
*/ */
static void nullifFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void nullifFunc(
const unsigned char *zX = sqlite3_value_data(argv[0]); sqlite3_context *context,
const unsigned char *zY = sqlite3_value_data(argv[1]); int argc,
if( zX!=0 && sqlite3Compare(zX, zY)!=0 ){ sqlite3_value **argv
sqlite3_result_text(context, zX, -1, 1); ){
if( sqlite3MemCompare(argv[0], argv[1], 0)!=0 ){
sqlite3_result(context, argv[0]);
} }
} }
@@ -313,7 +344,11 @@ static void nullifFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
** Implementation of the VERSION(*) function. The result is the version ** Implementation of the VERSION(*) function. The result is the version
** of the SQLite library that is running. ** of the SQLite library that is running.
*/ */
static void versionFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void versionFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_result_text(context, sqlite3_version, -1, 0); sqlite3_result_text(context, sqlite3_version, -1, 0);
} }
@@ -331,13 +366,22 @@ static void versionFunc(sqlite3_context *context, int argc, sqlite3_value **argv
static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
const char *zArg = sqlite3_value_data(argv[0]); const char *zArg = sqlite3_value_data(argv[0]);
if( argc<1 ) return; if( argc<1 ) return;
if( zArg==0 ){ switch( sqlite3_value_type(argv[0]) ){
case SQLITE3_NULL: {
sqlite3_result_text(context, "NULL", 4, 0); sqlite3_result_text(context, "NULL", 4, 0);
}else if( sqlite3IsNumber(zArg, 0, TEXT_Utf8) ){ break;
sqlite3_result_text(context, zArg, -1, 1); }
}else{ case SQLITE3_INTEGER:
case SQLITE3_FLOAT: {
sqlite3_result(context, argv[0]);
break;
}
case SQLITE3_BLOB: /*** FIX ME. Use a BLOB encoding ***/
case SQLITE3_TEXT: {
int i,j,n; int i,j,n;
const char *zArg = sqlite3_value_data(argv[0]);
char *z; char *z;
for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
z = sqliteMalloc( i+n+3 ); z = sqliteMalloc( i+n+3 );
if( z==0 ) return; if( z==0 ) return;
@@ -353,6 +397,7 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
sqlite3_result_text(context, z, j, 1); sqlite3_result_text(context, z, j, 1);
sqliteFree(z); sqliteFree(z);
} }
}
} }
#ifdef SQLITE_SOUNDEX #ifdef SQLITE_SOUNDEX
@@ -409,14 +454,14 @@ static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){
int iMin, iMax, n, r, i; int iMin, iMax, n, r, i;
unsigned char zBuf[1000]; unsigned char zBuf[1000];
if( argc>=1 ){ if( argc>=1 ){
iMin = atoi(sqlite3_value_data(argv[0])); iMin = sqlite3_value_int(argv[0]);
if( iMin<0 ) iMin = 0; if( iMin<0 ) iMin = 0;
if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1; if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1;
}else{ }else{
iMin = 1; iMin = 1;
} }
if( argc>=2 ){ if( argc>=2 ){
iMax = atoi(sqlite3_value_data(argv[1])); iMax = sqlite3_value_int(argv[1]);
if( iMax<iMin ) iMax = iMin; if( iMax<iMin ) iMax = iMin;
if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1; if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
}else{ }else{
@@ -578,23 +623,8 @@ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv)
static void minMaxFinalize(sqlite3_context *context){ static void minMaxFinalize(sqlite3_context *context){
sqlite3_value *pRes; sqlite3_value *pRes;
pRes = (sqlite3_value *)sqlite3_get_context(context, sizeof(Mem)); pRes = (sqlite3_value *)sqlite3_get_context(context, sizeof(Mem));
if( pRes->flags ){ if( pRes->flags ){
switch( sqlite3_value_type(pRes) ){ sqlite3_result(context, pRes);
case SQLITE3_INTEGER:
sqlite3_result_int32(context, sqlite3_value_int(pRes));
break;
case SQLITE3_FLOAT:
sqlite3_result_double(context, sqlite3_value_float(pRes));
case SQLITE3_TEXT:
case SQLITE3_BLOB:
sqlite3_result_text(context,
sqlite3_value_data(pRes), sqlite3_value_bytes(pRes), 1);
break;
case SQLITE3_NULL:
default:
assert(0);
}
} }
} }
@@ -607,90 +637,70 @@ void sqlite3RegisterBuiltinFunctions(sqlite *db){
static struct { static struct {
char *zName; char *zName;
signed char nArg; signed char nArg;
signed char dataType;
u8 argType; /* 0: none. 1: db 2: (-1) */ u8 argType; /* 0: none. 1: db 2: (-1) */
void (*xFunc)(sqlite3_context*,int,sqlite3_value **); void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
} aFuncs[] = { } aFuncs[] = {
{ "min", -1, SQLITE_ARGS, 0, minmaxFunc }, { "min", -1, 0, minmaxFunc },
{ "min", 0, 0, 0, 0 }, { "min", 0, 0, 0 },
{ "max", -1, SQLITE_ARGS, 2, minmaxFunc }, { "max", -1, 2, minmaxFunc },
{ "max", 0, 0, 2, 0 }, { "max", 0, 2, 0 },
{ "typeof", 1, SQLITE_TEXT, 0, typeofFunc }, { "typeof", 1, 0, typeofFunc },
{ "classof", 1, SQLITE_TEXT, 0, typeofFunc }, /* FIX ME: hack */ { "classof", 1, 0, typeofFunc }, /* FIX ME: hack */
{ "length", 1, SQLITE_NUMERIC, 0, lengthFunc }, { "length", 1, 0, lengthFunc },
{ "substr", 3, SQLITE_TEXT, 0, substrFunc }, { "substr", 3, 0, substrFunc },
{ "abs", 1, SQLITE_NUMERIC, 0, absFunc }, { "abs", 1, 0, absFunc },
{ "round", 1, SQLITE_NUMERIC, 0, roundFunc }, { "round", 1, 0, roundFunc },
{ "round", 2, SQLITE_NUMERIC, 0, roundFunc }, { "round", 2, 0, roundFunc },
{ "upper", 1, SQLITE_TEXT, 0, upperFunc }, { "upper", 1, 0, upperFunc },
{ "lower", 1, SQLITE_TEXT, 0, lowerFunc }, { "lower", 1, 0, lowerFunc },
{ "coalesce", -1, SQLITE_ARGS, 0, ifnullFunc }, { "coalesce", -1, 0, ifnullFunc },
{ "coalesce", 0, 0, 0, 0 }, { "coalesce", 0, 0, 0 },
{ "coalesce", 1, 0, 0, 0 }, { "coalesce", 1, 0, 0 },
{ "ifnull", 2, SQLITE_ARGS, 0, ifnullFunc }, { "ifnull", 2, 0, ifnullFunc },
{ "random", -1, SQLITE_NUMERIC, 0, randomFunc }, { "random", -1, 0, randomFunc },
{ "like", 2, SQLITE_NUMERIC, 0, likeFunc }, { "like", 2, 0, likeFunc },
{ "glob", 2, SQLITE_NUMERIC, 0, globFunc }, { "glob", 2, 0, globFunc },
{ "nullif", 2, SQLITE_ARGS, 0, nullifFunc }, { "nullif", 2, 0, nullifFunc },
{ "sqlite_version",0,SQLITE_TEXT, 0, versionFunc}, { "sqlite_version", 0, 0, versionFunc},
{ "quote", 1, SQLITE_ARGS, 0, quoteFunc }, { "quote", 1, 0, quoteFunc },
{ "last_insert_rowid", 0, SQLITE_NUMERIC, 1, last_insert_rowid }, { "last_insert_rowid", 0, 1, last_insert_rowid },
{ "change_count", 0, SQLITE_NUMERIC, 1, change_count }, { "change_count", 0, 1, change_count },
{ "last_statement_change_count", { "last_statement_change_count", 0, 1, last_statement_change_count },
0, SQLITE_NUMERIC, 1, last_statement_change_count },
#ifdef SQLITE_SOUNDEX #ifdef SQLITE_SOUNDEX
{ "soundex", 1, SQLITE_TEXT, 0, soundexFunc}, { "soundex", 1, 0, soundexFunc},
#endif #endif
#ifdef SQLITE_TEST #ifdef SQLITE_TEST
{ "randstr", 2, SQLITE_TEXT, 0, randStr }, { "randstr", 2, 0, randStr },
#endif #endif
}; };
static struct { static struct {
char *zName; char *zName;
signed char nArg; signed char nArg;
signed char dataType;
u8 argType; u8 argType;
void (*xStep)(sqlite3_context*,int,sqlite3_value**); void (*xStep)(sqlite3_context*,int,sqlite3_value**);
void (*xFinalize)(sqlite3_context*); void (*xFinalize)(sqlite3_context*);
} aAggs[] = { } aAggs[] = {
{ "min", 1, 0, 0, minmaxStep, minMaxFinalize }, { "min", 1, 0, minmaxStep, minMaxFinalize },
{ "max", 1, 0, 2, minmaxStep, minMaxFinalize }, { "max", 1, 2, minmaxStep, minMaxFinalize },
{ "sum", 1, SQLITE_NUMERIC, 0, sumStep, sumFinalize }, { "sum", 1, 0, sumStep, sumFinalize },
{ "avg", 1, SQLITE_NUMERIC, 0, sumStep, avgFinalize }, { "avg", 1, 0, sumStep, avgFinalize },
{ "count", 0, SQLITE_NUMERIC, 0, countStep, countFinalize }, { "count", 0, 0, countStep, countFinalize },
{ "count", 1, SQLITE_NUMERIC, 0, countStep, countFinalize }, { "count", 1, 0, countStep, countFinalize },
#if 0 #if 0
{ "stddev", 1, SQLITE_NUMERIC, 0, stdDevStep, stdDevFinalize }, { "stddev", 1, 0, stdDevStep, stdDevFinalize },
#endif #endif
}; };
static const char *azTypeFuncs[] = { "min", "max", "typeof" };
int i; int i;
for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){ for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
void *pArg = aFuncs[i].argType==2 ? (void*)(-1) : db; void *pArg = aFuncs[i].argType==2 ? (void*)(-1) : db;
sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, 0, 0, sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, 0, 0,
pArg, aFuncs[i].xFunc, 0, 0); pArg, aFuncs[i].xFunc, 0, 0);
if( aFuncs[i].xFunc ){
sqlite3_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
}
} }
for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){ for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
void *pArg = aAggs[i].argType==2 ? (void*)(-1) : db; void *pArg = aAggs[i].argType==2 ? (void*)(-1) : db;
sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, 0, 0, pArg, sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, 0, 0, pArg,
0, aAggs[i].xStep, aAggs[i].xFinalize); 0, aAggs[i].xStep, aAggs[i].xFinalize);
sqlite3_function_type(db, aAggs[i].zName, aAggs[i].dataType);
}
for(i=0; i<sizeof(azTypeFuncs)/sizeof(azTypeFuncs[0]); i++){
int n = strlen(azTypeFuncs[i]);
FuncDef *p = sqlite3HashFind(&db->aFunc, azTypeFuncs[i], n);
while( p ){
p->includeTypes = 1;
p = p->pNext;
}
} }
sqlite3RegisterDateTimeFunctions(db); sqlite3RegisterDateTimeFunctions(db);
} }

View File

@@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be ** other files are for internal use by SQLite and should not be
** accessed by users of the library. ** accessed by users of the library.
** **
** $Id: main.c,v 1.193 2004/05/26 10:11:06 danielk1977 Exp $ ** $Id: main.c,v 1.194 2004/05/26 16:54:43 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -412,7 +412,7 @@ static int binaryCollatingFunc(
/* /*
** Return the ROWID of the most recent insert ** Return the ROWID of the most recent insert
*/ */
int sqlite3_last_insert_rowid(sqlite *db){ long long int sqlite3_last_insert_rowid(sqlite *db){
return db->lastRowid; return db->lastRowid;
} }
@@ -695,20 +695,6 @@ int sqlite3_create_function16(
return rc; return rc;
} }
/*
** Change the datatype for all functions with a given name. See the
** header comment for the prototype of this function in sqlite.h for
** additional information.
*/
int sqlite3_function_type(sqlite *db, const char *zName, int dataType){
FuncDef *p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, strlen(zName));
while( p ){
p->dataType = dataType;
p = p->pNext;
}
return SQLITE_OK;
}
/* /*
** Register a trace function. The pArg from the previously registered trace ** Register a trace function. The pArg from the previously registered trace
** is returned. ** is returned.
@@ -1028,7 +1014,7 @@ static int openDatabase(
db->aDb = db->aDbStatic; db->aDb = db->aDbStatic;
db->enc = def_enc; db->enc = def_enc;
/* db->flags |= SQLITE_ShortColNames; */ /* db->flags |= SQLITE_ShortColNames; */
sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 1); sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 0);
sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);
for(i=0; i<db->nDb; i++){ for(i=0; i<db->nDb; i++){
sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);

View File

@@ -12,7 +12,7 @@
** This file contains C code routines that are called by the parser ** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite. ** to handle SELECT statements in SQLite.
** **
** $Id: select.c,v 1.177 2004/05/26 10:11:06 danielk1977 Exp $ ** $Id: select.c,v 1.178 2004/05/26 16:54:44 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
@@ -2338,7 +2338,7 @@ int sqlite3Select(
for(i=0; i<pParse->nAgg; i++){ for(i=0; i<pParse->nAgg; i++){
FuncDef *pFunc; FuncDef *pFunc;
if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){ if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){
sqlite3VdbeOp3(v, OP_AggInit, 0, i, (char*)pFunc, P3_POINTER); sqlite3VdbeOp3(v, OP_AggInit, 0, i, (char*)pFunc, P3_FUNCDEF);
} }
} }
if( pGroupBy==0 ){ if( pGroupBy==0 ){
@@ -2412,7 +2412,7 @@ int sqlite3Select(
pE = pAgg->pExpr; pE = pAgg->pExpr;
assert( pE!=0 ); assert( pE!=0 );
assert( pE->op==TK_AGG_FUNCTION ); assert( pE->op==TK_AGG_FUNCTION );
nExpr = sqlite3ExprCodeExprList(pParse, pE->pList, pDef->includeTypes); nExpr = sqlite3ExprCodeExprList(pParse, pE->pList);
sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeAddOp(v, OP_Integer, i, 0);
sqlite3VdbeOp3(v, OP_AggFunc, 0, nExpr, (char*)pDef, P3_POINTER); sqlite3VdbeOp3(v, OP_AggFunc, 0, nExpr, (char*)pDef, P3_POINTER);
} }

View File

@@ -12,7 +12,7 @@
** This header file defines the interface that the SQLite library ** This header file defines the interface that the SQLite library
** presents to client programs. ** presents to client programs.
** **
** @(#) $Id: sqlite.h.in,v 1.80 2004/05/26 06:18:38 danielk1977 Exp $ ** @(#) $Id: sqlite.h.in,v 1.81 2004/05/26 16:54:44 drh Exp $
*/ */
#ifndef _SQLITE_H_ #ifndef _SQLITE_H_
#define _SQLITE_H_ #define _SQLITE_H_
@@ -163,7 +163,7 @@ int sqlite3_exec(
** **
** This function is similar to the mysql_insert_id() function from MySQL. ** This function is similar to the mysql_insert_id() function from MySQL.
*/ */
int sqlite3_last_insert_rowid(sqlite*); long long int sqlite3_last_insert_rowid(sqlite*);
/* /*
** This function returns the number of database rows that were changed ** This function returns the number of database rows that were changed
@@ -1124,26 +1124,6 @@ int sqlite3_create_function16(
void (*xFinal)(sqlite3_context*) void (*xFinal)(sqlite3_context*)
); );
/*
** Use the following routine to define the datatype returned by a
** user-defined function. The second argument can be one of the
** constants SQLITE_NUMERIC, SQLITE_TEXT, or SQLITE_ARGS or it
** can be an integer greater than or equal to zero. When the datatype
** parameter is non-negative, the type of the result will be the
** same as the datatype-th argument. If datatype==SQLITE_NUMERIC
** then the result is always numeric. If datatype==SQLITE_TEXT then
** the result is always text. If datatype==SQLITE_ARGS then the result
** is numeric if any argument is numeric and is text otherwise.
*/
int sqlite3_function_type(
sqlite *db, /* The database there the function is registered */
const char *zName, /* Name of the function */
int datatype /* The datatype for this function */
);
#define SQLITE_NUMERIC (-1)
#define SQLITE_TEXT (-2)
#define SQLITE_ARGS (-3)
/* /*
** The next routine returns the number of calls to xStep for a particular ** The next routine returns the number of calls to xStep for a particular
** aggregate function instance. The current call to xStep counts so this ** aggregate function instance. The current call to xStep counts so this
@@ -1323,6 +1303,11 @@ void sqlite3_result_blob(sqlite3_context*, const void*, int n, int eCopy);
void sqlite3_result_error(sqlite3_context*, const char*, int); void sqlite3_result_error(sqlite3_context*, const char*, int);
void sqlite3_result_error16(sqlite3_context*, const void*, int); void sqlite3_result_error16(sqlite3_context*, const void*, int);
/*
** Copy a function parameter into the result of the function.
*/
void sqlite3_result(sqlite3_context*, sqlite3_value*);
#ifdef __cplusplus #ifdef __cplusplus
} /* End of the 'extern "C"' block */ } /* End of the 'extern "C"' block */
#endif #endif

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** Internal interface definitions for SQLite. ** Internal interface definitions for SQLite.
** **
** @(#) $Id: sqliteInt.h,v 1.252 2004/05/26 06:58:44 danielk1977 Exp $ ** @(#) $Id: sqliteInt.h,v 1.253 2004/05/26 16:54:45 drh Exp $
*/ */
#include "config.h" #include "config.h"
#include "sqlite.h" #include "sqlite.h"
@@ -160,20 +160,15 @@ extern const int sqlite3one;
/* /*
** The maximum number of bytes of data that can be put into a single ** The maximum number of bytes of data that can be put into a single
** row of a single table. The upper bound on this limit is 16777215 ** row of a single table. The upper bound on this limit is
** bytes (or 16MB-1). We have arbitrarily set the limit to just 1MB ** 9223372036854775808 bytes (or 2**63). We have arbitrarily set the
** here because the overflow page chain is inefficient for really big ** limit to just 1MB here because the overflow page chain is inefficient
** records and we want to discourage people from thinking that ** for really big records and we want to discourage people from thinking that
** multi-megabyte records are OK. If your needs are different, you can ** multi-megabyte records are OK. If your needs are different, you can
** change this define and recompile to increase or decrease the record ** change this define and recompile to increase or decrease the record
** size. ** size.
**
** The 16777198 is computed as follows: 238 bytes of payload on the
** original pages plus 16448 overflow pages each holding 1020 bytes of
** data.
*/ */
#define MAX_BYTES_PER_ROW 1048576 #define MAX_BYTES_PER_ROW 1048576
/* #define MAX_BYTES_PER_ROW 16777198 */
/* /*
** If memory allocation problems are found, recompile with ** If memory allocation problems are found, recompile with
@@ -334,18 +329,6 @@ struct Db {
/* /*
** Each database is an instance of the following structure. ** Each database is an instance of the following structure.
** **
** The sqlite.file_format is initialized by the database file
** and helps determines how the data in the database file is
** represented. This field allows newer versions of the library
** to read and write older databases. The various file formats
** are as follows:
**
** file_format==1 Version 2.1.0.
** file_format==2 Version 2.2.0. Add support for INTEGER PRIMARY KEY.
** file_format==3 Version 2.6.0. Fix empty-string index bug.
** file_format==4 Version 2.7.0. Add support for separate numeric and
** text datatypes.
**
** The sqlite.temp_store determines where temporary database files ** The sqlite.temp_store determines where temporary database files
** are stored. If 1, then a file is created to hold those tables. If ** are stored. If 1, then a file is created to hold those tables. If
** 2, then they are held in memory. 0 means use the default value in ** 2, then they are held in memory. 0 means use the default value in
@@ -462,15 +445,13 @@ struct sqlite {
** points to a linked list of these structures. ** points to a linked list of these structures.
*/ */
struct FuncDef { struct FuncDef {
void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */ char *zName; /* SQL name of the function */
void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate function step */ int nArg; /* Number of arguments. -1 means unlimited */
void (*xFinalize)(sqlite3_context*); /* Aggregate function finializer */
signed char nArg; /* Number of arguments. -1 means unlimited */
signed char dataType; /* Arg that determines datatype. -1=NUMERIC, */
/* -2=TEXT. -3=SQLITE_ARGS */
u8 includeTypes; /* Add datatypes to args of xFunc and xStep */
void *pUserData; /* User data parameter */ void *pUserData; /* User data parameter */
FuncDef *pNext; /* Next function with same name */ FuncDef *pNext; /* Next function with same name */
void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */
void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate step */
void (*xFinalize)(sqlite3_context*); /* Aggregate finializer */
}; };
/* /*
@@ -1256,7 +1237,7 @@ void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int);
WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, int, ExprList**); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, int, ExprList**);
void sqlite3WhereEnd(WhereInfo*); void sqlite3WhereEnd(WhereInfo*);
void sqlite3ExprCode(Parse*, Expr*); void sqlite3ExprCode(Parse*, Expr*);
int sqlite3ExprCodeExprList(Parse*, ExprList*, int); int sqlite3ExprCodeExprList(Parse*, ExprList*);
void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
void sqlite3ExprIfFalse(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
Table *sqlite3FindTable(sqlite*,const char*, const char*); Table *sqlite3FindTable(sqlite*,const char*, const char*);

View File

@@ -11,7 +11,7 @@
************************************************************************* *************************************************************************
** A TCL Interface to SQLite ** A TCL Interface to SQLite
** **
** $Id: tclsqlite.c,v 1.71 2004/05/26 06:18:38 danielk1977 Exp $ ** $Id: tclsqlite.c,v 1.72 2004/05/26 16:54:46 drh Exp $
*/ */
#ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */
@@ -864,7 +864,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
pFunc->zScript = (char*)&pFunc[1]; pFunc->zScript = (char*)&pFunc[1];
strcpy(pFunc->zScript, zScript); strcpy(pFunc->zScript, zScript);
sqlite3_create_function(pDb->db, zName, -1, 0, 0, pFunc, tclSqlFunc, 0, 0); sqlite3_create_function(pDb->db, zName, -1, 0, 0, pFunc, tclSqlFunc, 0, 0);
sqlite3_function_type(pDb->db, zName, SQLITE_NUMERIC);
break; break;
} }
@@ -1245,6 +1244,3 @@ int TCLSH_MAIN(int argc, char **argv){
#endif /* TCLSH */ #endif /* TCLSH */
#endif /* !defined(NO_TCL) */ #endif /* !defined(NO_TCL) */

View File

@@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing ** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code. ** commenting and indentation practices when changing or adding code.
** **
** $Id: vdbe.c,v 1.334 2004/05/26 13:27:00 danielk1977 Exp $ ** $Id: vdbe.c,v 1.335 2004/05/26 16:54:47 drh Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@@ -5864,7 +5864,8 @@ default: {
assert( (pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 ); assert( (pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
} }
/* MEM_Null excludes all other types */ /* MEM_Null excludes all other types */
assert( pTos->flags==MEM_Null || (pTos->flags&MEM_Null)==0 ); assert( (pTos->flags&(MEM_Str|MEM_Int|MEM_Real|MEM_Blob))==0
|| (pTos->flags&MEM_Null)==0 );
} }
if( pc<-1 || pc>=p->nOp ){ if( pc<-1 || pc>=p->nOp ){
sqlite3SetString(&p->zErrMsg, "jump destination out of range", (char*)0); sqlite3SetString(&p->zErrMsg, "jump destination out of range", (char*)0);

View File

@@ -15,7 +15,7 @@
** or VDBE. The VDBE implements an abstract machine that runs a ** or VDBE. The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database. ** simple program to access and modify the underlying database.
** **
** $Id: vdbe.h,v 1.83 2004/05/26 10:11:07 danielk1977 Exp $ ** $Id: vdbe.h,v 1.84 2004/05/26 16:54:48 drh Exp $
*/ */
#ifndef _SQLITE_VDBE_H_ #ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_
@@ -69,7 +69,8 @@ typedef struct VdbeOpList VdbeOpList;
#define P3_STATIC (-2) /* Pointer to a static string */ #define P3_STATIC (-2) /* Pointer to a static string */
#define P3_POINTER (-3) /* P3 is a pointer to some structure or object */ #define P3_POINTER (-3) /* P3 is a pointer to some structure or object */
#define P3_COLLSEQ (-4) /* P3 is a pointer to a CollSeq structure */ #define P3_COLLSEQ (-4) /* P3 is a pointer to a CollSeq structure */
#define P3_KEYINFO (-5) /* P3 is a pointer to a KeyInfo structure */ #define P3_FUNCDEF (-5) /* P3 is a pointer to a FuncDef structure */
#define P3_KEYINFO (-6) /* P3 is a pointer to a KeyInfo structure */
/* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure /* When adding a P3 argument using P3_KEYINFO, a copy of the KeyInfo structure
** is made. That copy is freed when the Vdbe is finalized. But if the ** is made. That copy is freed when the Vdbe is finalized. But if the
@@ -78,7 +79,7 @@ typedef struct VdbeOpList VdbeOpList;
** from a single sqliteMalloc(). But no copy is made and the calling ** from a single sqliteMalloc(). But no copy is made and the calling
** function should *not* try to free the KeyInfo. ** function should *not* try to free the KeyInfo.
*/ */
#define P3_KEYINFO_HANDOFF (-6) #define P3_KEYINFO_HANDOFF (-7)
/* /*
** The following macro converts a relative address in the p2 field ** The following macro converts a relative address in the p2 field

View File

@@ -517,6 +517,17 @@ static char *displayP3(Op *pOp, char *zTemp, int nTemp){
zP3 = zTemp; zP3 = zTemp;
break; break;
} }
case P3_FUNCDEF: {
FuncDef *pDef = (FuncDef*)pOp->p3;
char zNum[30];
sprintf(zTemp, "%.*s", nTemp, pDef->zName);
sprintf(zNum,"(%d)", pDef->nArg);
if( strlen(zTemp)+strlen(zNum)+1<=nTemp ){
strcat(zTemp, zNum);
}
zP3 = zTemp;
break;
}
default: { default: {
zP3 = pOp->p3; zP3 = pOp->p3;
if( zP3==0 ){ if( zP3==0 ){
@@ -1869,10 +1880,13 @@ int sqlite3VdbeMemNulTerminate(Mem *pMem){
} }
/* /*
** The following nine routines, named sqlite3_result_*(), are used to ** The following ten routines, named sqlite3_result_*(), are used to
** return values or errors from user-defined functions and aggregate ** return values or errors from user-defined functions and aggregate
** operations. They are commented in the header file sqlite.h (sqlite.h.in) ** operations. They are commented in the header file sqlite.h (sqlite.h.in)
*/ */
void sqlite3_result(sqlite3_context *pCtx, sqlite3_value *pValue){
sqlite3VdbeMemCopy(&pCtx->s, pValue);
}
void sqlite3_result_int32(sqlite3_context *pCtx, int iVal){ void sqlite3_result_int32(sqlite3_context *pCtx, int iVal){
MemSetInt(&pCtx->s, iVal); MemSetInt(&pCtx->s, iVal);
} }
@@ -1918,4 +1932,3 @@ void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
pCtx->isError = 1; pCtx->isError = 1;
MemSetStr(&pCtx->s, z, n, TEXT_Utf16, 1); MemSetStr(&pCtx->s, z, n, TEXT_Utf16, 1);
} }