aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2004-05-26 16:54:42 +0000
committerdrh <drh@noemail.net>2004-05-26 16:54:42 +0000
commitf9b596ebc05ff3365bed6b8dafb02d251c652889 (patch)
treedb56a7ae7dafee19f1d8fe3f947333c0914a7e0e /src
parentb77f5dadbf3e34d9724c836c6871955b59694123 (diff)
downloadsqlite-f9b596ebc05ff3365bed6b8dafb02d251c652889.tar.gz
sqlite-f9b596ebc05ff3365bed6b8dafb02d251c652889.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/date.c49
-rw-r--r--src/expr.c28
-rw-r--r--src/func.c312
-rw-r--r--src/main.c20
-rw-r--r--src/select.c6
-rw-r--r--src/sqlite.h.in29
-rw-r--r--src/sqliteInt.h45
-rw-r--r--src/tclsqlite.c6
-rw-r--r--src/vdbe.c5
-rw-r--r--src/vdbe.h7
-rw-r--r--src/vdbeaux.c17
11 files changed, 252 insertions, 272 deletions
diff --git a/src/date.c b/src/date.c
index 935b08690..3a15ba163 100644
--- a/src/date.c
+++ b/src/date.c
@@ -16,7 +16,7 @@
** 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:
**
@@ -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
*/
-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);
@@ -677,7 +681,11 @@ static void juliandayFunc(sqlite3_context *context, int argc, sqlite3_value **ar
**
** 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];
@@ -693,7 +701,11 @@ static void datetimeFunc(sqlite3_context *context, int argc, sqlite3_value **arg
**
** 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];
@@ -708,7 +720,11 @@ static void timeFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
**
** 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];
@@ -737,7 +753,11 @@ static void dateFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
** %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;
@@ -852,15 +872,14 @@ 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;
@@ -868,11 +887,5 @@ void sqlite3RegisterDateTimeFunctions(sqlite *db){
for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, 0, 0, 0,
aFuncs[i].xFunc, 0, 0);
- if( aFuncs[i].xFunc ){
- sqlite3_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
- }
}
}
-
-
-
diff --git a/src/expr.c b/src/expr.c
index c774f73a5..8a97ca9e0 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -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.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 <ctype.h>
@@ -503,7 +503,6 @@ int sqlite3IsRowid(const char *z){
** 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.
@@ -1224,13 +1223,13 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
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;
}
@@ -1346,16 +1345,13 @@ void sqlite3ExprCode(Parse *pParse, Expr *pExpr){
/*
** 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;
@@ -1365,12 +1361,8 @@ int sqlite3ExprCodeExprList(
n = pList->nExpr;
for(pItem=pList->a, i=0; i<n; i++, pItem++){
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 includeTypes ? n*2 : n;
+ return n;
}
/*
@@ -1714,11 +1706,13 @@ FuncDef *sqlite3FindFunction(
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;
}
diff --git a/src/func.c b/src/func.c
index 65789a6fb..7aaee79a3 100644
--- a/src/func.c
+++ b/src/func.c
@@ -16,7 +16,7 @@
** 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 <ctype.h>
#include <math.h>
@@ -29,45 +29,41 @@
/*
** 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; i<argc; i+=2){
- zArg = sqlite3_value_data(argv[i]);
- if( zArg==0 ) return;
- if( (xCompare(zArg, zBest)^mask)<0 ){
- zBest = zArg;
+ iBest = 0;
+ for(i=1; i<argc; i++){
+ if( (sqlite3MemCompare(argv[iBest], argv[i], 0)^mask)<0 ){
+ iBest = i;
}
}
- sqlite3_result_text(context, zBest, -1, 1);
+ sqlite3_result(context, argv[iBest]);
}
/*
** 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;
- assert( argc==2 );
switch( sqlite3_value_type(argv[0]) ){
- case SQLITE3_NULL: z = "null" ; break;
- case SQLITE3_INTEGER: z = "integer" ; break;
- case SQLITE3_TEXT: z = "text" ; break;
- case SQLITE3_FLOAT: z = "real" ; break;
- case SQLITE3_BLOB: z = "blob" ; break;
+ case SQLITE3_NULL: z = "null"; break;
+ case SQLITE3_INTEGER: z = "integer"; break;
+ case SQLITE3_TEXT: z = "text"; break;
+ case SQLITE3_FLOAT: z = "real"; break;
+ case SQLITE3_BLOB: z = "blob"; break;
}
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
*/
-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;
int len;
assert( argc==1 );
- z = sqlite3_value_data(argv[0]);
- if( z==0 ) return;
-#ifdef SQLITE_UTF8
- for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
-#else
- len = strlen(z);
-#endif
- sqlite3_result_int32(context, len);
+ switch( sqlite3_value_type(argv[0]) ){
+ case SQLITE3_BLOB:
+ 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++; }
+ 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){
const char *z;
assert( argc==1 );
- z = sqlite3_value_data(argv[0]);
- if( z==0 ) return;
- if( z[0]=='-' && isdigit(z[1]) ) z++;
- sqlite3_result_text(context, z, -1, 1);
+ switch( sqlite3_value_type(argv[0]) ){
+ case SQLITE3_INTEGER: {
+ sqlite3_result_int64(context, -sqlite3_value_int(argv[0]));
+ 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
*/
-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;
-#ifdef SQLITE_UTF8
const char *z2;
int i;
-#endif
int p1, p2, len;
+
assert( argc==3 );
z = sqlite3_value_data(argv[0]);
if( z==0 ) return;
p1 = sqlite3_value_int(argv[1]);
p2 = sqlite3_value_int(argv[2]);
-#ifdef SQLITE_UTF8
for(len=0, z2=z; *z2; z2++){ if( (0xc0&*z2)!=0x80 ) len++; }
-#else
- len = strlen(z);
-#endif
if( p1<0 ){
p1 += len;
if( p1<0 ){
@@ -134,7 +153,6 @@ static void substrFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
if( p1+p2>len ){
p2 = len-p1;
}
-#ifdef SQLITE_UTF8
for(i=0; i<p1 && z[i]; i++){
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++;
}
while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; }
-#endif
if( p2<0 ) p2 = 0;
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
** 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;
for(i=0; i<argc; 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;
}
}
@@ -216,7 +237,11 @@ static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv)
/*
** 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;
sqlite3Randomness(sizeof(r), &r);
sqlite3_result_int32(context, r);
@@ -232,14 +257,18 @@ static void last_insert_rowid(
sqlite3_value **argv
){
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
** 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);
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
** arguments are equal to each other.
*/
-static void nullifFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
- const unsigned char *zX = sqlite3_value_data(argv[0]);
- const unsigned char *zY = sqlite3_value_data(argv[1]);
- if( zX!=0 && sqlite3Compare(zX, zY)!=0 ){
- sqlite3_result_text(context, zX, -1, 1);
+static void nullifFunc(
+ sqlite3_context *context,
+ int argc,
+ sqlite3_value **argv
+){
+ 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
** 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);
}
@@ -331,27 +366,37 @@ static void versionFunc(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]);
if( argc<1 ) return;
- if( zArg==0 ){
- sqlite3_result_text(context, "NULL", 4, 0);
- }else if( sqlite3IsNumber(zArg, 0, TEXT_Utf8) ){
- sqlite3_result_text(context, zArg, -1, 1);
- }else{
- int i,j,n;
- char *z;
- for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
- z = sqliteMalloc( i+n+3 );
- if( z==0 ) return;
- z[0] = '\'';
- for(i=0, j=1; zArg[i]; i++){
- z[j++] = zArg[i];
- if( zArg[i]=='\'' ){
- z[j++] = '\'';
+ switch( sqlite3_value_type(argv[0]) ){
+ case SQLITE3_NULL: {
+ sqlite3_result_text(context, "NULL", 4, 0);
+ break;
+ }
+ 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;
+ const char *zArg = sqlite3_value_data(argv[0]);
+ char *z;
+
+ for(i=n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; }
+ z = sqliteMalloc( i+n+3 );
+ if( z==0 ) return;
+ z[0] = '\'';
+ for(i=0, j=1; zArg[i]; i++){
+ z[j++] = zArg[i];
+ if( zArg[i]=='\'' ){
+ z[j++] = '\'';
+ }
}
+ z[j++] = '\'';
+ z[j] = 0;
+ sqlite3_result_text(context, z, j, 1);
+ sqliteFree(z);
}
- z[j++] = '\'';
- z[j] = 0;
- sqlite3_result_text(context, z, j, 1);
- sqliteFree(z);
}
}
@@ -409,14 +454,14 @@ static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){
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<iMin ) iMax = iMin;
if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
}else{
@@ -578,23 +623,8 @@ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv)
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);
}
}
@@ -607,90 +637,70 @@ 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; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
void *pArg = aFuncs[i].argType==2 ? (void*)(-1) : db;
sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, 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++){
void *pArg = aAggs[i].argType==2 ? (void*)(-1) : db;
sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, 0, 0, pArg,
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);
}
-
-
-
diff --git a/src/main.c b/src/main.c
index 8a4f5ce99..e9c87aab2 100644
--- a/src/main.c
+++ b/src/main.c
@@ -14,7 +14,7 @@
** 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"
@@ -412,7 +412,7 @@ static int binaryCollatingFunc(
/*
** 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;
}
@@ -696,20 +696,6 @@ int sqlite3_create_function16(
}
/*
-** 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.
**
@@ -1028,7 +1014,7 @@ static int openDatabase(
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; i<db->nDb; i++){
sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);
diff --git a/src/select.c b/src/select.c
index 2340cb5b4..36431d91e 100644
--- a/src/select.c
+++ b/src/select.c
@@ -12,7 +12,7 @@
** 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"
@@ -2338,7 +2338,7 @@ int sqlite3Select(
for(i=0; i<pParse->nAgg; 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 ){
@@ -2412,7 +2412,7 @@ int sqlite3Select(
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);
}
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index a1d8f7649..027ba7346 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -12,7 +12,7 @@
** 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_
@@ -163,7 +163,7 @@ int sqlite3_exec(
**
** 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
@@ -1125,26 +1125,6 @@ int sqlite3_create_function16(
);
/*
-** 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.
@@ -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_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
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 3a94128be..e23710e78 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -11,7 +11,7 @@
*************************************************************************
** 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"
@@ -160,20 +160,15 @@ extern const int sqlite3one;
/*
** 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
@@ -334,18 +329,6 @@ struct Db {
/*
** 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
@@ -462,15 +445,13 @@ struct sqlite {
** 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 */
};
/*
@@ -1256,7 +1237,7 @@ 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*);
diff --git a/src/tclsqlite.c b/src/tclsqlite.c
index 877ee1056..a1a1a44c9 100644
--- a/src/tclsqlite.c
+++ b/src/tclsqlite.c
@@ -11,7 +11,7 @@
*************************************************************************
** 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 */
@@ -864,7 +864,6 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
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;
}
@@ -1245,6 +1244,3 @@ int TCLSH_MAIN(int argc, char **argv){
#endif /* TCLSH */
#endif /* !defined(NO_TCL) */
-
-
-
diff --git a/src/vdbe.c b/src/vdbe.c
index 7cc4288b0..2b8e2822e 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -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.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"
@@ -5864,7 +5864,8 @@ default: {
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);
diff --git a/src/vdbe.h b/src/vdbe.h
index 80ecb0a78..b093f3082 100644
--- a/src/vdbe.h
+++ b/src/vdbe.h
@@ -15,7 +15,7 @@
** 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_
@@ -69,7 +69,8 @@ typedef struct VdbeOpList VdbeOpList;
#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
@@ -78,7 +79,7 @@ typedef struct VdbeOpList VdbeOpList;
** 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
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 60158fd32..b03e49372 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -517,6 +517,17 @@ static char *displayP3(Op *pOp, char *zTemp, int nTemp){
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 ){
@@ -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
** 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);
}
@@ -1918,4 +1932,3 @@ void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
pCtx->isError = 1;
MemSetStr(&pCtx->s, z, n, TEXT_Utf16, 1);
}
-