/* ** 2002 February 23 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains the C functions that implement various SQL ** functions of SQLite. ** ** 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 $ */ #include #include #include #include #include "sqliteInt.h" #include "vdbeInt.h" #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; int i; int (*xCompare)(const char*, const char*); int mask; /* 0 for min() or 0xffffffff for max() */ const char *zArg; 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; i0 ){ p1--; } if( p1+p2>len ){ p2 = len-p1; } #ifdef SQLITE_UTF8 for(i=0; i30 ) n = 30; if( n<0 ) n = 0; } if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return; r = sqlite3_value_float(argv[0]); sprintf(zBuf,"%.*f",n,r); sqlite3_result_text(context, zBuf, -1, 1); } /* ** Implementation of the upper() and lower() SQL functions. */ static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *z; int i; if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return; z = sqliteMalloc(sqlite3_value_bytes(argv[0])); if( z==0 ) return; strcpy(z, sqlite3_value_data(argv[0])); for(i=0; z[i]; i++){ if( islower(z[i]) ) z[i] = toupper(z[i]); } sqlite3_result_text(context, z, -1, 1); sqliteFree(z); } static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *z; int i; if( argc<1 || SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return; z = sqliteMalloc(sqlite3_value_bytes(argv[0])); if( z==0 ) return; strcpy(z, sqlite3_value_data(argv[0])); for(i=0; z[i]; i++){ if( isupper(z[i]) ) z[i] = tolower(z[i]); } sqlite3_result_text(context, z, -1, 1); sqliteFree(z); } /* ** Implementation of the IFNULL(), NVL(), and COALESCE() functions. ** All three do the same thing. They return the first non-NULL ** argument. */ static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ int i; for(i=0; i0 ){ zResult[j++] = code + '0'; } } while( j<4 ){ zResult[j++] = '0'; } zResult[j] = 0; sqlite3_result_text(context, zResult, 4, 1); }else{ sqlite3_result_text(context, "?000", 4, 0); } } #endif #ifdef SQLITE_TEST /* ** This function generates a string of random characters. Used for ** generating test data. */ static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){ static const unsigned char zSrc[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" ".-!,:*^+=_|?/<> "; int iMin, iMax, n, r, i; unsigned char zBuf[1000]; if( argc>=1 ){ iMin = atoi(sqlite3_value_data(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])); if( iMax=sizeof(zBuf) ) iMax = sizeof(zBuf)-1; }else{ iMax = 50; } n = iMin; if( iMax>iMin ){ sqlite3Randomness(sizeof(r), &r); r &= 0x7fffffff; n += r%(iMax + 1 - iMin); } assert( nsum += sqlite3_value_float(argv[0]); p->cnt++; } } static void sumFinalize(sqlite3_context *context){ SumCtx *p; p = sqlite3_get_context(context, sizeof(*p)); sqlite3_result_double(context, p ? p->sum : 0.0); } static void avgFinalize(sqlite3_context *context){ SumCtx *p; p = sqlite3_get_context(context, sizeof(*p)); if( p && p->cnt>0 ){ sqlite3_result_double(context, p->sum/(double)p->cnt); } } /* ** An instance of the following structure holds the context of a ** variance or standard deviation computation. */ typedef struct StdDevCtx StdDevCtx; struct StdDevCtx { double sum; /* Sum of terms */ double sum2; /* Sum of the squares of terms */ int cnt; /* Number of terms counted */ }; #if 0 /* Omit because math library is required */ /* ** Routines used to compute the standard deviation as an aggregate. */ static void stdDevStep(sqlite3_context *context, int argc, const char **argv){ StdDevCtx *p; double x; if( argc<1 ) return; p = sqlite3_aggregate_context(context, sizeof(*p)); if( p && argv[0] ){ x = sqlite3AtoF(argv[0], 0); p->sum += x; p->sum2 += x*x; p->cnt++; } } static void stdDevFinalize(sqlite3_context *context){ double rN = sqlite3_aggregate_count(context); StdDevCtx *p = sqlite3_aggregate_context(context, sizeof(*p)); if( p && p->cnt>1 ){ double rCnt = cnt; sqlite3_set_result_double(context, sqrt((p->sum2 - p->sum*p->sum/rCnt)/(rCnt-1.0))); } } #endif /* ** The following structure keeps track of state information for the ** count() aggregate function. */ typedef struct CountCtx CountCtx; struct CountCtx { int n; }; /* ** Routines to implement the count() aggregate function. */ static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ CountCtx *p; p = sqlite3_get_context(context, sizeof(*p)); if( (argc==0 || SQLITE3_NULL!=sqlite3_value_type(argv[0])) && p ){ p->n++; } } static void countFinalize(sqlite3_context *context){ CountCtx *p; p = sqlite3_get_context(context, sizeof(*p)); sqlite3_result_int32(context, p ? p->n : 0); } /* ** This function tracks state information for the min() and max() ** aggregate functions. */ typedef struct MinMaxCtx MinMaxCtx; struct MinMaxCtx { char *z; /* The best so far */ char zBuf[28]; /* Space that can be used for storage */ }; /* ** Routines to implement min() and max() aggregate functions. */ static void minmaxStep(sqlite3_context *context, int argc, sqlite3_value **argv){ int max = 0; int cmp = 0; Mem *pArg = (Mem *)argv[0]; Mem *pBest = (Mem *)sqlite3_get_context(context, sizeof(*pBest)); if( SQLITE3_NULL==sqlite3_value_type(argv[0]) ) return; if( pBest->flags ){ /* This step function is used for both the min() and max() aggregates, ** the only difference between the two being that the sense of the ** comparison is inverted. For the max() aggregate, the ** sqlite3_user_data() function returns (void *)-1. For min() it ** returns (void *)db, where db is the sqlite3* database pointer. ** Therefore the next statement sets variable 'max' to 1 for the max() ** aggregate, or 0 for min(). */ max = ((sqlite3_user_data(context)==(void *)-1)?1:0); cmp = sqlite3MemCompare(pBest, pArg, 0); if( (max && cmp<0) || (!max && cmp>0) ){ sqlite3VdbeMemCopy(pBest, pArg); } }else{ sqlite3VdbeMemCopy(pBest, pArg); } } 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); } } } /* ** This function registered all of the above C functions as SQL ** functions. This should be the only routine in this file with ** external linkage. */ 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 }, #ifdef SQLITE_SOUNDEX { "soundex", 1, SQLITE_TEXT, 0, soundexFunc}, #endif #ifdef SQLITE_TEST { "randstr", 2, SQLITE_TEXT, 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 }, #if 0 { "stddev", 1, SQLITE_NUMERIC, 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); }