func.c revision cd37da7426f0c49c14ad9a8a07638ca971477566
#pragma ident "%Z%%M% %I% %E% SMI"
/*
** 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.43.2.3 2004/07/18 23:03:11 drh Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <sys/u8_textprep.h>
#include <assert.h>
#include "sqliteInt.h"
#include "os.h"
/*
** Implementation of the non-aggregate min() and max() functions
*/
const char *zBest;
int i;
int (*xCompare)(const char*, const char*);
int mask; /* 0 for min() or 0xffffffff for max() */
if( argc==0 ) return;
if( zBest==0 ) return;
}else{
}
if( argv[i]==0 ) return;
}
}
}
/*
** Return the type of the argument.
*/
}
/*
** Implementation of the length() function
*/
const char *z;
int len;
z = argv[0];
if( z==0 ) return;
#ifdef SQLITE_UTF8
#else
#endif
}
/*
** Implementation of the abs() function
*/
const char *z;
z = argv[0];
if( z==0 ) return;
}
/*
** Implementation of the substr() function
*/
const char *z;
#ifdef SQLITE_UTF8
const char *z2;
int i;
#endif
z = argv[0];
if( z==0 ) return;
#ifdef SQLITE_UTF8
#else
#endif
if( p1<0 ){
if( p1<0 ){
p1 = 0;
}
}else if( p1>0 ){
p1--;
}
}
#ifdef SQLITE_UTF8
for(i=0; i<p1 && z[i]; i++){
}
}
#endif
}
/*
** Implementation of the round() function
*/
int n;
double r;
char zBuf[100];
if( n>30 ) n = 30;
if( n<0 ) n = 0;
r = sqliteAtoF(argv[0], 0);
}
/*
** Implementation of the upper() and lower() SQL functions.
*/
unsigned char *z;
int i;
if( z==0 ) return;
for(i=0; z[i]; i++){
}
}
unsigned char *z;
int i;
if( z==0 ) return;
for(i=0; z[i]; i++){
}
}
/*
* A utility wrapper around u8_textprep_str() that returns an allocated
* string. The result must be freed or passed to
* sqlite_set_result_string().
*
* This is a Solaris-specific function, though it could be made
* portable. u8_textprep_str() and friends are CDDL'ed. This code was
* added to this file without changing the public domain notice, and
* therefore is in the public domain as well.
*/
static
char *
utf8textprep(const char *s, int flag)
{
char *outs;
/*
* u8_textprep_str() does not allocate memory. The input and
* output buffers may differ in size (though that would be more
* likely when normalization is done). We have to loop over it...
*
* To improve the chances that we can avoid looping we add 10
* bytes of output buffer room the first go around.
*/
return (NULL);
return (NULL);
s += (inlen - inbytesleft);
/* adjust outbytesleft and outlen */
outlen += inbytesleft;
}
if (rc < 0) {
return (NULL);
}
return (res);
}
/*
* A Unicode-capable case-folding (to lower) function
*
* See block comment for case_fold_utf8().
*/
static
void
{
/*
* SQLite functions can take many arguments, but this function
* uses only one, and we call sqlite_create_function() with
* nArg == 1.
*/
out:
}
static
void
{
/*
* SQLite functions can take many arguments, but this function
* uses only one, and we call sqlite_create_function() with
* nArg == 1.
*/
out:
}
/*
** Implementation of the IFNULL(), NVL(), and COALESCE() functions.
** All three do the same thing. They return the first non-NULL
** argument.
*/
int i;
for(i=0; i<argc; i++){
if( argv[i] ){
break;
}
}
}
/*
** Implementation of random(). Return a random integer.
*/
int r;
sqliteRandomness(sizeof(r), &r);
}
/*
** Implementation of the last_insert_rowid() SQL function. The return
** value is the same as the sqlite_last_insert_rowid() API function.
*/
}
/*
** Implementation of the change_count() SQL function. The return
** value is the same as the sqlite_changes() API function.
*/
}
/*
** Implementation of the last_statement_change_count() SQL function. The
** return value is the same as the sqlite_last_statement_changes() API function.
*/
const char **argv){
}
/*
** Implementation of the like() SQL function. This function implements
** the build-in LIKE operator. The first argument to the function is the
** string and the second argument is the pattern. So, the SQL statements:
**
** A LIKE B
**
** is implemented as like(A,B).
*/
sqliteLikeCompare((const unsigned char*)argv[0],
(const unsigned char*)argv[1]));
}
/*
** Implementation of the glob() SQL function. This function implements
** the build-in GLOB operator. The first argument to the function is the
** string and the second argument is the pattern. So, the SQL statements:
**
** A GLOB B
**
** is implemented as glob(A,B).
*/
sqliteGlobCompare((const unsigned char*)argv[0],
(const unsigned char*)argv[1]));
}
/*
** Implementation of the NULLIF(x,y) function. The result is the first
** argument if the arguments are different. The result is NULL if the
** arguments are equal to each other.
*/
}
}
/*
** Implementation of the VERSION(*) function. The result is the version
** of the SQLite library that is running.
*/
}
/*
** EXPERIMENTAL - This is not an official function. The interface may
** change. This function may disappear. Do not write code that depends
** on this function.
**
** Implementation of the QUOTE() function. This function takes a single
** argument. If the argument is numeric, the return value is the same as
** the argument. If the argument is NULL, the return value is the string
** "NULL". Otherwise, the argument is enclosed in single quotes with
** single-quote escapes.
*/
if( argc<1 ) return;
if( argv[0]==0 ){
}else if( sqliteIsNumber(argv[0]) ){
}else{
int i,j,n;
char *z;
z = sqliteMalloc( i+n+3 );
if( z==0 ) return;
z[0] = '\'';
for(i=0, j=1; argv[0][i]; i++){
z[j++] = argv[0][i];
if( argv[0][i]=='\'' ){
z[j++] = '\'';
}
}
z[j++] = '\'';
z[j] = 0;
sqlite_set_result_string(context, z, j);
sqliteFree(z);
}
}
#ifdef SQLITE_SOUNDEX
/*
** Compute the soundex encoding of a word.
*/
char zResult[8];
const char *zIn;
int i, j;
static const unsigned char iCode[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
};
if( zIn[i] ){
if( code>0 ){
}
}
while( j<4 ){
zResult[j++] = '0';
}
zResult[j] = 0;
}else{
}
}
#endif
#ifdef SQLITE_TEST
/*
** This function generates a string of random characters. Used for
** generating test data.
*/
static const unsigned char zSrc[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789"
".-!,:*^+=_|?/<> ";
unsigned char zBuf[1000];
if( argc>=1 ){
}else{
iMin = 1;
}
if( argc>=2 ){
}else{
iMax = 50;
}
n = iMin;
sqliteRandomness(sizeof(r), &r);
r &= 0x7fffffff;
}
sqliteRandomness(n, zBuf);
for(i=0; i<n; i++){
}
zBuf[n] = 0;
}
#endif
/*
** An instance of the following structure holds the context of a
** sum() or avg() aggregate computation.
*/
struct SumCtx {
double sum; /* Sum of terms */
int cnt; /* Number of elements summed */
};
/*
** Routines used to compute the sum or average.
*/
SumCtx *p;
if( argc<1 ) return;
p = sqlite_aggregate_context(context, sizeof(*p));
if( p && argv[0] ){
p->cnt++;
}
}
SumCtx *p;
p = sqlite_aggregate_context(context, sizeof(*p));
}
SumCtx *p;
p = sqlite_aggregate_context(context, sizeof(*p));
if( p && p->cnt>0 ){
}
}
/*
** An instance of the following structure holds the context of a
** variance or standard deviation computation.
*/
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.
*/
StdDevCtx *p;
double x;
if( argc<1 ) return;
p = sqlite_aggregate_context(context, sizeof(*p));
if( p && argv[0] ){
x = sqliteAtoF(argv[0], 0);
p->sum += x;
p->sum2 += x*x;
p->cnt++;
}
}
if( p && p->cnt>1 ){
}
}
#endif
/*
** The following structure keeps track of state information for the
** count() aggregate function.
*/
struct CountCtx {
int n;
};
/*
** Routines to implement the count() aggregate function.
*/
CountCtx *p;
p = sqlite_aggregate_context(context, sizeof(*p));
p->n++;
}
}
CountCtx *p;
p = sqlite_aggregate_context(context, sizeof(*p));
sqlite_set_result_int(context, p ? p->n : 0);
}
/*
** This function tracks state information for the min() and max()
** aggregate functions.
*/
struct MinMaxCtx {
char *z; /* The best so far */
};
/*
** Routines to implement min() and max() aggregate functions.
*/
MinMaxCtx *p;
int (*xCompare)(const char*, const char*);
int mask; /* 0 for min() or 0xffffffff for max() */
if( argv[0]==0 ) return; /* Ignore NULL values */
}else{
}
p = sqlite_aggregate_context(context, sizeof(*p));
if( p==0 || argc<1 ) return;
int len;
if( p->zBuf[0] ){
sqliteFree(p->z);
}
p->z = &p->zBuf[1];
p->zBuf[0] = 0;
}else{
p->zBuf[0] = 1;
if( p->z==0 ) return;
}
}
}
MinMaxCtx *p;
p = sqlite_aggregate_context(context, sizeof(*p));
if( p && p->z && p->zBuf[0]<2 ){
}
if( p && p->zBuf[0] ){
sqliteFree(p->z);
}
}
/*
** This function registered all of the above C functions as SQL
** functions. This should be the only routine in this file with
** external linkage.
*/
static struct {
char *zName;
signed char nArg;
signed char dataType;
void (*xFunc)(sqlite_func*,int,const char**);
} aFuncs[] = {
{ "min", 0, 0, 0, 0 },
{ "max", 0, 0, 2, 0 },
{ "coalesce", 0, 0, 0, 0 },
{ "coalesce", 1, 0, 0, 0 },
{ "last_statement_change_count",
#ifdef SQLITE_SOUNDEX
#endif
#ifdef SQLITE_TEST
#endif
};
static struct {
char *zName;
signed char nArg;
signed char dataType;
void (*xStep)(sqlite_func*,int,const char**);
void (*xFinalize)(sqlite_func*);
} aAggs[] = {
#if 0
#endif
};
int i;
void *pArg;
case 0: pArg = 0; break;
}
}
}
void *pArg;
case 0: pArg = 0; break;
}
}
for(i=0; i<sizeof(azTypeFuncs)/sizeof(azTypeFuncs[0]); i++){
int n = strlen(azTypeFuncs[i]);
while( p ){
p->includeTypes = 1;
p = p->pNext;
}
}
}