/ Check-in [92337d8f]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Enhance user function API to support association of meta-data with constant arguments and the specification of text encoding preference. The LIKE operator takes advantage of both. (CVS 1534)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 92337d8f79b9754cd61c73e7db2e792a1f482f50
User & Date: danielk1977 2004-06-06 09:44:04
Context
2004-06-06
12:41
Performance improvements for LIKE. It is still too slow though. (CVS 1535) check-in: 30b81507 user: danielk1977 tags: trunk
09:44
Enhance user function API to support association of meta-data with constant arguments and the specification of text encoding preference. The LIKE operator takes advantage of both. (CVS 1534) check-in: 92337d8f user: danielk1977 tags: trunk
00:42
Added sqlite3OsLock for win32. Assertion fault in attach.test. (CVS 1533) check-in: 9e6cd9ec user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/expr.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains routines used for analyzing expressions and
    13     13   ** for generating VDBE code that evaluates expressions in SQLite.
    14     14   **
    15         -** $Id: expr.c,v 1.134 2004/06/05 10:22:17 danielk1977 Exp $
           15  +** $Id: expr.c,v 1.135 2004/06/06 09:44:04 danielk1977 Exp $
    16     16   */
    17     17   #include "sqliteInt.h"
    18     18   #include <ctype.h>
    19     19   
    20     20   char const *sqlite3AffinityString(char affinity){
    21     21     switch( affinity ){
    22     22       case SQLITE_AFF_INTEGER: return "i";
................................................................................
   964    964         int no_such_func = 0;       /* True if no such function exists */
   965    965         int wrong_num_args = 0;     /* True if wrong number of arguments */
   966    966         int is_agg = 0;             /* True if is an aggregate function */
   967    967         int i;
   968    968         int nId;                    /* Number of characters in function name */
   969    969         const char *zId;            /* The function name. */
   970    970         FuncDef *pDef;
          971  +      int iPrefEnc = (pParse->db->enc==TEXT_Utf8)?0:1;
   971    972   
   972    973         getFunctionName(pExpr, &zId, &nId);
   973         -      pDef = sqlite3FindFunction(pParse->db, zId, nId, n, 0);
          974  +      pDef = sqlite3FindFunction(pParse->db, zId, nId, n, iPrefEnc, 0);
   974    975         if( pDef==0 ){
   975         -        pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, 0);
          976  +        pDef = sqlite3FindFunction(pParse->db, zId, nId, -1, iPrefEnc, 0);
   976    977           if( pDef==0 ){
   977    978             no_such_func = 1;
   978    979           }else{
   979    980             wrong_num_args = 1;
   980    981           }
   981    982         }else{
   982    983           is_agg = pDef->xFunc==0;
................................................................................
  1229   1230         ExprList *pList = pExpr->pList;
  1230   1231         int nExpr = pList ? pList->nExpr : 0;
  1231   1232         FuncDef *pDef;
  1232   1233         int nId;
  1233   1234         const char *zId;
  1234   1235         int p2 = 0;
  1235   1236         int i;
         1237  +      int iPrefEnc = (pParse->db->enc==TEXT_Utf8)?0:1;
  1236   1238         getFunctionName(pExpr, &zId, &nId);
  1237         -      pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, 0);
         1239  +      pDef = sqlite3FindFunction(pParse->db, zId, nId, nExpr, iPrefEnc, 0);
  1238   1240         assert( pDef!=0 );
  1239   1241         nExpr = sqlite3ExprCodeExprList(pParse, pList);
  1240   1242         for(i=0; i<nExpr && i<32; i++){
  1241         -        p2 &= (1<<i);
         1243  +        if( sqlite3ExprIsConstant(pList->a[i].pExpr) ){
         1244  +          p2 |= (1<<i);
         1245  +        }
  1242   1246         }
  1243   1247         sqlite3VdbeOp3(v, OP_Function, nExpr, p2, (char*)pDef, P3_FUNCDEF);
  1244   1248         break;
  1245   1249       }
  1246   1250       case TK_SELECT: {
  1247   1251         sqlite3VdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
  1248   1252         break;
................................................................................
  1641   1645         for(i=0; i<pParse->nAgg; i++){
  1642   1646           if( !aAgg[i].isAgg ) continue;
  1643   1647           if( sqlite3ExprCompare(aAgg[i].pExpr, pExpr) ){
  1644   1648             break;
  1645   1649           }
  1646   1650         }
  1647   1651         if( i>=pParse->nAgg ){
         1652  +        int iPrefEnc = (pParse->db->enc==TEXT_Utf8)?0:1;
  1648   1653           i = appendAggInfo(pParse);
  1649   1654           if( i<0 ) return 1;
  1650   1655           pParse->aAgg[i].isAgg = 1;
  1651   1656           pParse->aAgg[i].pExpr = pExpr;
  1652   1657           pParse->aAgg[i].pFunc = sqlite3FindFunction(pParse->db,
  1653   1658                pExpr->token.z, pExpr->token.n,
  1654         -             pExpr->pList ? pExpr->pList->nExpr : 0, 0);
         1659  +             pExpr->pList ? pExpr->pList->nExpr : 0, iPrefEnc, 0);
  1655   1660         }
  1656   1661         pExpr->iAgg = i;
  1657   1662         break;
  1658   1663       }
  1659   1664       default: {
  1660   1665         if( pExpr->pLeft ){
  1661   1666           nErr = sqlite3ExprAnalyzeAggregates(pParse, pExpr->pLeft);
................................................................................
  1673   1678         break;
  1674   1679       }
  1675   1680     }
  1676   1681     return nErr;
  1677   1682   }
  1678   1683   
  1679   1684   /*
  1680         -** Locate a user function given a name and a number of arguments.
  1681         -** Return a pointer to the FuncDef structure that defines that
  1682         -** function, or return NULL if the function does not exist.
         1685  +** Locate a user function given a name, a number of arguments and a flag
         1686  +** indicating whether the function prefers UTF-16 over UTF-8.  Return a
         1687  +** pointer to the FuncDef structure that defines that function, or return
         1688  +** NULL if the function does not exist.
  1683   1689   **
  1684   1690   ** If the createFlag argument is true, then a new (blank) FuncDef
  1685   1691   ** structure is created and liked into the "db" structure if a
  1686   1692   ** no matching function previously existed.  When createFlag is true
  1687   1693   ** and the nArg parameter is -1, then only a function that accepts
  1688   1694   ** any number of arguments will be returned.
  1689   1695   **
  1690   1696   ** If createFlag is false and nArg is -1, then the first valid
  1691   1697   ** function found is returned.  A function is valid if either xFunc
  1692   1698   ** or xStep is non-zero.
         1699  +**
         1700  +** If createFlag is false, then a function with the required name and
         1701  +** number of arguments may be returned even if the eTextRep flag does not
         1702  +** match that requested.
  1693   1703   */
  1694   1704   FuncDef *sqlite3FindFunction(
  1695   1705     sqlite *db,        /* An open database */
  1696   1706     const char *zName, /* Name of the function.  Not null-terminated */
  1697   1707     int nName,         /* Number of characters in the name */
  1698   1708     int nArg,          /* Number of arguments.  -1 means any number */
         1709  +  int eTextRep,      /* True to retrieve UTF-16 versions. */
  1699   1710     int createFlag     /* Create new entry if true and does not otherwise exist */
  1700   1711   ){
  1701         -  FuncDef *pFirst, *p, *pMaybe;
  1702         -  pFirst = p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
  1703         -  if( p && !createFlag && nArg<0 ){
  1704         -    while( p && p->xFunc==0 && p->xStep==0 ){ p = p->pNext; }
  1705         -    return p;
         1712  +  FuncDef *p;         /* Iterator variable */
         1713  +  FuncDef *pFirst;    /* First function with this name */
         1714  +  FuncDef *pBest = 0; /* Best match found so far */
         1715  +  int matchqual = 0;  
         1716  +
         1717  +  /* Normalize argument values to simplify comparisons below. */
         1718  +  if( eTextRep ) eTextRep = 1;
         1719  +  if( nArg<-1 ) nArg = -1;
         1720  +
         1721  +  pFirst = (FuncDef*)sqlite3HashFind(&db->aFunc, zName, nName);
         1722  +  for(p=pFirst; p; p=p->pNext){
         1723  +    if( 1 || p->xFunc || p->xStep ){
         1724  +      if( p->nArg==nArg && p->iPrefEnc==eTextRep ){
         1725  +        /* A perfect match. */
         1726  +        pBest = p;
         1727  +        matchqual = 4;
         1728  +        break;
         1729  +      }
         1730  +      if( p->nArg==nArg ){
         1731  +        /* Number of arguments matches, but not the text encoding */
         1732  +        pBest = p;
         1733  +        matchqual = 3;
         1734  +      }
         1735  +      else if( (p->nArg<0) || (nArg<0) ){
         1736  +        if( matchqual<2 && p->iPrefEnc==eTextRep ){
         1737  +          /* Matched a varargs function with correct text encoding */
         1738  +          pBest = p;
         1739  +          matchqual = 2;
         1740  +        }
         1741  +        if( matchqual<1 ){
         1742  +          /* Matched a varargs function with incorrect text encoding */
         1743  +          pBest = p;
         1744  +          matchqual = 1;
         1745  +        }
         1746  +      }
         1747  +    }
  1706   1748     }
  1707         -  pMaybe = 0;
  1708         -  while( p && p->nArg!=nArg ){
  1709         -    if( p->nArg<0 && !createFlag && (p->xFunc || p->xStep) ) pMaybe = p;
  1710         -    p = p->pNext;
         1749  +
         1750  +  if( createFlag && matchqual<4 && 
         1751  +      (pBest = sqliteMalloc(sizeof(*pBest)+nName+1)) ){
         1752  +    pBest->nArg = nArg;
         1753  +    pBest->pNext = pFirst;
         1754  +    pBest->zName = (char*)&pBest[1];
         1755  +    memcpy(pBest->zName, zName, nName);
         1756  +    pBest->zName[nName] = 0;
         1757  +    sqlite3HashInsert(&db->aFunc, pBest->zName, nName, (void*)pBest);
  1711   1758     }
  1712         -  if( p && !createFlag && p->xFunc==0 && p->xStep==0 ){
  1713         -    return 0;
  1714         -  }
  1715         -  if( p==0 && pMaybe ){
  1716         -    assert( createFlag==0 );
  1717         -    return pMaybe;
         1759  +
         1760  +  if( pBest && (pBest->xStep || pBest->xFunc || createFlag) ){
         1761  +    return pBest;
  1718   1762     }
  1719         -  if( p==0 && createFlag && (p = sqliteMalloc(sizeof(*p)+nName+1))!=0 ){
  1720         -    p->nArg = nArg;
  1721         -    p->pNext = pFirst;
  1722         -    p->zName = (char*)&p[1];
  1723         -    memcpy(p->zName, zName, nName);
  1724         -    p->zName[nName] = 0;
  1725         -    sqlite3HashInsert(&db->aFunc, p->zName, nName, (void*)p);
  1726         -  }
  1727         -  return p;
         1763  +  return 0;
  1728   1764   }
         1765  +

Changes to src/func.c.

    12     12   ** This file contains the C functions that implement various SQL
    13     13   ** functions of SQLite.  
    14     14   **
    15     15   ** There is only one exported symbol in this file - the function
    16     16   ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
    17     17   ** All other code has file scope.
    18     18   **
    19         -** $Id: func.c,v 1.62 2004/05/31 18:51:58 drh Exp $
           19  +** $Id: func.c,v 1.63 2004/06/06 09:44:04 danielk1977 Exp $
    20     20   */
    21     21   #include <ctype.h>
    22     22   #include <math.h>
    23     23   #include <stdlib.h>
    24     24   #include <assert.h>
    25     25   #include "sqliteInt.h"
    26     26   #include "vdbeInt.h"
................................................................................
   287    287     sqlite3_context *context, 
   288    288     int arg,
   289    289     sqlite3_value **argv
   290    290   ){
   291    291     sqlite *db = sqlite3_user_data(context);
   292    292     sqlite3_result_int(context, sqlite3_last_statement_changes(db));
   293    293   }
          294  +
          295  +/*
          296  +** A LIKE pattern compiles to an instance of the following structure. Refer
          297  +** to the comment for compileLike() function for details.
          298  +*/
          299  +struct LikePattern {
          300  +  int nState;
          301  +  struct LikeState {
          302  +    int val;           /* Unicode codepoint or -1 for any char i.e. '_' */
          303  +    int failstate;     /* State to jump to if next char is not val */
          304  +  } aState[0];
          305  +};
          306  +typedef struct LikePattern LikePattern;
          307  +
          308  +void deleteLike(void *pLike){
          309  +  sqliteFree(pLike);
          310  +}
          311  +
          312  +
          313  +/* #define TRACE_LIKE */
          314  +
          315  +#if defined(TRACE_LIKE) && !defined(NDEBUG)
          316  +char *dumpLike(LikePattern *pLike){
          317  +  int i;
          318  +  int k = 0;
          319  +  char *zBuf = (char *)sqliteMalloc(pLike->nState*40);
          320  +  
          321  +  k += sprintf(&zBuf[k], "%d states - ", pLike->nState);
          322  +  for(i=0; i<pLike->nState; i++){
          323  +    k += sprintf(&zBuf[k], " %d:(%d, %d)", i, pLike->aState[i].val,
          324  +        pLike->aState[i].failstate);
          325  +  }
          326  +  return zBuf;
          327  +}
          328  +#endif
          329  +
          330  +/*
          331  +** This function compiles an SQL 'LIKE' pattern into a state machine, 
          332  +** represented by a LikePattern structure.
          333  +**
          334  +** Each state of the state-machine has two attributes, 'val' and
          335  +** 'failstate'. The val attribute is either the value of a unicode 
          336  +** codepoint, or -1, indicating a '_' wildcard (match any single
          337  +** character). The failstate is either the number of another state
          338  +** or -1, indicating jump to 'no match'.
          339  +**
          340  +** To see if a string matches a pattern the pattern is
          341  +** compiled to a state machine that is executed according to the algorithm
          342  +** below. The string is assumed to be terminated by a 'NUL' character
          343  +** (unicode codepoint 0).
          344  +**
          345  +** 1   S = 0
          346  +** 2   DO 
          347  +** 3       C = <Next character from input string>
          348  +** 4       IF( C matches <State S val> )
          349  +** 5           S = S+1
          350  +** 6       ELSE IF( S != <State S failstate> )
          351  +** 7           S = <State S failstate>
          352  +** 8           <Rewind Input string 1 character>
          353  +** 9   WHILE( (C != NUL) AND (S != FAILED) )
          354  +** 10
          355  +** 11  IF( S == <number of states> )
          356  +** 12      RETURN MATCH
          357  +** 13  ELSE
          358  +** 14      RETURN NO-MATCH
          359  +**       
          360  +** In practice there is a small optimization to avoid the <Rewind>
          361  +** operation in line 8 of the description above.
          362  +**
          363  +** For example, the following pattern, 'X%ABabc%_Y' is compiled to
          364  +** the state machine below.
          365  +**
          366  +** State    Val          FailState
          367  +** -------------------------------
          368  +** 0        120 (x)      -1 (NO MATCH)
          369  +** 1        97  (a)      1
          370  +** 2        98  (b)      1
          371  +** 3        97  (a)      1
          372  +** 4        98  (b)      2
          373  +** 5        99  (c)      3
          374  +** 6        -1  (_)      6
          375  +** 7        121 (y)      7
          376  +** 8        0   (NUL)    7
          377  +**
          378  +** The algorithms implemented to compile and execute the state machine were
          379  +** first presented in "Fast pattern matching in strings", Knuth, Morris and
          380  +** Pratt, 1977.
          381  +**       
          382  +*/
          383  +LikePattern *compileLike(sqlite3_value *pPattern, u8 enc){
          384  +  LikePattern *pLike;
          385  +  struct LikeState *aState;
          386  +  int pc_state = -1;    /* State number of previous '%' wild card */
          387  +  int n = 0;
          388  +  int c;
          389  +
          390  +  int offset = 0;
          391  +  const char *zLike;
          392  + 
          393  +  if( enc==TEXT_Utf8 ){
          394  +    zLike = sqlite3_value_text(pPattern);
          395  +    n = sqlite3_value_bytes(pPattern) + 1;
          396  +  }else{
          397  +    zLike = sqlite3_value_text16(pPattern);
          398  +    n = sqlite3_value_bytes16(pPattern)/2 + 1;
          399  +  }
          400  +
          401  +  pLike = (LikePattern *)
          402  +      sqliteMalloc(sizeof(LikePattern)+n*sizeof(struct LikeState));
          403  +  aState = pLike->aState;
          404  +
          405  +  n = 0;
          406  +  do {
          407  +    c = sqlite3ReadUniChar(zLike, &offset, &enc, 1);
          408  +    if( c==95 ){        /* A '_' wildcard */
          409  +      aState[n].val = -1;
          410  +      n++;
          411  +    }else if( c==37 ){  /* A '%' wildcard */
          412  +      aState[n].failstate = n;
          413  +      pc_state = n;
          414  +    }else{              /* A regular character */
          415  +      aState[n].val = c;
          416  +
          417  +      assert( pc_state<=n );
          418  +      if( pc_state<0 ){
          419  +        aState[n].failstate = -1;
          420  +      }else if( pc_state==n ){
          421  +        aState[n].failstate = pc_state;
          422  +      }else{
          423  +        int k = pLike->aState[n-1].failstate;
          424  +        while( k>pc_state && aState[k+1].val!=-1 && aState[k+1].val!=c ){
          425  +          k = aState[k].failstate;
          426  +        }
          427  +        if( k!=pc_state && aState[k+1].val==c ){
          428  +          assert( k==pc_state );
          429  +          k++;
          430  +        }
          431  +        aState[n].failstate = k;
          432  +      }
          433  +      n++;
          434  +    }
          435  +  }while( c );
          436  +  pLike->nState = n;
          437  +#if defined(TRACE_LIKE) && !defined(NDEBUG)
          438  +  {
          439  +    char *zCompiled = dumpLike(pLike);
          440  +    printf("Pattern=\"%s\" Compiled=\"%s\"\n", zPattern, zCompiled);
          441  +    sqliteFree(zCompiled);
          442  +  }
          443  +#endif
          444  +  return pLike;
          445  +}
   294    446   
   295    447   /*
   296    448   ** Implementation of the like() SQL function.  This function implements
   297    449   ** the build-in LIKE operator.  The first argument to the function is the
   298         -** string and the second argument is the pattern.  So, the SQL statements:
          450  +** pattern and the second argument is the string.  So, the SQL statements:
   299    451   **
   300    452   **       A LIKE B
   301    453   **
   302         -** is implemented as like(A,B).
          454  +** is implemented as like(B,A).
          455  +**
          456  +** If the pointer retrieved by via a call to sqlite3_user_data() is
          457  +** not NULL, then this function uses UTF-16. Otherwise UTF-8.
   303    458   */
   304    459   static void likeFunc(
   305    460     sqlite3_context *context, 
   306    461     int argc, 
   307    462     sqlite3_value **argv
   308    463   ){
   309         -  const unsigned char *zA = sqlite3_value_text(argv[0]);
   310         -  const unsigned char *zB = sqlite3_value_text(argv[1]);
   311         -  if( zA && zB ){
   312         -    sqlite3_result_int(context, sqlite3LikeCompare(zA, zB));
          464  +  int s;
          465  +  int c;
          466  +  int nc;
          467  +  u8 enc;
          468  +  int offset = 0;
          469  +  const unsigned char *zString;
          470  +  LikePattern *pLike = sqlite3_get_auxdata(context, 0); 
          471  +
          472  +  /* If either argument is NULL, the result is NULL */
          473  +  if( sqlite3_value_type(argv[1])==SQLITE_NULL || 
          474  +      sqlite3_value_type(argv[0])==SQLITE_NULL ){
          475  +    return;
          476  +  }
          477  +
          478  +  /* If the user-data pointer is NULL, use UTF-8. Otherwise UTF-16. */
          479  +  if( sqlite3_user_data(context) ){
          480  +    enc = TEXT_Utf16;
          481  +    zString = (const unsigned char *)sqlite3_value_text16(argv[1]);
          482  +  }else{
          483  +    enc = TEXT_Utf8;
          484  +    zString = sqlite3_value_text(argv[1]);
          485  +  }
          486  +
          487  +  /* If the LIKE pattern has not been compiled, compile it now. */
          488  +  if( !pLike ){
          489  +    pLike = compileLike(argv[0], enc);
          490  +    if( !pLike ){
          491  +      sqlite3_result_error(context, "out of memory", -1);
          492  +      return;
          493  +    }
          494  +    sqlite3_set_auxdata(context, 0, pLike, deleteLike);
          495  +  }
          496  +
          497  +  s = 0;
          498  +  nc = 1;
          499  +  do {
          500  +    int val = pLike->aState[s].val;
          501  +    if( nc ) c = sqlite3ReadUniChar(zString, &offset, &enc, 1);
          502  +
          503  +#if defined(TRACE_LIKE) && !defined(NDEBUG)
          504  +    printf("State=%d:(%d, %d) Input=%d\n", 
          505  +        s, pLike->aState[s].val, 
          506  +        pLike->aState[s].failstate, c);
          507  +#endif
          508  +
          509  +    if( val==-1 || val==c ){
          510  +      s++;
          511  +      nc = 1;
          512  +    }else{
          513  +      if( pLike->aState[s].failstate==s ){
          514  +        nc = 1;
          515  +      }else{
          516  +        nc = 0;
          517  +        s = pLike->aState[s].failstate;
          518  +      }
          519  +    }
          520  +  }while( c && s>=0 );
          521  +
          522  +  if( s==pLike->nState ){
          523  +    sqlite3_result_int(context, 1);
          524  +  }else{
          525  +    sqlite3_result_int(context, 0);
   313    526     }
   314    527   }
   315    528   
   316    529   /*
   317    530   ** Implementation of the glob() SQL function.  This function implements
   318    531   ** the build-in GLOB operator.  The first argument to the function is the
   319    532   ** string and the second argument is the pattern.  So, the SQL statements:
................................................................................
   638    851   ** external linkage.
   639    852   */
   640    853   void sqlite3RegisterBuiltinFunctions(sqlite *db){
   641    854     static struct {
   642    855        char *zName;
   643    856        signed char nArg;
   644    857        u8 argType;               /* 0: none.  1: db  2: (-1) */
          858  +     u8 eTextRep;              /* 1: UTF-16.  0: UTF-8 */
   645    859        void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
   646    860     } aFuncs[] = {
   647         -    { "min",                        -1, 0, minmaxFunc },
   648         -    { "min",                         0, 0, 0          },
   649         -    { "max",                        -1, 2, minmaxFunc },
   650         -    { "max",                         0, 2, 0          },
   651         -    { "typeof",                      1, 0, typeofFunc },
   652         -    { "classof",                     1, 0, typeofFunc }, /* FIX ME: hack */
   653         -    { "length",                      1, 0, lengthFunc },
   654         -    { "substr",                      3, 0, substrFunc },
   655         -    { "abs",                         1, 0, absFunc    },
   656         -    { "round",                       1, 0, roundFunc  },
   657         -    { "round",                       2, 0, roundFunc  },
   658         -    { "upper",                       1, 0, upperFunc  },
   659         -    { "lower",                       1, 0, lowerFunc  },
   660         -    { "coalesce",                   -1, 0, ifnullFunc },
   661         -    { "coalesce",                    0, 0, 0          },
   662         -    { "coalesce",                    1, 0, 0          },
   663         -    { "ifnull",                      2, 0, ifnullFunc },
   664         -    { "random",                     -1, 0, randomFunc },
   665         -    { "like",                        2, 0, likeFunc   },
   666         -    { "glob",                        2, 0, globFunc   },
   667         -    { "nullif",                      2, 0, nullifFunc },
   668         -    { "sqlite_version",              0, 0, versionFunc},
   669         -    { "quote",                       1, 0, quoteFunc  },
   670         -    { "last_insert_rowid",           0, 1, last_insert_rowid },
   671         -    { "change_count",                0, 1, change_count      },
   672         -    { "last_statement_change_count", 0, 1, last_statement_change_count },
          861  +    { "min",                        -1, 0, 0, minmaxFunc },
          862  +    { "min",                         0, 0, 0, 0          },
          863  +    { "max",                        -1, 2, 0, minmaxFunc },
          864  +    { "max",                         0, 2, 0, 0          },
          865  +    { "typeof",                      1, 0, 0, typeofFunc },
          866  +    { "length",                      1, 0, 0, lengthFunc },
          867  +    { "substr",                      3, 0, 0, substrFunc },
          868  +    { "abs",                         1, 0, 0, absFunc    },
          869  +    { "round",                       1, 0, 0, roundFunc  },
          870  +    { "round",                       2, 0, 0, roundFunc  },
          871  +    { "upper",                       1, 0, 0, upperFunc  },
          872  +    { "lower",                       1, 0, 0, lowerFunc  },
          873  +    { "coalesce",                   -1, 0, 0, ifnullFunc },
          874  +    { "coalesce",                    0, 0, 0, 0          },
          875  +    { "coalesce",                    1, 0, 0, 0          },
          876  +    { "ifnull",                      2, 0, 0, ifnullFunc },
          877  +    { "random",                     -1, 0, 0, randomFunc },
          878  +    { "like",                        2, 0, 0, likeFunc   }, /* UTF-8 */
          879  +    { "like",                        2, 2, 1, likeFunc   }, /* UTF-16 */
          880  +    { "glob",                        2, 0, 0, globFunc   },
          881  +    { "nullif",                      2, 0, 0, nullifFunc },
          882  +    { "sqlite_version",              0, 0, 0, versionFunc},
          883  +    { "quote",                       1, 0, 0, quoteFunc  },
          884  +    { "last_insert_rowid",           0, 1, 0, last_insert_rowid },
          885  +    { "change_count",                0, 1, 0, change_count      },
          886  +    { "last_statement_change_count", 0, 1, 0, last_statement_change_count },
   673    887   #ifdef SQLITE_SOUNDEX
   674         -    { "soundex",                     1, 0, soundexFunc},
          888  +    { "soundex",                     1, 0, 0, soundexFunc},
   675    889   #endif
   676    890   #ifdef SQLITE_TEST
   677         -    { "randstr",                     2, 0, randStr    },
          891  +    { "randstr",                     2, 0, 0, randStr    },
   678    892   #endif
   679    893     };
   680    894     static struct {
   681    895       char *zName;
   682    896       signed char nArg;
   683    897       u8 argType;
   684    898       void (*xStep)(sqlite3_context*,int,sqlite3_value**);

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.204 2004/06/04 06:22:01 danielk1977 Exp $
           17  +** $Id: main.c,v 1.205 2004/06/06 09:44:04 danielk1977 Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** A pointer to this structure is used to communicate information
................................................................................
   652    652         (!xFunc && (xFinal && !xStep)) ||
   653    653         (!xFunc && (!xFinal && xStep)) ||
   654    654         (nArg<-1 || nArg>127) ||
   655    655         (255<(nName = strlen(zFunctionName))) ){
   656    656       return SQLITE_ERROR;
   657    657     }
   658    658   
   659         -  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, 1);
          659  +  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, eTextRep, 1);
   660    660     if( p==0 ) return 1;
   661    661     p->xFunc = xFunc;
   662    662     p->xStep = xStep;
   663    663     p->xFinalize = xFinal;
   664    664     p->pUserData = pUserData;
   665    665     return SQLITE_OK;
   666    666   }

Changes to src/sqlite.h.in.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This header file defines the interface that the SQLite library
    13     13   ** presents to client programs.
    14     14   **
    15         -** @(#) $Id: sqlite.h.in,v 1.92 2004/06/05 10:22:18 danielk1977 Exp $
           15  +** @(#) $Id: sqlite.h.in,v 1.93 2004/06/06 09:44:04 danielk1977 Exp $
    16     16   */
    17     17   #ifndef _SQLITE_H_
    18     18   #define _SQLITE_H_
    19     19   #include <stdarg.h>     /* Needed for the definition of va_list */
    20     20   
    21     21   /*
    22     22   ** Make sure we can call this stuff from C++.
................................................................................
   830    830   ** database handle internally, then user functions or aggregates must 
   831    831   ** be added individually to each database handle with which they will be
   832    832   ** used.
   833    833   **
   834    834   ** The third parameter is the number of arguments that the function or
   835    835   ** aggregate takes. If this parameter is negative, then the function or
   836    836   ** aggregate may take any number of arguments.
          837  +**
          838  +** If the fourth parameter is non-zero, this indicates that the function is
          839  +** more likely to handle text in UTF-16 encoding than UTF-8. This does not
          840  +** change the behaviour of the programming interface. However, if two
          841  +** versions of the same function are registered, one with eTextRep non-zero
          842  +** and the other zero, SQLite invokes the version likely to minimize
          843  +** conversions between unicode encodings.
   837    844   **
   838    845   ** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are
   839    846   ** pointers to user implemented C functions that implement the user
   840    847   ** function or aggregate. A scalar function requires an implementation of
   841    848   ** the xFunc callback only, NULL pointers should be passed as the xStep
   842    849   ** and xFinal parameters. An aggregate function requires an implementation
   843    850   ** of xStep and xFinal, but NULL should be passed for xFunc. To delete an

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.268 2004/06/04 06:22:02 danielk1977 Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.269 2004/06/06 09:44:05 danielk1977 Exp $
    15     15   */
    16     16   #include "config.h"
    17     17   #include "sqlite3.h"
    18     18   #include "hash.h"
    19     19   #include "parse.h"
    20     20   #include <stdio.h>
    21     21   #include <stdlib.h>
................................................................................
  1261   1261   Table *sqlite3FindTable(sqlite*,const char*, const char*);
  1262   1262   Table *sqlite3LocateTable(Parse*,const char*, const char*);
  1263   1263   Index *sqlite3FindIndex(sqlite*,const char*, const char*);
  1264   1264   void sqlite3UnlinkAndDeleteIndex(sqlite*,Index*);
  1265   1265   void sqlite3Vacuum(Parse*, Token*);
  1266   1266   int sqlite3RunVacuum(char**, sqlite*);
  1267   1267   int sqlite3GlobCompare(const unsigned char*,const unsigned char*);
  1268         -int sqlite3LikeCompare(const unsigned char*,const unsigned char*);
  1269   1268   char *sqlite3TableNameFromToken(Token*);
  1270   1269   int sqlite3ExprCheck(Parse*, Expr*, int, int*);
  1271   1270   int sqlite3ExprType(Expr*);
  1272   1271   int sqlite3ExprCompare(Expr*, Expr*);
  1273   1272   int sqliteFuncId(Token*);
  1274   1273   int sqlite3ExprResolveIds(Parse*, SrcList*, ExprList*, Expr*);
  1275   1274   int sqlite3ExprAnalyzeAggregates(Parse*, Expr*);
................................................................................
  1293   1292   void sqlite3EndWriteOperation(Parse*);
  1294   1293   Expr *sqlite3ExprDup(Expr*);
  1295   1294   void sqlite3TokenCopy(Token*, Token*);
  1296   1295   ExprList *sqlite3ExprListDup(ExprList*);
  1297   1296   SrcList *sqlite3SrcListDup(SrcList*);
  1298   1297   IdList *sqlite3IdListDup(IdList*);
  1299   1298   Select *sqlite3SelectDup(Select*);
  1300         -FuncDef *sqlite3FindFunction(sqlite*,const char*,int,int,int);
         1299  +FuncDef *sqlite3FindFunction(sqlite*,const char*,int,int,int,int);
  1301   1300   void sqlite3RegisterBuiltinFunctions(sqlite*);
  1302   1301   void sqlite3RegisterDateTimeFunctions(sqlite*);
  1303   1302   int sqlite3SafetyOn(sqlite*);
  1304   1303   int sqlite3SafetyOff(sqlite*);
  1305   1304   int sqlite3SafetyCheck(sqlite*);
  1306   1305   void sqlite3ChangeCookie(sqlite*, Vdbe*, int);
  1307   1306   void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*,
................................................................................
  1369   1368   int sqlite3atoi64(const char*, i64*);
  1370   1369   void sqlite3Error(sqlite *, int, const char*,...);
  1371   1370   int sqlite3utfTranslate(const void *, int , u8 , void **, int *, u8);
  1372   1371   u8 sqlite3UtfReadBom(const void *zData, int nData);
  1373   1372   void *sqlite3HexToBlob(const char *z);
  1374   1373   int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
  1375   1374   const char *sqlite3ErrStr(int);
         1375  +int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold);

Changes to src/utf.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains routines used to translate between UTF-8, 
    13     13   ** UTF-16, UTF-16BE, and UTF-16LE.
    14     14   **
    15         -** $Id: utf.c,v 1.16 2004/06/02 00:29:24 danielk1977 Exp $
           15  +** $Id: utf.c,v 1.17 2004/06/06 09:44:05 danielk1977 Exp $
    16     16   **
    17     17   ** Notes on UTF-8:
    18     18   **
    19     19   **   Byte-0    Byte-1    Byte-2    Byte-3    Value
    20     20   **  0xxxxxxx                                 00000000 00000000 0xxxxxxx
    21     21   **  110yyyyy  10xxxxxx                       00000000 00000yyy yyxxxxxx
    22     22   **  1110zzzz  10yyyyyy  10xxxxxx             00000000 zzzzyyyy yyxxxxxx
................................................................................
    69     69   
    70     70   /*
    71     71   ** READ_16 interprets the first two bytes of the unsigned char array pZ 
    72     72   ** as a 16-bit unsigned int. If big_endian is non-zero the intepretation
    73     73   ** is big-endian, otherwise little-endian.
    74     74   */
    75     75   #define READ_16(pZ,big_endian) (big_endian?BE16(pZ):LE16(pZ))
           76  +
           77  +/*
           78  +** The following macro, LOWERCASE(x), takes an integer representing a
           79  +** unicode code point. The value returned is the same code point folded to
           80  +** lower case, if applicable. SQLite currently understands the upper/lower
           81  +** case relationship between the 26 characters used in the English
           82  +** language only.
           83  +**
           84  +** This means that characters with umlauts etc. will not be folded
           85  +** correctly (unless they are encoded as composite characters, which would
           86  +** doubtless cause much trouble).
           87  +*/
           88  +#define LOWERCASE(x) (x<91?(int)(UpperToLower[x]):x);
           89  +static unsigned char UpperToLower[91] = {
           90  +      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
           91  +     18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
           92  +     36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
           93  +     54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
           94  +    104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
           95  +    122,
           96  +};
           97  +
           98  +/*
           99  +** The first parameter, zStr, points at a unicode string. This routine
          100  +** reads a single character from the string and returns the codepoint value
          101  +** of the character read.
          102  +**
          103  +** The value of *pEnc is the string encoding. If *pEnc is TEXT_Utf16le or
          104  +** TEXT_Utf16be, and the first character read is a byte-order-mark, then
          105  +** the value of *pEnc is modified if necessary. In this case the next
          106  +** character is read and it's code-point value returned.
          107  +**
          108  +** The value of *pOffset is the byte-offset in zStr from which to begin
          109  +** reading. It is incremented by the number of bytes read by this function.
          110  +**
          111  +** If the fourth parameter, fold, is non-zero, then codepoint values are
          112  +** folded to lower-case before being returned. See comments for macro
          113  +** LOWERCASE(x) for details.
          114  +*/
          115  +int sqlite3ReadUniChar(const char *zStr, int *pOffset, u8 *pEnc, int fold){
          116  +  int ret = 0;
          117  +
          118  +  switch( *pEnc ){
          119  +    case TEXT_Utf8: {
          120  +      struct Utf8TblRow {
          121  +        u8 b1_mask;
          122  +        u8 b1_masked_val;
          123  +        u8 b1_value_mask;
          124  +        int trailing_bytes;
          125  +      };
          126  +      static const struct Utf8TblRow utf8tbl[] = {
          127  +        { 0x80, 0x00, 0x7F, 0 },
          128  +        { 0xE0, 0xC0, 0x1F, 1 },
          129  +        { 0xF0, 0xE0, 0x0F, 2 },
          130  +        { 0xF8, 0xF0, 0x0E, 3 },
          131  +        { 0, 0, 0, 0}
          132  +      };
          133  +    
          134  +      u8 b1;   /* First byte of the potentially multi-byte utf-8 character */
          135  +      int ii;
          136  +      struct Utf8TblRow const *pRow;
          137  +    
          138  +      pRow = &(utf8tbl[0]);
          139  +    
          140  +      b1 = zStr[(*pOffset)++];
          141  +      while( pRow->b1_mask && (b1&pRow->b1_mask)!=pRow->b1_masked_val ){
          142  +        pRow++;
          143  +      }
          144  +      if( !pRow->b1_mask ){
          145  +        return (int)0xFFFD;
          146  +      }
          147  +      
          148  +      ret = (u32)(b1&pRow->b1_value_mask);
          149  +      for( ii=0; ii<pRow->trailing_bytes; ii++ ){
          150  +        u8 b = zStr[(*pOffset)++];
          151  +        if( (b&0xC0)!=0x80 ){
          152  +          return (int)0xFFFD;
          153  +        }
          154  +        ret = (ret<<6) + (u32)(b&0x3F);
          155  +      }
          156  +      
          157  +      break;
          158  +    }
          159  +
          160  +    case TEXT_Utf16le:
          161  +    case TEXT_Utf16be: {
          162  +      u32 code_point;   /* the first code-point in the character */
          163  +      u32 code_point2;  /* the second code-point in the character, if any */
          164  +    
          165  +      code_point = READ_16(&zStr[*pOffset], (*pEnc==TEXT_Utf16be));
          166  +      *pOffset += 2;
          167  +    
          168  +      /* If this is a non-surrogate code-point, just cast it to an int and
          169  +      ** this is the code-point value.
          170  +      */
          171  +      if( code_point<0xD800 || code_point>0xE000 ){
          172  +        ret = code_point;
          173  +        break;
          174  +      }
          175  +
          176  +      /* If this is a trailing surrogate code-point, then the string is
          177  +      ** malformed; return the replacement character.
          178  +      */
          179  +      if( code_point>0xDBFF ){
          180  +        return (int)0xFFFD;
          181  +      }
          182  +    
          183  +      /* The code-point just read is a leading surrogate code-point. If their
          184  +      ** is not enough data left or the next code-point is not a trailing
          185  +      ** surrogate, return the replacement character.
          186  +      */
          187  +      code_point2 = READ_16(&zStr[*pOffset], (*pEnc==TEXT_Utf16be));
          188  +      *pOffset += 2;
          189  +      if( code_point2<0xDC00 || code_point>0xDFFF ){
          190  +        return (int)0xFFFD;
          191  +      }
          192  +   
          193  +      ret = ( 
          194  +          (((code_point&0x03C0)+0x0040)<<16) +   /* uuuuu */
          195  +          ((code_point&0x003F)<<10) +            /* xxxxxx */
          196  +          (code_point2&0x03FF)                   /* yy yyyyyyyy */
          197  +      );
          198  +    }
          199  +    default:
          200  +      assert(0);
          201  +  }
          202  +
          203  +  if( fold ){
          204  +    return LOWERCASE(ret);
          205  +  }
          206  +  return ret;
          207  +}
    76    208   
    77    209   /*
    78    210   ** Read the BOM from the start of *pStr, if one is present. Return zero
    79    211   ** for little-endian, non-zero for big-endian. If no BOM is present, return
    80    212   ** the value of the parameter "big_endian".
    81    213   **
    82    214   ** Return values:
................................................................................
   129    261   
   130    262   /*
   131    263   ** Read a single unicode character from the UTF-8 encoded string *pStr. The
   132    264   ** value returned is a unicode scalar value. In the case of malformed
   133    265   ** strings, the unicode replacement character U+FFFD may be returned.
   134    266   */
   135    267   static u32 readUtf8(UtfString *pStr){
   136         -  struct Utf8TblRow {
   137         -    u8 b1_mask;
   138         -    u8 b1_masked_val;
   139         -    u8 b1_value_mask;
   140         -    int trailing_bytes;
   141         -  };
   142         -  static const struct Utf8TblRow utf8tbl[] = {
   143         -    { 0x80, 0x00, 0x7F, 0 },
   144         -    { 0xE0, 0xC0, 0x1F, 1 },
   145         -    { 0xF0, 0xE0, 0x0F, 2 },
   146         -    { 0xF8, 0xF0, 0x0E, 3 },
   147         -    { 0, 0, 0, 0}
   148         -  };
   149         -
   150         -  u8 b1;       /* First byte of the potentially multi-byte utf-8 character */
   151         -  u32 ret = 0; /* Return value */
   152         -  int ii;
   153         -  struct Utf8TblRow const *pRow;
   154         -
   155         -  pRow = &(utf8tbl[0]);
   156         -
   157         -  b1 = pStr->pZ[pStr->c];
   158         -  pStr->c++;
   159         -  while( pRow->b1_mask && (b1&pRow->b1_mask)!=pRow->b1_masked_val ){
   160         -    pRow++;
   161         -  }
   162         -  if( !pRow->b1_mask ){
   163         -    return 0xFFFD;
   164         -  }
   165         -  
   166         -  ret = (u32)(b1&pRow->b1_value_mask);
   167         -  for( ii=0; ii<pRow->trailing_bytes; ii++ ){
   168         -    u8 b = pStr->pZ[pStr->c+ii];
   169         -    if( (b&0xC0)!=0x80 ){
   170         -      return 0xFFFD;
   171         -    }
   172         -    ret = (ret<<6) + (u32)(b&0x3F);
   173         -  }
   174         -  
   175         -  pStr->c += pRow->trailing_bytes;
   176         -  return ret;
          268  +  u8 enc = TEXT_Utf8;
          269  +  return sqlite3ReadUniChar(pStr->pZ, &pStr->c, &enc, 0);
   177    270   }
   178    271   
   179    272   /*
   180    273   ** Write the unicode character 'code' to the string pStr using UTF-8
   181    274   ** encoding. SQLITE_NOMEM may be returned if sqlite3Malloc() fails.
   182    275   */
   183    276   static int writeUtf8(UtfString *pStr, u32 code){

Changes to src/util.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Utility functions used throughout sqlite.
    13     13   **
    14     14   ** This file contains functions for allocating memory, comparing
    15     15   ** strings, and stuff like that.
    16     16   **
    17         -** $Id: util.c,v 1.96 2004/06/02 00:41:10 drh Exp $
           17  +** $Id: util.c,v 1.97 2004/06/06 09:44:05 danielk1977 Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include <stdarg.h>
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** If malloc() ever fails, this global variable gets set to 1.
................................................................................
  1048   1048           if( c != *zString ) return 0;
  1049   1049           zPattern++;
  1050   1050           zString++;
  1051   1051           break;
  1052   1052         }
  1053   1053       }
  1054   1054     }
  1055         -  return *zString==0;
  1056         -}
  1057         -
  1058         -/*
  1059         -** Compare two UTF-8 strings for equality using the "LIKE" operator of
  1060         -** SQL.  The '%' character matches any sequence of 0 or more
  1061         -** characters and '_' matches any single character.  Case is
  1062         -** not significant.
  1063         -**
  1064         -** This routine is just an adaptation of the sqlite3GlobCompare()
  1065         -** routine above.
  1066         -*/
  1067         -int 
  1068         -sqlite3LikeCompare(const unsigned char *zPattern, const unsigned char *zString){
  1069         -  register int c;
  1070         -  int c2;
  1071         -
  1072         -  while( (c = UpperToLower[*zPattern])!=0 ){
  1073         -    switch( c ){
  1074         -      case '%': {
  1075         -        while( (c=zPattern[1]) == '%' || c == '_' ){
  1076         -          if( c=='_' ){
  1077         -            if( *zString==0 ) return 0;
  1078         -            sqliteNextChar(zString);
  1079         -          }
  1080         -          zPattern++;
  1081         -        }
  1082         -        if( c==0 ) return 1;
  1083         -        c = UpperToLower[c];
  1084         -        while( (c2=UpperToLower[*zString])!=0 ){
  1085         -          while( c2 != 0 && c2 != c ){ c2 = UpperToLower[*++zString]; }
  1086         -          if( c2==0 ) return 0;
  1087         -          if( sqlite3LikeCompare(&zPattern[1],zString) ) return 1;
  1088         -          sqliteNextChar(zString);
  1089         -        }
  1090         -        return 0;
  1091         -      }
  1092         -      case '_': {
  1093         -        if( *zString==0 ) return 0;
  1094         -        sqliteNextChar(zString);
  1095         -        zPattern++;
  1096         -        break;
  1097         -      }
  1098         -      default: {
  1099         -        if( c != UpperToLower[*zString] ) return 0;
  1100         -        zPattern++;
  1101         -        zString++;
  1102         -        break;
  1103         -      }
  1104         -    }
  1105         -  }
  1106   1055     return *zString==0;
  1107   1056   }
  1108   1057   
  1109   1058   /*
  1110   1059   ** Change the sqlite.magic from SQLITE_MAGIC_OPEN to SQLITE_MAGIC_BUSY.
  1111   1060   ** Return an error (non-zero) if the magic was not SQLITE_MAGIC_OPEN
  1112   1061   ** when this routine is called.

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.358 2004/06/05 10:22:18 danielk1977 Exp $
           46  +** $Id: vdbe.c,v 1.359 2004/06/06 09:44:05 danielk1977 Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
  1269   1269     popStack(&pTos, n);
  1270   1270   
  1271   1271     /* If any auxilary data functions have been called by this user function,
  1272   1272     ** immediately call the destructor for any non-static values.
  1273   1273     */
  1274   1274     if( ctx.pVdbeFunc ){
  1275   1275       int mask = pOp->p2;
  1276         -    for(i=0; i<n; i++){
         1276  +    for(i=0; i<ctx.pVdbeFunc->nAux; i++){
  1277   1277         struct AuxData *pAux = &ctx.pVdbeFunc->apAux[i];
  1278   1278         if( (i>31 || !(mask&(1<<i))) && pAux->pAux ){
  1279   1279           pAux->xDelete(pAux->pAux);
  1280   1280           pAux->pAux = 0;
  1281   1281         }
  1282   1282       }
  1283   1283       pOp->p3 = (char *)ctx.pVdbeFunc;

Changes to src/vdbeapi.c.

   244    244     if( iArg<0 ) return;
   245    245   
   246    246     if( !pCtx->pVdbeFunc || pCtx->pVdbeFunc->nAux<=iArg ){
   247    247       int nMalloc = sizeof(VdbeFunc)+sizeof(struct AuxData)*(iArg+1);
   248    248       pCtx->pVdbeFunc = sqliteRealloc(pCtx->pVdbeFunc, nMalloc);
   249    249       if( !pCtx->pVdbeFunc ) return;
   250    250       pCtx->pVdbeFunc->nAux = iArg+1;
          251  +    pCtx->pVdbeFunc->pFunc = pCtx->pFunc;
   251    252     }
   252    253   
   253    254     pAuxData = &pCtx->pVdbeFunc->apAux[iArg];
   254    255     if( pAuxData->pAux && pAuxData->xDelete ){
   255    256       pAuxData->xDelete(pAuxData->pAux);
   256    257     }
   257    258     pAuxData->pAux = pAux;

Changes to src/vdbeaux.c.

  1231   1231     }
  1232   1232     for(i=0; i<p->nOp; i++){
  1233   1233       Op *pOp = &p->aOp[i];
  1234   1234       if( pOp->p3type==P3_DYNAMIC || pOp->p3type==P3_KEYINFO ){
  1235   1235         sqliteFree(pOp->p3);
  1236   1236       }
  1237   1237       if( pOp->p3type==P3_VDBEFUNC ){
         1238  +      int j;
  1238   1239         VdbeFunc *pVdbeFunc = (VdbeFunc *)pOp->p3;
  1239         -      for(i=0; i<pVdbeFunc->nAux; i++){
  1240         -        struct AuxData *pAuxData = &pVdbeFunc->apAux[i].pAux;
         1240  +      for(j=0; j<pVdbeFunc->nAux; j++){
         1241  +        struct AuxData *pAuxData = &pVdbeFunc->apAux[j].pAux;
  1241   1242           if( pAuxData->pAux && pAuxData->xDelete ){
  1242   1243             pAuxData->xDelete(pAuxData->pAux);
  1243   1244           }
  1244   1245         }
  1245   1246         sqliteFree(pVdbeFunc);
  1246   1247       }
  1247   1248   #ifndef NDEBUG