Index: src/date.c ================================================================== --- src/date.c +++ src/date.c @@ -14,11 +14,11 @@ ** ** There is only one exported symbol in this file - the function ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** 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: ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon @@ -662,11 +662,15 @@ /* ** julianday( TIMESTRING, MOD, MOD, ...) ** ** 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; if( isDate(argc, argv, &x)==0 ){ computeJD(&x); sqlite3_result_double(context, x.rJD); } @@ -675,11 +679,15 @@ /* ** datetime( TIMESTRING, MOD, MOD, ...) ** ** 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; if( isDate(argc, argv, &x)==0 ){ char zBuf[100]; computeYMD_HMS(&x); sprintf(zBuf, "%04d-%02d-%02d %02d:%02d:%02d",x.Y, x.M, x.D, x.h, x.m, @@ -691,11 +699,15 @@ /* ** time( TIMESTRING, MOD, MOD, ...) ** ** 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; if( isDate(argc, argv, &x)==0 ){ char zBuf[100]; computeHMS(&x); sprintf(zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s); @@ -706,11 +718,15 @@ /* ** date( TIMESTRING, MOD, MOD, ...) ** ** 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; if( isDate(argc, argv, &x)==0 ){ char zBuf[100]; computeYMD(&x); sprintf(zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D); @@ -735,11 +751,15 @@ ** %w day of week 0-6 sunday==0 ** %W week of year 00-53 ** %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; int n, i, j; char *z; const char *zFmt = sqlite3_value_data(argv[0]); char zBuf[100]; @@ -850,29 +870,22 @@ */ void sqlite3RegisterDateTimeFunctions(sqlite *db){ static struct { char *zName; int nArg; - int dataType; void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } aFuncs[] = { #ifndef SQLITE_OMIT_DATETIME_FUNCS - { "julianday", -1, SQLITE_NUMERIC, juliandayFunc }, - { "date", -1, SQLITE_TEXT, dateFunc }, - { "time", -1, SQLITE_TEXT, timeFunc }, - { "datetime", -1, SQLITE_TEXT, datetimeFunc }, - { "strftime", -1, SQLITE_TEXT, strftimeFunc }, + { "julianday", -1, juliandayFunc }, + { "date", -1, dateFunc }, + { "time", -1, timeFunc }, + { "datetime", -1, datetimeFunc }, + { "strftime", -1, strftimeFunc }, #endif }; int i; for(i=0; i char const *sqlite3AffinityString(char affinity){ @@ -501,11 +501,10 @@ ** pExpr->iDb Set the index in db->aDb[] of the database holding ** the table. ** pExpr->iTable Set to the cursor number for the table obtained ** from pSrcList. ** 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->pLeft Any expression this points to is deleted ** pExpr->pRight Any expression this points to is deleted. ** ** The pDbToken is the name of the database (the "X"). This value may be @@ -1222,17 +1221,17 @@ int nId; const char *zId; getFunctionName(pExpr, &zId, &nId); pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, 0); assert( pDef!=0 ); - nExpr = sqlite3ExprCodeExprList(pParse, pList, pDef->includeTypes); + nExpr = sqlite3ExprCodeExprList(pParse, pList); /* FIX ME: The following is a temporary hack. */ if( 0==sqlite3StrNICmp(zId, "classof", nId) ){ assert( nExpr==1 ); sqlite3VdbeAddOp(v, OP_Class, nExpr, 0); }else{ - sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER); + sqlite3VdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_FUNCDEF); } break; } case TK_SELECT: { sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0); @@ -1344,35 +1343,28 @@ } } /* ** Generate code that pushes the value of every element of the given -** expression list onto the stack. If the includeTypes flag is true, -** then also push a string that is the datatype of each element onto -** the stack after the value. +** expression list onto the stack. ** ** Return the number of elements pushed onto the stack. */ int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ - ExprList *pList, /* The expression list to be coded */ - int includeTypes /* TRUE to put datatypes on the stack too */ + ExprList *pList /* The expression list to be coded */ ){ struct ExprList_item *pItem; int i, n; Vdbe *v; if( pList==0 ) return 0; v = sqlite3GetVdbe(pParse); n = pList->nExpr; for(pItem=pList->a, i=0; ipExpr); - if( includeTypes ){ - /** DEPRECATED. This will go away with the new function interface **/ - sqlite3VdbeOp3(v, OP_String, 0, 0, "numeric", P3_STATIC); - } } - return includeTypes ? n*2 : n; + return n; } /* ** Generate code for a boolean expression such that a jump is made ** to the label "dest" if the expression is true but execution @@ -1712,13 +1704,15 @@ } if( p==0 && pMaybe ){ assert( createFlag==0 ); 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->pNext = pFirst; - p->dataType = pFirst ? pFirst->dataType : SQLITE_NUMERIC; - sqlite3HashInsert(&db->aFunc, zName, nName, (void*)p); + p->zName = (char*)&p[1]; + memcpy(p->zName, zName, nName); + p->zName[nName] = 0; + sqlite3HashInsert(&db->aFunc, p->zName, nName, (void*)p); } return p; } Index: src/func.c ================================================================== --- src/func.c +++ src/func.c @@ -14,11 +14,11 @@ ** ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** 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 #include #include #include @@ -27,103 +27,122 @@ #include "os.h" /* ** Implementation of the non-aggregate min() and max() functions */ -static void minmaxFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - const char *zBest; +static void minmaxFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ int i; - int (*xCompare)(const char*, const char*); int mask; /* 0 for min() or 0xffffffff for max() */ - const char *zArg; + int iBest; if( argc==0 ) return; mask = (int)sqlite3_user_data(context); - zBest = sqlite3_value_data(argv[0]); - if( zBest==0 ) return; - zArg = sqlite3_value_data(argv[1]); - if( zArg[0]=='n' ){ - xCompare = sqlite3Compare; - }else{ - xCompare = strcmp; - } - for(i=2; ilen ){ p2 = len-p1; } -#ifdef SQLITE_UTF8 for(i=0; i "; int iMin, iMax, n, r, i; unsigned char zBuf[1000]; if( argc>=1 ){ - iMin = atoi(sqlite3_value_data(argv[0])); + iMin = sqlite3_value_int(argv[0]); if( iMin<0 ) iMin = 0; if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1; }else{ iMin = 1; } if( argc>=2 ){ - iMax = atoi(sqlite3_value_data(argv[1])); + iMax = sqlite3_value_int(argv[1]); if( iMax=sizeof(zBuf) ) iMax = sizeof(zBuf)-1; }else{ iMax = 50; } @@ -576,27 +621,12 @@ } } static void minMaxFinalize(sqlite3_context *context){ sqlite3_value *pRes; pRes = (sqlite3_value *)sqlite3_get_context(context, sizeof(Mem)); - if( pRes->flags ){ - switch( sqlite3_value_type(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); - } + sqlite3_result(context, pRes); } } /* ** This function registered all of the above C functions as SQL @@ -605,92 +635,72 @@ */ void sqlite3RegisterBuiltinFunctions(sqlite *db){ static struct { char *zName; signed char nArg; - signed char dataType; u8 argType; /* 0: none. 1: db 2: (-1) */ void (*xFunc)(sqlite3_context*,int,sqlite3_value **); } aFuncs[] = { - { "min", -1, SQLITE_ARGS, 0, minmaxFunc }, - { "min", 0, 0, 0, 0 }, - { "max", -1, SQLITE_ARGS, 2, minmaxFunc }, - { "max", 0, 0, 2, 0 }, - { "typeof", 1, SQLITE_TEXT, 0, typeofFunc }, - { "classof", 1, SQLITE_TEXT, 0, typeofFunc }, /* FIX ME: hack */ - { "length", 1, SQLITE_NUMERIC, 0, lengthFunc }, - { "substr", 3, SQLITE_TEXT, 0, substrFunc }, - { "abs", 1, SQLITE_NUMERIC, 0, absFunc }, - { "round", 1, SQLITE_NUMERIC, 0, roundFunc }, - { "round", 2, SQLITE_NUMERIC, 0, roundFunc }, - { "upper", 1, SQLITE_TEXT, 0, upperFunc }, - { "lower", 1, SQLITE_TEXT, 0, lowerFunc }, - { "coalesce", -1, SQLITE_ARGS, 0, ifnullFunc }, - { "coalesce", 0, 0, 0, 0 }, - { "coalesce", 1, 0, 0, 0 }, - { "ifnull", 2, SQLITE_ARGS, 0, ifnullFunc }, - { "random", -1, SQLITE_NUMERIC, 0, randomFunc }, - { "like", 2, SQLITE_NUMERIC, 0, likeFunc }, - { "glob", 2, SQLITE_NUMERIC, 0, globFunc }, - { "nullif", 2, SQLITE_ARGS, 0, nullifFunc }, - { "sqlite_version",0,SQLITE_TEXT, 0, versionFunc}, - { "quote", 1, SQLITE_ARGS, 0, quoteFunc }, - { "last_insert_rowid", 0, SQLITE_NUMERIC, 1, last_insert_rowid }, - { "change_count", 0, SQLITE_NUMERIC, 1, change_count }, - { "last_statement_change_count", - 0, SQLITE_NUMERIC, 1, last_statement_change_count }, + { "min", -1, 0, minmaxFunc }, + { "min", 0, 0, 0 }, + { "max", -1, 2, minmaxFunc }, + { "max", 0, 2, 0 }, + { "typeof", 1, 0, typeofFunc }, + { "classof", 1, 0, typeofFunc }, /* FIX ME: hack */ + { "length", 1, 0, lengthFunc }, + { "substr", 3, 0, substrFunc }, + { "abs", 1, 0, absFunc }, + { "round", 1, 0, roundFunc }, + { "round", 2, 0, roundFunc }, + { "upper", 1, 0, upperFunc }, + { "lower", 1, 0, lowerFunc }, + { "coalesce", -1, 0, ifnullFunc }, + { "coalesce", 0, 0, 0 }, + { "coalesce", 1, 0, 0 }, + { "ifnull", 2, 0, ifnullFunc }, + { "random", -1, 0, randomFunc }, + { "like", 2, 0, likeFunc }, + { "glob", 2, 0, globFunc }, + { "nullif", 2, 0, nullifFunc }, + { "sqlite_version", 0, 0, versionFunc}, + { "quote", 1, 0, quoteFunc }, + { "last_insert_rowid", 0, 1, last_insert_rowid }, + { "change_count", 0, 1, change_count }, + { "last_statement_change_count", 0, 1, last_statement_change_count }, #ifdef SQLITE_SOUNDEX - { "soundex", 1, SQLITE_TEXT, 0, soundexFunc}, + { "soundex", 1, 0, soundexFunc}, #endif #ifdef SQLITE_TEST - { "randstr", 2, SQLITE_TEXT, 0, randStr }, + { "randstr", 2, 0, randStr }, #endif }; static struct { char *zName; signed char nArg; - signed char dataType; u8 argType; void (*xStep)(sqlite3_context*,int,sqlite3_value**); void (*xFinalize)(sqlite3_context*); } aAggs[] = { - { "min", 1, 0, 0, minmaxStep, minMaxFinalize }, - { "max", 1, 0, 2, minmaxStep, minMaxFinalize }, - { "sum", 1, SQLITE_NUMERIC, 0, sumStep, sumFinalize }, - { "avg", 1, SQLITE_NUMERIC, 0, sumStep, avgFinalize }, - { "count", 0, SQLITE_NUMERIC, 0, countStep, countFinalize }, - { "count", 1, SQLITE_NUMERIC, 0, countStep, countFinalize }, + { "min", 1, 0, minmaxStep, minMaxFinalize }, + { "max", 1, 2, minmaxStep, minMaxFinalize }, + { "sum", 1, 0, sumStep, sumFinalize }, + { "avg", 1, 0, sumStep, avgFinalize }, + { "count", 0, 0, countStep, countFinalize }, + { "count", 1, 0, countStep, countFinalize }, #if 0 - { "stddev", 1, SQLITE_NUMERIC, 0, stdDevStep, stdDevFinalize }, + { "stddev", 1, 0, stdDevStep, stdDevFinalize }, #endif }; - static const char *azTypeFuncs[] = { "min", "max", "typeof" }; int i; for(i=0; iaFunc, azTypeFuncs[i], n); - while( p ){ - p->includeTypes = 1; - p = p->pNext; - } } sqlite3RegisterDateTimeFunctions(db); } - - - Index: src/main.c ================================================================== --- src/main.c +++ src/main.c @@ -12,11 +12,11 @@ ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** 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 "os.h" #include @@ -410,11 +410,11 @@ } /* ** 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 the number of changes in the most recent call to sqlite3_exec(). @@ -693,24 +693,10 @@ iCollateArg, pUserData, xFunc, xStep, xFinal); sqliteFree(zFunctionName8); 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 ** is returned. ** ** A NULL trace function means that no tracing is executes. A non-NULL @@ -1026,11 +1012,11 @@ db->magic = SQLITE_MAGIC_BUSY; db->nDb = 2; db->aDb = db->aDbStatic; db->enc = def_enc; /* 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); for(i=0; inDb; i++){ sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0); sqlite3HashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0); Index: src/select.c ================================================================== --- src/select.c +++ src/select.c @@ -10,11 +10,11 @@ ** ************************************************************************* ** This file contains C code routines that are called by the parser ** 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" /* @@ -2336,11 +2336,11 @@ if( isAgg ){ sqlite3VdbeAddOp(v, OP_AggReset, 0, pParse->nAgg); for(i=0; inAgg; i++){ FuncDef *pFunc; 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 ){ sqlite3VdbeAddOp(v, OP_String, 0, 0); sqlite3VdbeAddOp(v, OP_AggFocus, 0, 0); @@ -2410,11 +2410,11 @@ assert( pAgg->pFunc->xStep!=0 ); pDef = pAgg->pFunc; pE = pAgg->pExpr; assert( pE!=0 ); assert( pE->op==TK_AGG_FUNCTION ); - nExpr = sqlite3ExprCodeExprList(pParse, pE->pList, pDef->includeTypes); + nExpr = sqlite3ExprCodeExprList(pParse, pE->pList); sqlite3VdbeAddOp(v, OP_Integer, i, 0); sqlite3VdbeOp3(v, OP_AggFunc, 0, nExpr, (char*)pDef, P3_POINTER); } } Index: src/sqlite.h.in ================================================================== --- src/sqlite.h.in +++ src/sqlite.h.in @@ -10,11 +10,11 @@ ** ************************************************************************* ** This header file defines the interface that the SQLite library ** 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_ #define _SQLITE_H_ #include /* Needed for the definition of va_list */ @@ -161,11 +161,11 @@ ** available as the ROWID, OID, or _ROWID_ column.) The following routine ** returns the integer key of the most recent insert in the database. ** ** 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 ** (or inserted or deleted) by the most recent called sqlite3_exec(). ** @@ -1122,30 +1122,10 @@ void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), 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 ** aggregate function instance. The current call to xStep counts so this ** routine always returns at least 1. */ @@ -1321,9 +1301,14 @@ ** terminator character. */ void sqlite3_result_error(sqlite3_context*, const char*, 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 } /* End of the 'extern "C"' block */ #endif #endif Index: src/sqliteInt.h ================================================================== --- src/sqliteInt.h +++ src/sqliteInt.h @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** 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 "sqlite.h" #include "hash.h" #include "parse.h" @@ -158,24 +158,19 @@ */ #define Addr(X) ((uptr)X) /* ** 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 -** bytes (or 16MB-1). We have arbitrarily set the limit to just 1MB -** here because the overflow page chain is inefficient for really big -** records and we want to discourage people from thinking that +** row of a single table. The upper bound on this limit is +** 9223372036854775808 bytes (or 2**63). We have arbitrarily set the +** limit to just 1MB here because the overflow page chain is inefficient +** 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 ** change this define and recompile to increase or decrease the record ** 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 16777198 */ /* ** If memory allocation problems are found, recompile with ** ** -DMEMORY_DEBUG=1 @@ -332,22 +327,10 @@ #define TEXT_Utf16 (SQLITE3_BIGENDIAN?TEXT_Utf16be:TEXT_Utf16le) /* ** 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 ** 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 ** the TEMP_STORE macro. ** @@ -460,19 +443,17 @@ ** structure. A pointer to this structure is stored in the sqlite.aFunc ** hash table. When multiple functions have the same name, the hash table ** points to a linked list of these structures. */ struct FuncDef { - void (*xFunc)(sqlite3_context*,int,sqlite3_value**); /* Regular function */ - void (*xStep)(sqlite3_context*,int,sqlite3_value**); /* Aggregate function step */ - 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 */ - FuncDef *pNext; /* Next function with same name */ + char *zName; /* SQL name of the function */ + int nArg; /* Number of arguments. -1 means unlimited */ + void *pUserData; /* User data parameter */ + 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 */ }; /* ** information about each column of an SQL table is held in an instance ** of this structure. @@ -1254,11 +1235,11 @@ void sqlite3DeleteFrom(Parse*, SrcList*, Expr*); void sqlite3Update(Parse*, SrcList*, ExprList*, Expr*, int); WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, int, ExprList**); void sqlite3WhereEnd(WhereInfo*); void sqlite3ExprCode(Parse*, Expr*); -int sqlite3ExprCodeExprList(Parse*, ExprList*, int); +int sqlite3ExprCodeExprList(Parse*, ExprList*); void sqlite3ExprIfTrue(Parse*, Expr*, int, int); void sqlite3ExprIfFalse(Parse*, Expr*, int, int); Table *sqlite3FindTable(sqlite*,const char*, const char*); Table *sqlite3LocateTable(Parse*,const char*, const char*); Index *sqlite3FindIndex(sqlite*,const char*, const char*); Index: src/tclsqlite.c ================================================================== --- src/tclsqlite.c +++ src/tclsqlite.c @@ -9,11 +9,11 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* ** 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 */ #include "sqliteInt.h" #include "tcl.h" @@ -862,11 +862,10 @@ pFunc->interp = interp; pFunc->pNext = pDb->pFunc; pFunc->zScript = (char*)&pFunc[1]; strcpy(pFunc->zScript, zScript); sqlite3_create_function(pDb->db, zName, -1, 0, 0, pFunc, tclSqlFunc, 0, 0); - sqlite3_function_type(pDb->db, zName, SQLITE_NUMERIC); break; } /* ** $db last_insert_rowid @@ -1243,8 +1242,5 @@ return 0; } #endif /* TCLSH */ #endif /* !defined(NO_TCL) */ - - - Index: src/vdbe.c ================================================================== --- src/vdbe.c +++ src/vdbe.c @@ -41,11 +41,11 @@ ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** 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.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 "os.h" #include #include "vdbeInt.h" @@ -5862,11 +5862,12 @@ }else{ /* Cannot define a string subtype for non-string objects */ assert( (pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 ); } /* 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 ){ sqlite3SetString(&p->zErrMsg, "jump destination out of range", (char*)0); rc = SQLITE_INTERNAL; } Index: src/vdbe.h ================================================================== --- src/vdbe.h +++ src/vdbe.h @@ -13,11 +13,11 @@ ** ** This header defines the interface to the virtual database engine ** or VDBE. The VDBE implements an abstract machine that runs a ** 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_ #define _SQLITE_VDBE_H_ #include @@ -67,20 +67,21 @@ #define P3_NOTUSED 0 /* The P3 parameter is not used */ #define P3_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ #define P3_STATIC (-2) /* Pointer to a static string */ #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_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 ** is made. That copy is freed when the Vdbe is finalized. But if the ** argument is P3_KEYINFO_HANDOFF, the passed in pointer is used. It still ** gets freed when the Vdbe is finalized so it still should be obtained ** from a single sqliteMalloc(). But no copy is made and the calling ** 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 ** of a VdbeOp structure into a negative number so that ** sqlite3VdbeAddOpList() knows that the address is relative. Calling Index: src/vdbeaux.c ================================================================== --- src/vdbeaux.c +++ src/vdbeaux.c @@ -514,10 +514,21 @@ case P3_COLLSEQ: { CollSeq *pColl = (CollSeq*)pOp->p3; sprintf(zTemp, "collseq(%.20s)", pColl->zName); zP3 = zTemp; 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: { zP3 = pOp->p3; if( zP3==0 ){ zP3 = ""; @@ -1867,14 +1878,17 @@ pMem->n += nulTermLen; pMem->flags |= MEM_Term; } /* -** 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 ** 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){ MemSetInt(&pCtx->s, iVal); } void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ MemSetInt(&pCtx->s, iVal); @@ -1916,6 +1930,5 @@ } void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ pCtx->isError = 1; MemSetStr(&pCtx->s, z, n, TEXT_Utf16, 1); } -