Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
func.c File Reference
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include "vdbeInt.h"
#include "os.h"

Go to the source code of this file.

Classes

struct  compareInfo
struct  SumCtx
struct  CountCtx

Defines

#define sqliteNextChar(X)   while( (0xc0&*++(X))==0x80 ){}
#define sqliteCharVal(X)   sqlite3ReadUtf8(X)

Typedefs

typedef struct SumCtx
typedef struct CountCtx

Functions

static CollSeqsqlite3GetFuncCollSeq (sqlite3_context *context)
static void minmaxFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void typeofFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void lengthFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void absFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void substrFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void roundFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void upperFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void lowerFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void ifnullFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void randomFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void last_insert_rowid (sqlite3_context *context, int arg, sqlite3_value **argv)
static void changes (sqlite3_context *context, int arg, sqlite3_value **argv)
static void total_changes (sqlite3_context *context, int arg, sqlite3_value **argv)
static int patternCompare (const u8 *zPattern, const u8 *zString, const struct compareInfo *pInfo, const int esc)
static void likeFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void nullifFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void versionFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void quoteFunc (sqlite3_context *context, int argc, sqlite3_value **argv)
static void sumStep (sqlite3_context *context, int argc, sqlite3_value **argv)
static void sumFinalize (sqlite3_context *context)
static void avgFinalize (sqlite3_context *context)
static void totalFinalize (sqlite3_context *context)
static void countStep (sqlite3_context *context, int argc, sqlite3_value **argv)
static void countFinalize (sqlite3_context *context)
static void minmaxStep (sqlite3_context *context, int argc, sqlite3_value **argv)
static void minMaxFinalize (sqlite3_context *context)
void sqlite3RegisterBuiltinFunctions (sqlite3 *db)
static void setLikeOptFlag (sqlite3 *db, const char *zName, int flagVal)
void sqlite3RegisterLikeFunctions (sqlite3 *db, int caseSensitive)
int sqlite3IsLikeFunction (sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc)

Variables

static struct compareInfo = { '*', '?', '[', 0 }

Class Documentation

struct compareInfo

Definition at line 317 of file func.c.

Class Members
u8 matchAll
u8 matchOne
u8 matchSet
u8 noCase
struct SumCtx

Definition at line 828 of file func.c.

Class Members
u8 approx
i64 cnt
i64 iSum
u8 overflow
double rSum
struct CountCtx

Definition at line 902 of file func.c.

Class Members
i64 n

Define Documentation

Definition at line 338 of file func.c.

#define sqliteNextChar (   X)    while( (0xc0&*++(X))==0x80 ){}

Definition at line 337 of file func.c.


Typedef Documentation

typedef struct CountCtx

Definition at line 901 of file func.c.

typedef struct SumCtx

Definition at line 827 of file func.c.


Function Documentation

static void absFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 119 of file func.c.

                                                                             {
  assert( argc==1 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_INTEGER: {
      i64 iVal = sqlite3_value_int64(argv[0]);
      if( iVal<0 ){
        if( (iVal<<1)==0 ){
          sqlite3_result_error(context, "integer overflow", -1);
          return;
        }
        iVal = -iVal;
      } 
      sqlite3_result_int64(context, iVal);
      break;
    }
    case SQLITE_NULL: {
      sqlite3_result_null(context);
      break;
    }
    default: {
      double rVal = sqlite3_value_double(argv[0]);
      if( rVal<0 ) rVal = -rVal;
      sqlite3_result_double(context, rVal);
      break;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void avgFinalize ( sqlite3_context context) [static]

Definition at line 884 of file func.c.

                                                 {
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){
    sqlite3_result_double(context, p->rSum/(double)p->cnt);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void changes ( sqlite3_context context,
int  arg,
sqlite3_value **  argv 
) [static]

Definition at line 292 of file func.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void countFinalize ( sqlite3_context context) [static]

Definition at line 916 of file func.c.

                                                   {
  CountCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  sqlite3_result_int64(context, p ? p->n : 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void countStep ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 909 of file func.c.

                                                                               {
  CountCtx *p;
  p = sqlite3_aggregate_context(context, sizeof(*p));
  if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){
    p->n++;
  }
}   

Here is the call graph for this function:

Here is the caller graph for this function:

static void ifnullFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 246 of file func.c.

 {
  int i;
  for(i=0; i<argc; i++){
    if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){
      sqlite3_result_value(context, argv[i]);
      break;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void last_insert_rowid ( sqlite3_context context,
int  arg,
sqlite3_value **  argv 
) [static]

Definition at line 279 of file func.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void lengthFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 88 of file func.c.

 {
  int len;

  assert( argc==1 );
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_BLOB:
    case SQLITE_INTEGER:
    case SQLITE_FLOAT: {
      sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
      break;
    }
    case SQLITE_TEXT: {
      const unsigned char *z = sqlite3_value_text(argv[0]);
      for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
      sqlite3_result_int(context, len);
      break;
    }
    default: {
      sqlite3_result_null(context);
      break;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void likeFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 494 of file func.c.

 {
  const unsigned char *zA = sqlite3_value_text(argv[0]);
  const unsigned char *zB = sqlite3_value_text(argv[1]);
  int escape = 0;
  if( argc==3 ){
    /* The escape character string must consist of a single UTF-8 character.
    ** Otherwise, return an error.
    */
    const unsigned char *zEsc = sqlite3_value_text(argv[2]);
    if( sqlite3utf8CharLen((char*)zEsc, -1)!=1 ){
      sqlite3_result_error(context, 
          "ESCAPE expression must be a single character", -1);
      return;
    }
    escape = sqlite3ReadUtf8(zEsc);
  }
  if( zA && zB ){
    struct compareInfo *pInfo = sqlite3_user_data(context);
#ifdef SQLITE_TEST
    sqlite3_like_count++;
#endif
    sqlite3_result_int(context, patternCompare(zA, zB, pInfo, escape));
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void lowerFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 227 of file func.c.

                                                                               {
  unsigned char *z;
  int i;
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
  z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
  if( z==0 ) return;
  strcpy((char*)z, (char*)sqlite3_value_text(argv[0]));
  for(i=0; z[i]; i++){
    z[i] = tolower(z[i]);
  }
  sqlite3_result_text(context, (char*)z, -1, SQLITE_TRANSIENT);
  sqliteFree(z);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void minMaxFinalize ( sqlite3_context context) [static]

Definition at line 954 of file func.c.

                                                    {
  sqlite3_value *pRes;
  pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0);
  if( pRes ){
    if( pRes->flags ){
      sqlite3_result_value(context, pRes);
    }
    sqlite3VdbeMemRelease(pRes);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void minmaxFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 39 of file func.c.

 {
  int i;
  int mask;    /* 0 for min() or 0xffffffff for max() */
  int iBest;
  CollSeq *pColl;

  if( argc==0 ) return;
  mask = sqlite3_user_data(context)==0 ? 0 : -1;
  pColl = sqlite3GetFuncCollSeq(context);
  assert( pColl );
  assert( mask==-1 || mask==0 );
  iBest = 0;
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  for(i=1; i<argc; i++){
    if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return;
    if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){
      iBest = i;
    }
  }
  sqlite3_result_value(context, argv[iBest]);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void minmaxStep ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 925 of file func.c.

                                                                                {
  Mem *pArg  = (Mem *)argv[0];
  Mem *pBest;

  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest));
  if( !pBest ) return;

  if( pBest->flags ){
    int max;
    int cmp;
    CollSeq *pColl = sqlite3GetFuncCollSeq(context);
    /* 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, pColl);
    if( (max && cmp<0) || (!max && cmp>0) ){
      sqlite3VdbeMemCopy(pBest, pArg);
    }
  }else{
    sqlite3VdbeMemCopy(pBest, pArg);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void nullifFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 528 of file func.c.

 {
  CollSeq *pColl = sqlite3GetFuncCollSeq(context);
  if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){
    sqlite3_result_value(context, argv[0]);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int patternCompare ( const u8 zPattern,
const u8 zString,
const struct compareInfo pInfo,
const int  esc 
) [static]

Definition at line 369 of file func.c.

 {
  register int c;
  int invert;
  int seen;
  int c2;
  u8 matchOne = pInfo->matchOne;
  u8 matchAll = pInfo->matchAll;
  u8 matchSet = pInfo->matchSet;
  u8 noCase = pInfo->noCase; 
  int prevEscape = 0;     /* True if the previous character was 'escape' */

  while( (c = *zPattern)!=0 ){
    if( !prevEscape && c==matchAll ){
      while( (c=zPattern[1]) == matchAll || c == matchOne ){
        if( c==matchOne ){
          if( *zString==0 ) return 0;
          sqliteNextChar(zString);
        }
        zPattern++;
      }
      if( c && esc && sqlite3ReadUtf8(&zPattern[1])==esc ){
        u8 const *zTemp = &zPattern[1];
        sqliteNextChar(zTemp);
        c = *zTemp;
      }
      if( c==0 ) return 1;
      if( c==matchSet ){
        assert( esc==0 );   /* This is GLOB, not LIKE */
        while( *zString && patternCompare(&zPattern[1],zString,pInfo,esc)==0 ){
          sqliteNextChar(zString);
        }
        return *zString!=0;
      }else{
        while( (c2 = *zString)!=0 ){
          if( noCase ){
            c2 = sqlite3UpperToLower[c2];
            c = sqlite3UpperToLower[c];
            while( c2 != 0 && c2 != c ){ c2 = sqlite3UpperToLower[*++zString]; }
          }else{
            while( c2 != 0 && c2 != c ){ c2 = *++zString; }
          }
          if( c2==0 ) return 0;
          if( patternCompare(&zPattern[1],zString,pInfo,esc) ) return 1;
          sqliteNextChar(zString);
        }
        return 0;
      }
    }else if( !prevEscape && c==matchOne ){
      if( *zString==0 ) return 0;
      sqliteNextChar(zString);
      zPattern++;
    }else if( c==matchSet ){
      int prior_c = 0;
      assert( esc==0 );    /* This only occurs for GLOB, not LIKE */
      seen = 0;
      invert = 0;
      c = sqliteCharVal(zString);
      if( c==0 ) return 0;
      c2 = *++zPattern;
      if( c2=='^' ){ invert = 1; c2 = *++zPattern; }
      if( c2==']' ){
        if( c==']' ) seen = 1;
        c2 = *++zPattern;
      }
      while( (c2 = sqliteCharVal(zPattern))!=0 && c2!=']' ){
        if( c2=='-' && zPattern[1]!=']' && zPattern[1]!=0 && prior_c>0 ){
          zPattern++;
          c2 = sqliteCharVal(zPattern);
          if( c>=prior_c && c<=c2 ) seen = 1;
          prior_c = 0;
        }else if( c==c2 ){
          seen = 1;
          prior_c = c2;
        }else{
          prior_c = c2;
        }
        sqliteNextChar(zPattern);
      }
      if( c2==0 || (seen ^ invert)==0 ) return 0;
      sqliteNextChar(zString);
      zPattern++;
    }else if( esc && !prevEscape && sqlite3ReadUtf8(zPattern)==esc){
      prevEscape = 1;
      sqliteNextChar(zPattern);
    }else{
      if( noCase ){
        if( sqlite3UpperToLower[c] != sqlite3UpperToLower[*zString] ) return 0;
      }else{
        if( c != *zString ) return 0;
      }
      zPattern++;
      zString++;
      prevEscape = 0;
    }
  }
  return *zString==0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void quoteFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 563 of file func.c.

                                                                               {
  if( argc<1 ) return;
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_NULL: {
      sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC);
      break;
    }
    case SQLITE_INTEGER:
    case SQLITE_FLOAT: {
      sqlite3_result_value(context, argv[0]);
      break;
    }
    case SQLITE_BLOB: {
      static const char hexdigits[] = { 
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 
      };
      char *zText = 0;
      int nBlob = sqlite3_value_bytes(argv[0]);
      char const *zBlob = sqlite3_value_blob(argv[0]);

      zText = (char *)sqliteMalloc((2*nBlob)+4); 
      if( !zText ){
        sqlite3_result_error(context, "out of memory", -1);
      }else{
        int i;
        for(i=0; i<nBlob; i++){
          zText[(i*2)+2] = hexdigits[(zBlob[i]>>4)&0x0F];
          zText[(i*2)+3] = hexdigits[(zBlob[i])&0x0F];
        }
        zText[(nBlob*2)+2] = '\'';
        zText[(nBlob*2)+3] = '\0';
        zText[0] = 'X';
        zText[1] = '\'';
        sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
        sqliteFree(zText);
      }
      break;
    }
    case SQLITE_TEXT: {
      int i,j,n;
      const unsigned char *zArg = sqlite3_value_text(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, SQLITE_TRANSIENT);
      sqliteFree(z);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void randomFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 263 of file func.c.

 {
  sqlite_int64 r;
  sqlite3Randomness(sizeof(r), &r);
  if( (r<<1)==0 ) r = 0;  /* Prevent 0x8000.... as the result so that we */
                          /* can always do abs() of the result */
  sqlite3_result_int64(context, r);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void roundFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 193 of file func.c.

                                                                               {
  int n = 0;
  double r;
  char zBuf[500];  /* larger than the %f representation of the largest double */
  assert( argc==1 || argc==2 );
  if( argc==2 ){
    if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return;
    n = sqlite3_value_int(argv[1]);
    if( n>30 ) n = 30;
    if( n<0 ) n = 0;
  }
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  r = sqlite3_value_double(argv[0]);
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%.*f",n,r);
  sqlite3AtoF(zBuf, &r);
  sqlite3_result_double(context, r);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void setLikeOptFlag ( sqlite3 db,
const char *  zName,
int  flagVal 
) [static]

Definition at line 1087 of file func.c.

                                                                       {
  FuncDef *pDef;
  pDef = sqlite3FindFunction(db, zName, strlen(zName), 2, SQLITE_UTF8, 0);
  if( pDef ){
    pDef->flags = flagVal;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static CollSeq* sqlite3GetFuncCollSeq ( sqlite3_context context) [static]

Definition at line 32 of file func.c.

                                                               {
  return context->pColl;
}

Here is the caller graph for this function:

int sqlite3IsLikeFunction ( sqlite3 db,
Expr pExpr,
int pIsNocase,
char *  aWc 
)

Definition at line 1123 of file func.c.

                                                                              {
  FuncDef *pDef;
  if( pExpr->op!=TK_FUNCTION ){
    return 0;
  }
  if( pExpr->pList->nExpr!=2 ){
    return 0;
  }
  pDef = sqlite3FindFunction(db, (char*)pExpr->token.z, pExpr->token.n, 2,
                             SQLITE_UTF8, 0);
  if( pDef==0 || (pDef->flags & SQLITE_FUNC_LIKE)==0 ){
    return 0;
  }

  /* The memcpy() statement assumes that the wildcard characters are
  ** the first three statements in the compareInfo structure.  The
  ** asserts() that follow verify that assumption
  */
  memcpy(aWc, pDef->pUserData, 3);
  assert( (char*)&likeInfoAlt == (char*)&likeInfoAlt.matchAll );
  assert( &((char*)&likeInfoAlt)[1] == (char*)&likeInfoAlt.matchOne );
  assert( &((char*)&likeInfoAlt)[2] == (char*)&likeInfoAlt.matchSet );
  *pIsNocase = (pDef->flags & SQLITE_FUNC_CASE)==0;
  return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 971 of file func.c.

                                                 {
  static const struct {
     char *zName;
     signed char nArg;
     u8 argType;           /* 0: none.  1: db  2: (-1) */
     u8 eTextRep;          /* 1: UTF-16.  0: UTF-8 */
     u8 needCollSeq;
     void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
  } aFuncs[] = {
    { "min",               -1, 0, SQLITE_UTF8,    1, minmaxFunc },
    { "min",                0, 0, SQLITE_UTF8,    1, 0          },
    { "max",               -1, 2, SQLITE_UTF8,    1, minmaxFunc },
    { "max",                0, 2, SQLITE_UTF8,    1, 0          },
    { "typeof",             1, 0, SQLITE_UTF8,    0, typeofFunc },
    { "length",             1, 0, SQLITE_UTF8,    0, lengthFunc },
    { "substr",             3, 0, SQLITE_UTF8,    0, substrFunc },
#ifndef SQLITE_OMIT_UTF16
    { "substr",             3, 0, SQLITE_UTF16LE, 0, sqlite3utf16Substr },
#endif
    { "abs",                1, 0, SQLITE_UTF8,    0, absFunc    },
    { "round",              1, 0, SQLITE_UTF8,    0, roundFunc  },
    { "round",              2, 0, SQLITE_UTF8,    0, roundFunc  },
    { "upper",              1, 0, SQLITE_UTF8,    0, upperFunc  },
    { "lower",              1, 0, SQLITE_UTF8,    0, lowerFunc  },
    { "coalesce",          -1, 0, SQLITE_UTF8,    0, ifnullFunc },
    { "coalesce",           0, 0, SQLITE_UTF8,    0, 0          },
    { "coalesce",           1, 0, SQLITE_UTF8,    0, 0          },
    { "ifnull",             2, 0, SQLITE_UTF8,    1, ifnullFunc },
    { "random",            -1, 0, SQLITE_UTF8,    0, randomFunc },
    { "nullif",             2, 0, SQLITE_UTF8,    1, nullifFunc },
    { "sqlite_version",     0, 0, SQLITE_UTF8,    0, versionFunc},
    { "quote",              1, 0, SQLITE_UTF8,    0, quoteFunc  },
    { "last_insert_rowid",  0, 1, SQLITE_UTF8,    0, last_insert_rowid },
    { "changes",            0, 1, SQLITE_UTF8,    0, changes    },
    { "total_changes",      0, 1, SQLITE_UTF8,    0, total_changes },
#ifdef SQLITE_SOUNDEX
    { "soundex",            1, 0, SQLITE_UTF8, 0, soundexFunc},
#endif
#ifdef SQLITE_TEST
    { "randstr",               2, 0, SQLITE_UTF8, 0, randStr    },
    { "test_destructor",       1, 1, SQLITE_UTF8, 0, test_destructor},
    { "test_destructor_count", 0, 0, SQLITE_UTF8, 0, test_destructor_count},
    { "test_auxdata",         -1, 0, SQLITE_UTF8, 0, test_auxdata},
    { "test_error",            1, 0, SQLITE_UTF8, 0, test_error},
#endif
  };
  static const struct {
    char *zName;
    signed char nArg;
    u8 argType;
    u8 needCollSeq;
    void (*xStep)(sqlite3_context*,int,sqlite3_value**);
    void (*xFinalize)(sqlite3_context*);
  } aAggs[] = {
    { "min",    1, 0, 1, minmaxStep,   minMaxFinalize },
    { "max",    1, 2, 1, minmaxStep,   minMaxFinalize },
    { "sum",    1, 0, 0, sumStep,      sumFinalize    },
    { "total",  1, 0, 0, sumStep,      totalFinalize    },
    { "avg",    1, 0, 0, sumStep,      avgFinalize    },
    { "count",  0, 0, 0, countStep,    countFinalize  },
    { "count",  1, 0, 0, countStep,    countFinalize  },
  };
  int i;

  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
    void *pArg = 0;
    switch( aFuncs[i].argType ){
      case 1: pArg = db; break;
      case 2: pArg = (void *)(-1); break;
    }
    sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
        aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0);
    if( aFuncs[i].needCollSeq ){
      FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName, 
          strlen(aFuncs[i].zName), aFuncs[i].nArg, aFuncs[i].eTextRep, 0);
      if( pFunc && aFuncs[i].needCollSeq ){
        pFunc->needCollSeq = 1;
      }
    }
  }
#ifndef SQLITE_OMIT_ALTERTABLE
  sqlite3AlterFunctions(db);
#endif
#ifndef SQLITE_OMIT_PARSER
  sqlite3AttachFunctions(db);
#endif
  for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
    void *pArg = 0;
    switch( aAggs[i].argType ){
      case 1: pArg = db; break;
      case 2: pArg = (void *)(-1); break;
    }
    sqlite3CreateFunc(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, 
        pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
    if( aAggs[i].needCollSeq ){
      FuncDef *pFunc = sqlite3FindFunction( db, aAggs[i].zName,
          strlen(aAggs[i].zName), aAggs[i].nArg, SQLITE_UTF8, 0);
      if( pFunc && aAggs[i].needCollSeq ){
        pFunc->needCollSeq = 1;
      }
    }
  }
  sqlite3RegisterDateTimeFunctions(db);
#ifdef SQLITE_SSE
  (void)sqlite3SseFunctions(db);
#endif
#ifdef SQLITE_CASE_SENSITIVE_LIKE
  sqlite3RegisterLikeFunctions(db, 1);
#else
  sqlite3RegisterLikeFunctions(db, 0);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void sqlite3RegisterLikeFunctions ( sqlite3 db,
int  caseSensitive 
)

Definition at line 1100 of file func.c.

                                                                 {
  struct compareInfo *pInfo;
  if( caseSensitive ){
    pInfo = (struct compareInfo*)&likeInfoAlt;
  }else{
    pInfo = (struct compareInfo*)&likeInfoNorm;
  }
  sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
  sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0);
  sqlite3CreateFunc(db, "glob", 2, SQLITE_UTF8, 
      (struct compareInfo*)&globInfo, likeFunc, 0,0);
  setLikeOptFlag(db, "glob", SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE);
  setLikeOptFlag(db, "like", 
      caseSensitive ? (SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE) : SQLITE_FUNC_LIKE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void substrFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 150 of file func.c.

 {
  const unsigned char *z;
  const unsigned char *z2;
  int i;
  int p1, p2, len;

  assert( argc==3 );
  z = sqlite3_value_text(argv[0]);
  if( z==0 ) return;
  p1 = sqlite3_value_int(argv[1]);
  p2 = sqlite3_value_int(argv[2]);
  for(len=0, z2=z; *z2; z2++){ if( (0xc0&*z2)!=0x80 ) len++; }
  if( p1<0 ){
    p1 += len;
    if( p1<0 ){
      p2 += p1;
      p1 = 0;
    }
  }else if( p1>0 ){
    p1--;
  }
  if( p1+p2>len ){
    p2 = len-p1;
  }
  for(i=0; i<p1 && z[i]; i++){
    if( (z[i]&0xc0)==0x80 ) p1++;
  }
  while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p1++; }
  for(; i<p1+p2 && z[i]; i++){
    if( (z[i]&0xc0)==0x80 ) p2++;
  }
  while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; }
  if( p2<0 ) p2 = 0;
  sqlite3_result_text(context, (char*)&z[p1], p2, SQLITE_TRANSIENT);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void sumFinalize ( sqlite3_context context) [static]

Definition at line 871 of file func.c.

                                                 {
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  if( p && p->cnt>0 ){
    if( p->overflow ){
      sqlite3_result_error(context,"integer overflow",-1);
    }else if( p->approx ){
      sqlite3_result_double(context, p->rSum);
    }else{
      sqlite3_result_int64(context, p->iSum);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void sumStep ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 846 of file func.c.

                                                                             {
  SumCtx *p;
  int type;
  assert( argc==1 );
  p = sqlite3_aggregate_context(context, sizeof(*p));
  type = sqlite3_value_numeric_type(argv[0]);
  if( p && type!=SQLITE_NULL ){
    p->cnt++;
    if( type==SQLITE_INTEGER ){
      i64 v = sqlite3_value_int64(argv[0]);
      p->rSum += v;
      if( (p->approx|p->overflow)==0 ){
        i64 iNewSum = p->iSum + v;
        int s1 = p->iSum >> (sizeof(i64)*8-1);
        int s2 = v       >> (sizeof(i64)*8-1);
        int s3 = iNewSum >> (sizeof(i64)*8-1);
        p->overflow = (s1&s2&~s3) | (~s1&~s2&s3);
        p->iSum = iNewSum;
      }
    }else{
      p->rSum += sqlite3_value_double(argv[0]);
      p->approx = 1;
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void total_changes ( sqlite3_context context,
int  arg,
sqlite3_value **  argv 
) [static]

Definition at line 305 of file func.c.

Here is the call graph for this function:

Here is the caller graph for this function:

static void totalFinalize ( sqlite3_context context) [static]

Definition at line 891 of file func.c.

                                                   {
  SumCtx *p;
  p = sqlite3_aggregate_context(context, 0);
  sqlite3_result_double(context, p ? p->rSum : 0.0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void typeofFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 68 of file func.c.

 {
  const char *z = 0;
  switch( sqlite3_value_type(argv[0]) ){
    case SQLITE_NULL:    z = "null";    break;
    case SQLITE_INTEGER: z = "integer"; break;
    case SQLITE_TEXT:    z = "text";    break;
    case SQLITE_FLOAT:   z = "real";    break;
    case SQLITE_BLOB:    z = "blob";    break;
  }
  sqlite3_result_text(context, z, -1, SQLITE_STATIC);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void upperFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 214 of file func.c.

                                                                               {
  unsigned char *z;
  int i;
  if( argc<1 || SQLITE_NULL==sqlite3_value_type(argv[0]) ) return;
  z = sqliteMalloc(sqlite3_value_bytes(argv[0])+1);
  if( z==0 ) return;
  strcpy((char*)z, (char*)sqlite3_value_text(argv[0]));
  for(i=0; z[i]; i++){
    z[i] = toupper(z[i]);
  }
  sqlite3_result_text(context, (char*)z, -1, SQLITE_TRANSIENT);
  sqliteFree(z);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void versionFunc ( sqlite3_context context,
int  argc,
sqlite3_value **  argv 
) [static]

Definition at line 543 of file func.c.

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

static struct compareInfo = { '*', '?', '[', 0 } [static]

Definition at line 324 of file func.c.