/ Check-in [633951f0]
Login

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

Overview
Comment:Revise the API for user-defined functions. (CVS 398)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:633951f0fa11c91f93aa2862df84691750c01e73
User & Date: drh 2002-02-27 19:00:21
Context
2002-02-27
19:50
Try to reduce the number of malloc() for user-defined functions. Begin transfering built-in functions over to the user-define function mechanism. (CVS 399) check-in: c4f9e017 user: drh tags: trunk
19:00
Revise the API for user-defined functions. (CVS 398) check-in: 633951f0 user: drh tags: trunk
01:53
The user-defined function routines failed to detect a malloc() failure. (CVS 397) check-in: 085b0d67 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/expr.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
....
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.47 2002/02/27 01:53:13 drh Exp $
*/
#include "sqliteInt.h"


/*
** Construct a new expression node and return a pointer to it.  Memory
** for this node is obtained from sqliteMalloc().  The calling function
................................................................................
          pUser = sqliteFindUserFunction(pParse->db,
                      pExpr->token.z, pExpr->token.n, pList->nExpr, 0);
          assert( pUser!=0 );
          for(i=0; i<pList->nExpr; i++){
            sqliteExprCode(pParse, pList->a[i].pExpr);
          }
          sqliteVdbeAddOp(v, OP_UserFunc, pList->nExpr, 0);
          sqliteVdbeChangeP3(v, -1, (char*)pUser->xFunc, P3_POINTER);
          break;
        }
        default: {
          /* Can't happen! */
          break;
        }
      }
................................................................................
  const char *zName, /* Name of the function.  Not null-terminated */
  int nName,         /* Number of characters in the name */
  int nArg,          /* Number of arguments.  -1 means any number */
  int createFlag     /* Create new entry if true and does not otherwise exist */
){
  UserFunc *pFirst, *p, *pMaybe;
  pFirst = p = (UserFunc*)sqliteHashFind(&db->userFunc, zName, nName);
  if( p==0 ) return 0;
  if( !createFlag && nArg<0 ){
    while( p && p->xFunc==0 && p->xStep==0 ){ p = p->pNext; }
    return p;
  }
  pMaybe = 0;
  while( p && p->nArg!=nArg ){
    if( p->nArg<0 && !createFlag && (p->xFunc || p->xStep) ) pMaybe = p;
    p = p->pNext;







|







 







|







 







<
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
....
1392
1393
1394
1395
1396
1397
1398

1399
1400
1401
1402
1403
1404
1405
1406
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions in SQLite.
**
** $Id: expr.c,v 1.48 2002/02/27 19:00:21 drh Exp $
*/
#include "sqliteInt.h"


/*
** Construct a new expression node and return a pointer to it.  Memory
** for this node is obtained from sqliteMalloc().  The calling function
................................................................................
          pUser = sqliteFindUserFunction(pParse->db,
                      pExpr->token.z, pExpr->token.n, pList->nExpr, 0);
          assert( pUser!=0 );
          for(i=0; i<pList->nExpr; i++){
            sqliteExprCode(pParse, pList->a[i].pExpr);
          }
          sqliteVdbeAddOp(v, OP_UserFunc, pList->nExpr, 0);
          sqliteVdbeChangeP3(v, -1, (char*)pUser, P3_POINTER);
          break;
        }
        default: {
          /* Can't happen! */
          break;
        }
      }
................................................................................
  const char *zName, /* Name of the function.  Not null-terminated */
  int nName,         /* Number of characters in the name */
  int nArg,          /* Number of arguments.  -1 means any number */
  int createFlag     /* Create new entry if true and does not otherwise exist */
){
  UserFunc *pFirst, *p, *pMaybe;
  pFirst = p = (UserFunc*)sqliteHashFind(&db->userFunc, zName, nName);

  if( p && !createFlag && nArg<0 ){
    while( p && p->xFunc==0 && p->xStep==0 ){ p = p->pNext; }
    return p;
  }
  pMaybe = 0;
  while( p && p->nArg!=nArg ){
    if( p->nArg<0 && !createFlag && (p->xFunc || p->xStep) ) pMaybe = p;
    p = p->pNext;

Changes to src/func.c.

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
..
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
** 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.3 2002/02/26 23:55:31 drh Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include "sqlite.h"

/*
** Implementation of the upper() and lower() SQL functions.
*/
static void upperFunc(void *context, int argc, const char **argv){
  char *z;
  int i;
  if( argc<1 || argv[0]==0 ) return;
  z = sqlite_set_result_string(context, argv[0], -1);
  if( z==0 ) return;
  for(i=0; z[i]; i++){
    if( islower(z[i]) ) z[i] = toupper(z[i]);
  }
}
static void lowerFunc(void *context, int argc, const char **argv){
  char *z;
  int i;
  if( argc<1 || argv[0]==0 ) return;
  z = sqlite_set_result_string(context, argv[0], -1);
  if( z==0 ) return;
  for(i=0; z[i]; i++){
    if( isupper(z[i]) ) z[i] = tolower(z[i]);
................................................................................
  double sum2;    /* Sum of the squares of terms */
  int n;          /* Number of terms seen so far */
};

/*
** Routines used to compute the standard deviation as an aggregate.
*/
static void *stdDevStep(void *stddev, int argc, char **argv){
  StdDevCtx *p;
  double x;
  if( argc<1 ) return 0;
  if( stddev==0 ){
    p = malloc( sizeof(*p) );
    p->n = 0;
    p->sum = 0.0;
    p->sum2 = 0.0;
  }else{
    p = (StdDevCtx*)stddev;
  }
  x = atof(argv[0]);
  p->sum += x;
  p->sum2 += x*x;
  p->n++;
  return p;
}
static void stdDevFinalize(void *stddev, void *context){
  StdDevCtx *p = (StdDevCtx*)stddev;

  if( context && p && p->n>1 ){
    double rN = p->n;
    sqlite_set_result_double(context, 
       sqrt((p->sum2 - p->sum*p->sum/rN)/(rN-1.0)));
  }
  if( stddev ) free(stddev);
}

/*
** This function registered all of the above C functions as SQL
** functions.  This should be the only routine in this file with
** external linkage.
*/
void sqliteRegisterBuildinFunctions(sqlite *db){
  sqlite_create_function(db, "upper", 1, upperFunc);
  sqlite_create_function(db, "lower", 1, lowerFunc);
  sqlite_create_aggregate(db, "stddev", 1, stdDevStep, stdDevFinalize);
}







|









|









|







 







|


|
|
|
<
<
<
<
<
<




<

|
<
>
|




<








|
|
|

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
..
57
58
59
60
61
62
63
64
65
66
67
68
69






70
71
72
73

74
75

76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
** 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.4 2002/02/27 19:00:22 drh Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include "sqlite.h"

/*
** Implementation of the upper() and lower() SQL functions.
*/
static void upperFunc(sqlite_func *context, int argc, const char **argv){
  char *z;
  int i;
  if( argc<1 || argv[0]==0 ) return;
  z = sqlite_set_result_string(context, argv[0], -1);
  if( z==0 ) return;
  for(i=0; z[i]; i++){
    if( islower(z[i]) ) z[i] = toupper(z[i]);
  }
}
static void lowerFunc(sqlite_func *context, int argc, const char **argv){
  char *z;
  int i;
  if( argc<1 || argv[0]==0 ) return;
  z = sqlite_set_result_string(context, argv[0], -1);
  if( z==0 ) return;
  for(i=0; z[i]; i++){
    if( isupper(z[i]) ) z[i] = tolower(z[i]);
................................................................................
  double sum2;    /* Sum of the squares of terms */
  int n;          /* Number of terms seen so far */
};

/*
** Routines used to compute the standard deviation as an aggregate.
*/
static void stdDevStep(sqlite_func *context, int argc, const char **argv){
  StdDevCtx *p;
  double x;
  if( argc<1 ) return;
  p = sqlite_aggregate_context(context, sizeof(*p));
  if( p==0 ) return;






  x = atof(argv[0]);
  p->sum += x;
  p->sum2 += x*x;
  p->n++;

}
static void stdDevFinalize(sqlite_func *context){

  StdDevCtx *p = sqlite_aggregate_context(context, sizeof(*p));
  if( p && p->n>1 ){
    double rN = p->n;
    sqlite_set_result_double(context, 
       sqrt((p->sum2 - p->sum*p->sum/rN)/(rN-1.0)));
  }

}

/*
** This function registered all of the above C functions as SQL
** functions.  This should be the only routine in this file with
** external linkage.
*/
void sqliteRegisterBuildinFunctions(sqlite *db){
  sqlite_create_function(db, "upper", 1, upperFunc, 0);
  sqlite_create_function(db, "lower", 1, lowerFunc, 0);
  sqlite_create_aggregate(db, "stddev", 1, stdDevStep, stdDevFinalize, 0);
}

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
639
640
641
642
643
644
645
646

647
648
649
650
651
652
653
654

655
656
657
658
659
660
661
662

663
664
665
666
667
668
669
670

671
672
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.64 2002/02/27 01:53:13 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"

/*
** This is the callback routine for the code that initializes the
** database.  See sqliteInit() below for additional information.
................................................................................
** If nArg is -1 it means that this function will accept any number
** of arguments, including 0.
*/
int sqlite_create_function(
  sqlite *db,          /* Add the function to this database connection */
  const char *zName,   /* Name of the function to add */
  int nArg,            /* Number of arguments */
  void (*xFunc)(void*,int,const char**)  /* Implementation of the function */

){
  UserFunc *p;
  if( db==0 || zName==0 ) return 1;
  p = sqliteFindUserFunction(db, zName, strlen(zName), nArg, 1);
  if( p==0 ) return 1;
  p->xFunc = xFunc;
  p->xStep = 0;
  p->xFinalize = 0;

  return 0;
}
int sqlite_create_aggregate(
  sqlite *db,          /* Add the function to this database connection */
  const char *zName,   /* Name of the function to add */
  int nArg,            /* Number of arguments */
  void *(*xStep)(void*,int,const char**), /* The step function */
  void (*xFinalize)(void*,void*)          /* The finalizer */

){
  UserFunc *p;
  if( db==0 || zName==0 ) return 1;
  p = sqliteFindUserFunction(db, zName, strlen(zName), nArg, 1);
  if( p==0 ) return 1;
  p->xFunc = 0;
  p->xStep = xStep;
  p->xFinalize = xFinalize;

  return 0;
}







|







 







|
>








>






|
|
>








>


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.65 2002/02/27 19:00:22 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"

/*
** This is the callback routine for the code that initializes the
** database.  See sqliteInit() below for additional information.
................................................................................
** If nArg is -1 it means that this function will accept any number
** of arguments, including 0.
*/
int sqlite_create_function(
  sqlite *db,          /* Add the function to this database connection */
  const char *zName,   /* Name of the function to add */
  int nArg,            /* Number of arguments */
  void (*xFunc)(sqlite_func*,int,const char**),  /* The implementation */
  void *pUserData      /* User data */
){
  UserFunc *p;
  if( db==0 || zName==0 ) return 1;
  p = sqliteFindUserFunction(db, zName, strlen(zName), nArg, 1);
  if( p==0 ) return 1;
  p->xFunc = xFunc;
  p->xStep = 0;
  p->xFinalize = 0;
  p->pUserData = pUserData;
  return 0;
}
int sqlite_create_aggregate(
  sqlite *db,          /* Add the function to this database connection */
  const char *zName,   /* Name of the function to add */
  int nArg,            /* Number of arguments */
  void (*xStep)(sqlite_func*,int,const char**), /* The step function */
  void (*xFinalize)(sqlite_func*),              /* The finalizer */
  void *pUserData      /* User data */
){
  UserFunc *p;
  if( db==0 || zName==0 ) return 1;
  p = sqliteFindUserFunction(db, zName, strlen(zName), nArg, 1);
  if( p==0 ) return 1;
  p->xFunc = 0;
  p->xStep = xStep;
  p->xFinalize = xFinalize;
  p->pUserData = pUserData;
  return 0;
}

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
743
744
745
746
747
748
749


























































750
751
752
753
754
755
756
....
1051
1052
1053
1054
1055
1056
1057








1058
1059
1060
1061
1062
1063
1064
....
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
....
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225

1226

1227

1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.67 2002/02/27 01:47:12 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
    pParse->nErr++;
    return 1;
  }
  pParse->nTab = base;
  return 0;
}



























































/*
** Analyze the SELECT statement passed in as an argument to see if it
** is a simple min() or max() query.  If it is and this query can be
** satisfied using a single seek to the beginning or end of an index,
** then generate the code for this SELECT return 1.  If this is not a 
** simple min() or max() query, then return 0;
**
................................................................................
    if( sqliteExprResolveIds(pParse, pTabList, pEList, pHaving) ){
      goto select_end;
    }
    if( sqliteExprCheck(pParse, pHaving, isAgg, 0) ){
      goto select_end;
    }
  }









  /* Check for the special case of a min() or max() function by itself
  ** in the result set.
  */
  if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){
    rc = 0;
    goto select_end;
................................................................................
  /* Reset the aggregator
  */
  if( isAgg ){
    sqliteVdbeAddOp(v, OP_AggReset, 0, pParse->nAgg);
    for(i=0; i<pParse->nAgg; i++){
      UserFunc *pUser;
      if( (pUser = pParse->aAgg[i].pUser)!=0 && pUser->xFinalize!=0 ){
        sqliteVdbeAddOp(v, OP_AggFinalizer, 0, i);
        sqliteVdbeChangeP3(v, -1, (char*)pUser->xFinalize, P3_POINTER);
      }
    }
    if( pGroupBy==0 ){
      sqliteVdbeAddOp(v, OP_String, 0, 0);
      sqliteVdbeAddOp(v, OP_AggFocus, 0, 0);
      for(i=0; i<pParse->nAgg; i++){
        Expr *pE;
................................................................................
        continue;
      }
      assert( pE->op==TK_AGG_FUNCTION );
      assert( pE->pList!=0 );
      for(j=0; j<pE->pList->nExpr; j++){
        sqliteExprCode(pParse, pE->pList->a[j].pExpr);
      }
      sqliteVdbeAddOp(v, OP_AggGet, 0, i);
      switch( pE->iColumn ){
        case FN_Min:      op = OP_Min;     break;
        case FN_Max:      op = OP_Max;     break;
        case FN_Avg:      op = OP_Add;     break;
        case FN_Sum:      op = OP_Add;     break;
        case FN_Unknown:  op = OP_AggFunc; break;
      }
      if( op!=OP_AggFunc ){

        sqliteVdbeAddOp(v, op, 0, 0);

      }else{

        sqliteVdbeAddOp(v, OP_AggFunc, 0, pE->pList->nExpr);
        assert( pParse->aAgg[i].pUser!=0 );
        assert( pParse->aAgg[i].pUser->xStep!=0 );
        sqliteVdbeChangeP3(v,-1,(char*)pParse->aAgg[i].pUser->xStep,P3_POINTER);
      }
      sqliteVdbeAddOp(v, OP_AggSet, 0, i);
    }
  }

  /* End the database scan loop.
  */
  sqliteWhereEnd(pWInfo);








|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>







 







|
|







 







<








>

>

>



|

<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
....
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
....
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
....
1276
1277
1278
1279
1280
1281
1282

1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300

1301
1302
1303
1304
1305
1306
1307
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.68 2002/02/27 19:00:22 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
    pParse->nErr++;
    return 1;
  }
  pParse->nTab = base;
  return 0;
}

/*
** This routine attempts to flatten subqueries in order to speed
** execution.  It returns 1 if it makes changes and 0 if no flattening
** occurs.
**
** To understand the concept of flattening, consider the following
** query:
**
**     SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
**
** The default way of implementing this query is to execute the
** subquery first and store the results in a temporary table, then
** run the outer query on that temporary table.  This requires two
** passes over the data.  Furthermore, because the temporary table
** has no indices, the WHERE clause on the outer query cannot be
** optimized using indices.
**
** This routine attempts to write queries such as the above into
** a single flat select, like this:
**
**     SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
**
** The code generated for this simpification gives the same result
** but only has to scan the data once.
**
** Generally speaking, flattening is only possible if the subquery
** query is a simple query without a GROUP BY clause or the DISTINCT
** keyword and the outer query is not a join. 
**
** If flattening is not possible, this routine is a no-op and return 0.
** If flattening is possible, this routine  rewrites the query into
** the simplified form and return 1.
**
** All of the expression analysis must occur before this routine runs.
** This routine depends on the results of the expression analysis.
*/
int flattenSubqueries(Select *p){
  Select *pSub;
  if( p->pSrc->nId>1 ){
    return 0;   /* Cannot optimize: The outer query is a join. */
  }
  pSub = p->pSrc->a[0].pSelect;
  if( pSub==0 ){
    return 0;   /* Nothing to optimize: There is no subquery. */
  }
  if( pSub->isDistinct ){
    return 0;   /* Subquery contains DISTINCT keyword */
  }
  if( pSub->pGroupBy ){
    return 0;   /* Subquery contains a GROUP BY clause */
  }
  if( pSub->pPrior ){
    return 0;   /* Subquery is the union of two or more queries */
  } 

  return 0;
}	

/*
** Analyze the SELECT statement passed in as an argument to see if it
** is a simple min() or max() query.  If it is and this query can be
** satisfied using a single seek to the beginning or end of an index,
** then generate the code for this SELECT return 1.  If this is not a 
** simple min() or max() query, then return 0;
**
................................................................................
    if( sqliteExprResolveIds(pParse, pTabList, pEList, pHaving) ){
      goto select_end;
    }
    if( sqliteExprCheck(pParse, pHaving, isAgg, 0) ){
      goto select_end;
    }
  }

  /* Try to merge subqueries in the FROM clause into the main
  ** query.
  */
  if( flattenSubqueries(p) ){
    pEList = p->pEList;
    pWhere = p->pWhere;
  }

  /* Check for the special case of a min() or max() function by itself
  ** in the result set.
  */
  if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){
    rc = 0;
    goto select_end;
................................................................................
  /* Reset the aggregator
  */
  if( isAgg ){
    sqliteVdbeAddOp(v, OP_AggReset, 0, pParse->nAgg);
    for(i=0; i<pParse->nAgg; i++){
      UserFunc *pUser;
      if( (pUser = pParse->aAgg[i].pUser)!=0 && pUser->xFinalize!=0 ){
        sqliteVdbeAddOp(v, OP_AggInit, 0, i);
        sqliteVdbeChangeP3(v, -1, (char*)pUser, P3_POINTER);
      }
    }
    if( pGroupBy==0 ){
      sqliteVdbeAddOp(v, OP_String, 0, 0);
      sqliteVdbeAddOp(v, OP_AggFocus, 0, 0);
      for(i=0; i<pParse->nAgg; i++){
        Expr *pE;
................................................................................
        continue;
      }
      assert( pE->op==TK_AGG_FUNCTION );
      assert( pE->pList!=0 );
      for(j=0; j<pE->pList->nExpr; j++){
        sqliteExprCode(pParse, pE->pList->a[j].pExpr);
      }

      switch( pE->iColumn ){
        case FN_Min:      op = OP_Min;     break;
        case FN_Max:      op = OP_Max;     break;
        case FN_Avg:      op = OP_Add;     break;
        case FN_Sum:      op = OP_Add;     break;
        case FN_Unknown:  op = OP_AggFunc; break;
      }
      if( op!=OP_AggFunc ){
        sqliteVdbeAddOp(v, OP_AggGet, 0, i);
        sqliteVdbeAddOp(v, op, 0, 0);
        sqliteVdbeAddOp(v, OP_AggSet, 0, i);
      }else{
        sqliteVdbeAddOp(v, OP_Integer, i, 0);
        sqliteVdbeAddOp(v, OP_AggFunc, 0, pE->pList->nExpr);
        assert( pParse->aAgg[i].pUser!=0 );
        assert( pParse->aAgg[i].pUser->xStep!=0 );
        sqliteVdbeChangeP3(v, -1, (char*)pParse->aAgg[i].pUser, P3_POINTER);
      }

    }
  }

  /* End the database scan loop.
  */
  sqliteWhereEnd(pWInfo);

Changes to src/sqlite.h.in.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
358
359
360
361
362
363
364






365
366
367
368
369
370
371
372
373

374
375
376
377
378
379
380

381
382
383
384
385
386
387
388
389
390
391
392
393





394
395
396
397
398



























399
400
401
402
403
404
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.26 2002/02/23 23:45:45 drh Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** The version of the SQLite library.
................................................................................
  char ***resultp,       /* Result written to a char *[]  that this points to */
  int *nrow,             /* Number of result rows written here */
  int *ncolumn,          /* Number of result columns written here */
  char **errmsg,         /* Error msg written here */
  va_list ap             /* Arguments to the format string */
);







/*
** Use the following routines to create new user-defined functions.  See
** the documentation for details.
*/
int sqlite_create_function(
  sqlite*,               /* Database where the new function is registered */
  const char *zName,     /* Name of the new function */
  int nArg,              /* Number of arguments.  -1 means any number */
  void (*xFunc)(void*,int,const char**)  /* C code to implement the function */

);
int sqlite_create_aggregate(
  sqlite*,               /* Database where the new function is registered */
  const char *zName,     /* Name of the function */
  int nArg,              /* Number of arguments */
  void *(*xStep)(void*,int,const char**), /* Called for each row */
  void (*xFinalize)(void*,void*)          /* Called once to get final result */

);

/*
** The user function implementations call one of the following four routines
** in order to return their results.  The first parameter to each of these
** routines is a copy of the first argument to xFunc() or the second argument
** to xFinalize().  The second parameter to these routines is the result
** to be returned.  A NULL can be passed as the second parameter to
** sqlite_set_result_string() in order to return a NULL result.
**
** The 3rd argument to _string and _error is the number of characters to
** take from the string.  If this argument is negative, then all characters
** up to and including the first '\000' are used.





*/
char *sqlite_set_result_string(void*,const char*,int);
void sqlite_set_result_int(void*,int);
void sqlite_set_result_double(void*,double);
void sqlite_set_result_error(void*,const char*,int);




























#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif

#endif /* _SQLITE_H_ */







|







 







>
>
>
>
>
>





|
|
|
|
>


|
|
|
|
|
>





|
|
|
|




>
>
>
>
>

|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.27 2002/02/27 19:00:22 drh Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** The version of the SQLite library.
................................................................................
  char ***resultp,       /* Result written to a char *[]  that this points to */
  int *nrow,             /* Number of result rows written here */
  int *ncolumn,          /* Number of result columns written here */
  char **errmsg,         /* Error msg written here */
  va_list ap             /* Arguments to the format string */
);

/*
** A pointer to the following structure is used to communicate with
** the implementations of user-defined functions.
*/
typedef struct sqlite_func sqlite_func;

/*
** Use the following routines to create new user-defined functions.  See
** the documentation for details.
*/
int sqlite_create_function(
  sqlite*,                  /* Database where the new function is registered */
  const char *zName,        /* Name of the new function */
  int nArg,                 /* Number of arguments.  -1 means any number */
  void (*xFunc)(sqlite_func*,int,const char**),  /* C code to implement */
  void *pUserData           /* Available via the sqlite_user_data() call */
);
int sqlite_create_aggregate(
  sqlite*,                  /* Database where the new function is registered */
  const char *zName,        /* Name of the function */
  int nArg,                 /* Number of arguments */
  void (*xStep)(sqlite_func*,int,const char**), /* Called for each row */
  void (*xFinalize)(sqlite_func*),       /* Called once to get final result */
  void *pUserData           /* Available via the sqlite_user_data() call */
);

/*
** The user function implementations call one of the following four routines
** in order to return their results.  The first parameter to each of these
** routines is a copy of the first argument to xFunc() or xFinialize()
** The second parameter to these routines is the result to be returned.
** A NULL can be passed as the second parameter to sqlite_set_result_string()
** in order to return a NULL result.
**
** The 3rd argument to _string and _error is the number of characters to
** take from the string.  If this argument is negative, then all characters
** up to and including the first '\000' are used.
**
** The sqlite_set_result_string() function allocates a buffer to hold the
** result and returns a pointer to this buffer.  The calling routine
** (that is, the implmentation of a user function) can alter the content
** of this buffer if desired.
*/
char *sqlite_set_result_string(sqlite_func*,const char*,int);
void sqlite_set_result_int(sqlite_func*,int);
void sqlite_set_result_double(sqlite_func*,double);
void sqlite_set_result_error(sqlite_func*,const char*,int);

/*
** The pUserData parameter to the sqlite_create_function() and
** sqlite_create_aggregate() routines used to register user functions
** is available to the implementation of the function using this
** call.
*/
void *sqlite_user_data(sqlite_func*);

/*
** User aggregate functions use the following routine to allocate
** a structure for storing their context.  The first time this routine
** is called for a particular aggregate, a new structure of size nBytes
** is allocated, zeroed, and returned.  On subsequent calls (for the
** same aggregate instance) the same buffer is returned.  The implementation
** of the aggregate can use the returned buffer to accumulate data.
**
** The buffer allocated is freed automatically be SQLite.
*/
void *sqlite_aggregate_context(sqlite_func*, int nBytes);

/*
** The next return returns the number of calls to xStep for a particular
** aggregate function instance.  The current call to xStep counts so the
** function always returns at least 1.
*/
int sqlite_aggregate_count(sqlite_func*);

#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif

#endif /* _SQLITE_H_ */

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.94 2002/02/27 01:47:12 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
................................................................................
/*
** Each user-defined function is defined by an instance of the following
** structure.  A pointer to this structure is stored in the sqlite.userFunc
** hash table.  When multiple functions have the same name, the hash table
** points to a linked list of these structures.
*/
struct UserFunc {
  void (*xFunc)(void*,int,const char**);   /* Regular function */
  void *(*xStep)(void*,int,const char**);  /* Aggregate function step */
  void (*xFinalize)(void*,void*);          /* Aggregate function finializer */
  int nArg;                                /* Number of arguments */

  UserFunc *pNext;                         /* Next function with same name */
};

/*
** information about each column of an SQL table is held in an instance
** of this structure.
*/
struct Column {







|







 







|
|
|
|
>
|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
**    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.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.95 2002/02/27 19:00:22 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
................................................................................
/*
** Each user-defined function is defined by an instance of the following
** structure.  A pointer to this structure is stored in the sqlite.userFunc
** hash table.  When multiple functions have the same name, the hash table
** points to a linked list of these structures.
*/
struct UserFunc {
  void (*xFunc)(sqlite_func*,int,const char**);   /* Regular function */
  void *(*xStep)(sqlite_func*,int,const char**);  /* Aggregate function step */
  void (*xFinalize)(sqlite_func*);           /* Aggregate function finializer */
  int nArg;                                  /* Number of arguments */
  void *pUserData;                           /* User data parameter */
  UserFunc *pNext;                           /* Next function with same name */
};

/*
** information about each column of an SQL table is held in an instance
** of this structure.
*/
struct Column {

Changes to src/vdbe.c.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
138
139
140
141
142
143
144
145
146
147
148










149
150
151



152

153


154
155
156
157
158
159
160
161
162
...
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
...
521
522
523
524
525
526
527




528
529
530

531
532
533
534
535
536
537
...
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579











































580






581
582
583
584
585
586
587
588
589



590





591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
...
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
....
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791


1792
1793
1794
1795
1796

1797
1798
1799
1800
1801
1802
1803
1804
1805
1806

1807

1808
1809
1810
1811
1812
1813
1814
1815
....
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334

4335
4336
4337
4338
4339
4340
4341

4342
4343
4344
4345
4346

4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360

4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372








4373
4374
4375
4376
4377
4378
4379
....
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527

4528
4529
4530
4531
4532




4533
4534
4535
4536
4537
4538
4539
** type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.123 2002/02/24 03:25:16 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The following global variable is incremented every time a cursor
** moves, either by the OP_MoveTo or the OP_Next opcode.  The test
................................................................................
#define STK_Dyn       0x0010   /* Need to call sqliteFree() on zStack[*] */
#define STK_Static    0x0020   /* zStack[] points to a static string */

/* The following STK_ value appears only in AggElem.aMem.s.flag fields.
** It indicates that the corresponding AggElem.aMem.z points to a
** user-defined aggregate context that needs to be finalized.
*/
#define STK_AggCtx    0x0040   /* zStack[] points to an user function context */

/*
** The "context" argument for a user-defined function.










*/
struct UserFuncContext {
  Stack s;       /* Small string, integer, and floating point values go here */



  char *z;       /* Space for holding dynamic string results */

  int isError;   /* Set to true for an error */


};
typedef struct UserFuncContext UserFuncContext;

/*
** An Agg structure describes an Aggregator.  Each Agg consists of
** zero or more Aggregator elements (AggElem).  Each AggElem contains
** a key and one or more values.  The values are used in processing
** aggregate functions in a SELECT.  The key is used to implement
** the GROUP BY clause of a select.
................................................................................
typedef struct Agg Agg;
typedef struct AggElem AggElem;
struct Agg {
  int nMem;            /* Number of values stored in each AggElem */
  AggElem *pCurrent;   /* The AggElem currently in focus */
  HashElem *pSearch;   /* The hash element for pCurrent */
  Hash hash;           /* Hash table of all aggregate elements */
  void (**axFinalize)(void*,void*);  /* Array of nMem finalizers */
};
struct AggElem {
  char *zKey;          /* The key to this AggElem */
  int nKey;            /* Number of bytes in the key, including '\0' at end */
  Mem aMem[1];         /* The values for this AggElem */
};

................................................................................
** sqlite_set_result_error() works like sqlite_set_result_string() except
** that it signals a fatal error.  The string argument, if any, is the
** error message.  If the argument is NULL a generic substitute error message
** is used.
**
** The sqlite_set_result_int() and sqlite_set_result_double() set the return
** value of the user function to an integer or a double.




*/
char *sqlite_set_result_string(void *context, const char *zResult, int n){
  UserFuncContext *p = (UserFuncContext*)context;

  if( p->s.flags & STK_Dyn ){
    sqliteFree(p->z);
  }
  if( zResult==0 ){
    p->s.flags = STK_Null;
    n = 0;
    p->z = 0;
................................................................................
      }
      p->s.flags = STK_Str | STK_Dyn;
    }
  }
  p->s.n = n;
  return p->z;
}
void sqlite_set_result_int(void *context, int iResult){
  UserFuncContext *p = (UserFuncContext*)context;
  if( p->s.flags & STK_Dyn ){
    sqliteFree(p->z);
  }
  p->s.i = iResult;
  p->s.flags = STK_Int;
}
void sqlite_set_result_double(void *context, double rResult){
  UserFuncContext *p = (UserFuncContext*)context;
  if( p->s.flags & STK_Dyn ){
    sqliteFree(p->z);
  }
  p->s.r = rResult;
  p->s.flags = STK_Real;
}
void sqlite_set_result_error(void *context, const char *zMsg, int n){
  UserFuncContext *p = (UserFuncContext*)context;
  sqlite_set_result_string(context, zMsg, n);
  p->isError = 1;
}

/*











































** Reset an Agg structure.  Delete all its contents.






*/
static void AggReset(Agg *pAgg){
  int i;
  HashElem *p;
  for(p = sqliteHashFirst(&pAgg->hash); p; p = sqliteHashNext(p)){
    AggElem *pElem = sqliteHashData(p);
    assert( pAgg->axFinalize!=0 );
    for(i=0; i<pAgg->nMem; i++){
      if( pElem->aMem[i].s.flags & STK_Dyn ){



        sqliteFree(pElem->aMem[i].z);





      }else if( pAgg->axFinalize[i] && (pElem->aMem[i].s.flags & STK_AggCtx) ){
        (pAgg->axFinalize[i])((void*)pElem->aMem[i].z, 0);
      }
    }
    sqliteFree(pElem);
  }
  sqliteHashClear(&pAgg->hash);
  sqliteFree(pAgg->axFinalize);
  pAgg->axFinalize = 0;
  pAgg->pCurrent = 0;
  pAgg->pSearch = 0;
  pAgg->nMem = 0;
}

/*
** Insert a new element and make it the current element.  
................................................................................
  "Clear",             "CreateIndex",       "CreateTable",       "IntegrityCk",
  "IdxPut",            "IdxDelete",         "IdxRecno",          "IdxGT",
  "IdxGE",             "MemLoad",           "MemStore",          "ListWrite",
  "ListRewind",        "ListRead",          "ListReset",         "SortPut",
  "SortMakeRec",       "SortMakeKey",       "Sort",              "SortNext",
  "SortCallback",      "SortReset",         "FileOpen",          "FileRead",
  "FileColumn",        "AggReset",          "AggFocus",          "AggIncr",
  "AggNext",           "AggSet",            "AggGet",            "AggFinalizer",
  "AggFunc",           "SetInsert",         "SetFound",          "SetNotFound",
  "MakeRecord",        "MakeKey",           "MakeIdxKey",        "IncrKey",
  "Goto",              "If",                "Halt",              "ColumnCount",
  "ColumnName",        "Callback",          "NullCallback",      "Integer",
  "String",            "Pop",               "Dup",               "Pull",
  "Push",              "MustBeInt",         "Add",               "AddImm",
  "Subtract",          "Multiply",          "Divide",            "Remainder",
  "BitAnd",            "BitOr",             "BitNot",            "ShiftLeft",
................................................................................
  }
  p->tos = nos;
  break;
}

/* Opcode: UserFunc P1 * P3
**
** Invoke a user function (P3 is a pointer to the function) with
** P1 string arguments taken from the stack.  Pop all arguments from
** the stack and push back the result.


*/
case OP_UserFunc: {
  int n, i;
  UserFuncContext ctx;
  void (*xFunc)(void*,int,const char**);

  n = pOp->p1;
  VERIFY( if( n<=0 ) goto bad_instruction; )
  VERIFY( if( p->tos+1<n ) goto not_enough_stack; )
  for(i=p->tos-n+1; i<=p->tos; i++){
    if( (aStack[i].flags & STK_Null)==0 ){
      if( Stringify(p, i) ) goto no_mem;
    }
  }
  xFunc = (void(*)(void*,int,const char**))pOp->p3;
  ctx.s.flags = STK_Null;

  ctx.isError = 0;

  xFunc((void*)&ctx, n, (const char**)&zStack[p->tos-n+1]);
  PopStack(p, n);
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos] = ctx.s;
  if( ctx.s.flags & STK_Dyn ){
    zStack[p->tos] = ctx.z;
  }else if( ctx.s.flags & STK_Str ){
................................................................................
**
** Reset the aggregator so that it no longer contains any data.
** Future aggregator elements will contain P2 values each.
*/
case OP_AggReset: {
  AggReset(&p->agg);
  p->agg.nMem = pOp->p2;
  p->agg.axFinalize = sqliteMalloc( p->agg.nMem*sizeof(p->agg.axFinalize[0]) );
  break;
}

/* Opcode: AggFinalizer * P2 P3
**
** Register a finializer function for the P2-th column of the aggregate.
** The P3 parameter is a pointer to the finalizer.
** There should be one instance of this opcode immediately following
** each AggReset for each user defined aggregate function that is used
** in a SELECT.
**
** All finalizers must be registered so that user-defined aggregate
** function contexts can be deallocated if the VDBE aborts.
*/
case OP_AggFinalizer: {
  int i = pOp->p2;
  VERIFY( if( p->agg.nMem<=i ) goto bad_instruction; );
  p->agg.axFinalize[i] = (void(*)(void*,void*))pOp->p3;

  break;
}

/* Opcode: AggFunc * P2 P3
**
** Execute the step function for a user-defined aggregate.  The
** function has P2 arguments.  P3 is a pointer to the step function.

**
** The top of the stack should be the function context.  The P2
** parameters occur below the function context on the stack.  The
** revised function context remains on the stack after this op-code
** finishes.

*/
case OP_AggFunc: {
  int n = pOp->p2;
  int i;
  void *pCtx;
  void *(*xStep)(void*,int,const char**);

  if( aStack[p->tos].flags & STK_AggCtx ){
    pCtx = zStack[p->tos];
  }else{
    pCtx = 0;
  }
  VERIFY( if( n<=0 ) goto bad_instruction; )
  VERIFY( if( p->tos+1<n ) goto not_enough_stack; )

  for(i=p->tos-n; i<p->tos; i++){
    if( (aStack[i].flags & STK_Null)==0 ){
      if( Stringify(p, i) ) goto no_mem;
    }
  }
  xStep = (void*(*)(void*,int,const char**))pOp->p3;
  pCtx = xStep(pCtx, n, (const char**)&zStack[p->tos-n]);
  PopStack(p, n+1);
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos].flags = STK_AggCtx;
  zStack[p->tos] = (char*)pCtx;








  break;
}

/* Opcode: AggFocus * P2 *
**
** Pop the top of the stack and use that as an aggregator key.  If
** an aggregator with that same key already exists, then make the
................................................................................
  }else{
    p->agg.pSearch = sqliteHashNext(p->agg.pSearch);
  }
  if( p->agg.pSearch==0 ){
    pc = pOp->p2 - 1;
  } else {
    int i;
    UserFuncContext ctx;
    void *pCtx;
    Mem *aMem;
    int nErr = 0;
    p->agg.pCurrent = sqliteHashData(p->agg.pSearch);
    aMem = p->agg.pCurrent->aMem;
    for(i=0; i<p->agg.nMem; i++){
      if( p->agg.axFinalize[i]==0 ) continue;

      if( (aMem[i].s.flags & STK_AggCtx)==0 ) continue;
      ctx.s.flags = STK_Null;
      ctx.z = 0;
      pCtx = (void*)aMem[i].z;
      (*p->agg.axFinalize[i])(pCtx, &ctx);




      aMem[i].s = ctx.s;
      aMem[i].z = ctx.z;
      if( (aMem[i].s.flags & STK_Str) &&
              (aMem[i].s.flags & (STK_Dyn|STK_Static))==0 ){
        aMem[i].z = aMem[i].s.z;
      }
      nErr += ctx.isError;







|







 







|


|
>
>
>
>
>
>
>
>
>
>

<
<
>
>
>
|
>
|
>
>

<







 







|







 







>
>
>
>

|
<
>







 







|
|






|
|






|
|
|




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>






|

|
>
>
>
|
>
>
>
>
>
|
|





|
|







 







|
|







 







|
|
|
>
>



|
<
>








|

>

>
|







 







|



|

|
|
|
<
<
<
<
<

|

|
<
>






|
>

|
<
|
|
>




|
|

<
<
<
<
<


>





|
|
|
|
|
|
|
>
>
>
>
>
>
>
>







 







|
<





|
>



|
|
>
>
>
>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159


160
161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
...
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
534
535
536
537
538
539
540
541
542
543
544
545
546

547
548
549
550
551
552
553
554
...
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
....
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
....
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871

1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
....
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402





4403
4404
4405
4406

4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417

4418
4419
4420
4421
4422
4423
4424
4425
4426
4427





4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
....
4591
4592
4593
4594
4595
4596
4597
4598

4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
** type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.124 2002/02/27 19:00:22 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** The following global variable is incremented every time a cursor
** moves, either by the OP_MoveTo or the OP_Next opcode.  The test
................................................................................
#define STK_Dyn       0x0010   /* Need to call sqliteFree() on zStack[*] */
#define STK_Static    0x0020   /* zStack[] points to a static string */

/* The following STK_ value appears only in AggElem.aMem.s.flag fields.
** It indicates that the corresponding AggElem.aMem.z points to a
** user-defined aggregate context that needs to be finalized.
*/
#define STK_AggCtx    0x0040   /* zStack[] points to an agg function context */

/*
** The "context" argument for a user-defined function.  A pointer to an
** instance of this structure is the first argument to the routines used
** implement user-defined SQL functions.
**
** There is a typedef for this structure in sqlite.h.  So all routines,
** even the public interface to SQLite, can use a pointer to this structure.
** But this file is the only place where the internal details of this
** structure are known.
**
** This structure is defined inside of vdbe.c because it uses substructures
** (Stack) which are only defined there.
*/


struct sqlite_func {
  UserFunc *pFunc;  /* Pointer to function information.  MUST BE FIRST */
  Stack s;          /* Small strings, ints, and double values go here */
  char *z;          /* Space for holding dynamic string results */
  void *pAgg;       /* Aggregate context */
  u8 isError;       /* Set to true for an error */
  u8 isStep;        /* Current in the step function */
  int cnt;          /* Number of times that the step function has been called */
};


/*
** An Agg structure describes an Aggregator.  Each Agg consists of
** zero or more Aggregator elements (AggElem).  Each AggElem contains
** a key and one or more values.  The values are used in processing
** aggregate functions in a SELECT.  The key is used to implement
** the GROUP BY clause of a select.
................................................................................
typedef struct Agg Agg;
typedef struct AggElem AggElem;
struct Agg {
  int nMem;            /* Number of values stored in each AggElem */
  AggElem *pCurrent;   /* The AggElem currently in focus */
  HashElem *pSearch;   /* The hash element for pCurrent */
  Hash hash;           /* Hash table of all aggregate elements */
  UserFunc **apFunc;   /* Information about user-defined aggregate functions */
};
struct AggElem {
  char *zKey;          /* The key to this AggElem */
  int nKey;            /* Number of bytes in the key, including '\0' at end */
  Mem aMem[1];         /* The values for this AggElem */
};

................................................................................
** sqlite_set_result_error() works like sqlite_set_result_string() except
** that it signals a fatal error.  The string argument, if any, is the
** error message.  If the argument is NULL a generic substitute error message
** is used.
**
** The sqlite_set_result_int() and sqlite_set_result_double() set the return
** value of the user function to an integer or a double.
**
** These routines are defined here in vdbe.c because they depend on knowing
** the internals of the sqlite_func structure which is only defined in that
** one source file.
*/
char *sqlite_set_result_string(sqlite_func *p, const char *zResult, int n){

  assert( !p->isStep );
  if( p->s.flags & STK_Dyn ){
    sqliteFree(p->z);
  }
  if( zResult==0 ){
    p->s.flags = STK_Null;
    n = 0;
    p->z = 0;
................................................................................
      }
      p->s.flags = STK_Str | STK_Dyn;
    }
  }
  p->s.n = n;
  return p->z;
}
void sqlite_set_result_int(sqlite_func *p, int iResult){
  assert( !p->isStep );
  if( p->s.flags & STK_Dyn ){
    sqliteFree(p->z);
  }
  p->s.i = iResult;
  p->s.flags = STK_Int;
}
void sqlite_set_result_double(sqlite_func *p, double rResult){
  assert( !p->isStep );
  if( p->s.flags & STK_Dyn ){
    sqliteFree(p->z);
  }
  p->s.r = rResult;
  p->s.flags = STK_Real;
}
void sqlite_set_result_error(sqlite_func *p, const char *zMsg, int n){
  assert( !p->isStep );
  sqlite_set_result_string(p, zMsg, n);
  p->isError = 1;
}

/*
** Extract the user data from a sqlite_func structure and return a
** pointer to it.
**
** This routine is defined here in vdbe.c because it depends on knowing
** the internals of the sqlite_func structure which is only defined in that
** one source file.
*/
void *sqlite_user_data(sqlite_func *p){
  assert( p && p->pFunc );
  return p->pFunc->pUserData;
}

/*
** Allocate or return the aggregate context for a user function.  A new
** context is allocated on the first call.  Subsequent calls return the
** same context that was returned on prior calls.
**
** This routine is defined here in vdbe.c because it depends on knowing
** the internals of the sqlite_func structure which is only defined in that
** one source file.
*/
void *sqlite_aggregate_context(sqlite_func *p, int nByte){
  assert( p && p->pFunc && p->pFunc->xStep );
  if( p->pAgg==0 ){
    p->pAgg = sqliteMalloc( nByte );
  }
  return p->pAgg;
}

/*
** Return the number of times the Step function of a user-defined 
** aggregate has been called.
**
** This routine is defined here in vdbe.c because it depends on knowing
** the internals of the sqlite_func structure which is only defined in that
** one source file.
*/
int sqlite_aggregate_count(sqlite_func *p){
  assert( p && p->pFunc && p->pFunc->xStep );
  return p->cnt;
}

/*
** Reset an Agg structure.  Delete all its contents. 
**
** For user-defined aggregate functions, if the step function has been
** called, make sure the finalizer function has also been called.  The
** finalizer might need to free memory that was allocated as part of its
** private context.  If the finalizer has not been called yet, call it
** now.
*/
static void AggReset(Agg *pAgg){
  int i;
  HashElem *p;
  for(p = sqliteHashFirst(&pAgg->hash); p; p = sqliteHashNext(p)){
    AggElem *pElem = sqliteHashData(p);
    assert( pAgg->apFunc!=0 );
    for(i=0; i<pAgg->nMem; i++){
      if( pAgg->apFunc[i] && (pElem->aMem[i].s.flags & STK_AggCtx)!=0 ){
        sqlite_func ctx;
        ctx.s.flags = STK_Null;
        ctx.z = 0;
        ctx.pAgg = pElem->aMem[i].z;
        ctx.cnt = pElem->aMem[i].s.i;
        ctx.isStep = 0;
        ctx.isError = 0;
        (*pAgg->apFunc[i]->xFinalize)(&ctx);
      }
      if( pElem->aMem[i].s.flags & (STK_Dyn | STK_AggCtx) ){
        sqliteFree(pElem->aMem[i].z);
      }
    }
    sqliteFree(pElem);
  }
  sqliteHashClear(&pAgg->hash);
  sqliteFree(pAgg->apFunc);
  pAgg->apFunc = 0;
  pAgg->pCurrent = 0;
  pAgg->pSearch = 0;
  pAgg->nMem = 0;
}

/*
** Insert a new element and make it the current element.  
................................................................................
  "Clear",             "CreateIndex",       "CreateTable",       "IntegrityCk",
  "IdxPut",            "IdxDelete",         "IdxRecno",          "IdxGT",
  "IdxGE",             "MemLoad",           "MemStore",          "ListWrite",
  "ListRewind",        "ListRead",          "ListReset",         "SortPut",
  "SortMakeRec",       "SortMakeKey",       "Sort",              "SortNext",
  "SortCallback",      "SortReset",         "FileOpen",          "FileRead",
  "FileColumn",        "AggReset",          "AggFocus",          "AggIncr",
  "AggNext",           "AggSet",            "AggGet",            "AggFunc",
  "AggInit",           "SetInsert",         "SetFound",          "SetNotFound",
  "MakeRecord",        "MakeKey",           "MakeIdxKey",        "IncrKey",
  "Goto",              "If",                "Halt",              "ColumnCount",
  "ColumnName",        "Callback",          "NullCallback",      "Integer",
  "String",            "Pop",               "Dup",               "Pull",
  "Push",              "MustBeInt",         "Add",               "AddImm",
  "Subtract",          "Multiply",          "Divide",            "Remainder",
  "BitAnd",            "BitOr",             "BitNot",            "ShiftLeft",
................................................................................
  }
  p->tos = nos;
  break;
}

/* Opcode: UserFunc P1 * P3
**
** Invoke a user function (P3 is a pointer to a UserFunc structure that
** defines the function) with P1 string arguments taken from the stack.
** Pop all arguments from the stack and push back the result.
**
** See also: AggFunc
*/
case OP_UserFunc: {
  int n, i;
  sqlite_func ctx;


  n = pOp->p1;
  VERIFY( if( n<=0 ) goto bad_instruction; )
  VERIFY( if( p->tos+1<n ) goto not_enough_stack; )
  for(i=p->tos-n+1; i<=p->tos; i++){
    if( (aStack[i].flags & STK_Null)==0 ){
      if( Stringify(p, i) ) goto no_mem;
    }
  }
  ctx.pFunc = (UserFunc*)pOp->p3;
  ctx.s.flags = STK_Null;
  ctx.z = 0;
  ctx.isError = 0;
  ctx.isStep = 0;
  (*ctx.pFunc->xFunc)(&ctx, n, (const char**)&zStack[p->tos-n+1]);
  PopStack(p, n);
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos] = ctx.s;
  if( ctx.s.flags & STK_Dyn ){
    zStack[p->tos] = ctx.z;
  }else if( ctx.s.flags & STK_Str ){
................................................................................
**
** Reset the aggregator so that it no longer contains any data.
** Future aggregator elements will contain P2 values each.
*/
case OP_AggReset: {
  AggReset(&p->agg);
  p->agg.nMem = pOp->p2;
  p->agg.apFunc = sqliteMalloc( p->agg.nMem*sizeof(p->agg.apFunc[0]) );
  break;
}

/* Opcode: AggInit * P2 P3
**
** Initialize the function parameters for a user-defined aggregate function.
** The user-defined aggregate will operate out of aggregate column P2.
** P3 is a pointer to the UserFunc structure for the function.





*/
case OP_AggInit: {
  int i = pOp->p2;
  VERIFY( if( i<0 || i>=p->agg.nMem ) goto bad_instruction; )

  p->agg.apFunc[i] = (UserFunc*)pOp->p3;
  break;
}

/* Opcode: AggFunc * P2 P3
**
** Execute the step function for a user-defined aggregate.  The
** function has P2 arguments.  P3 is a pointer to the UserFunc
** structure that specifies the user-defined function.
**
** The top of the stack must be an integer which is the index of

** the aggregate column that corresponds to this aggregate function.
** Ideally, this index would be another parameter, but there are
** no free parameters left.  The integer is popped from the stack.
*/
case OP_AggFunc: {
  int n = pOp->p2;
  int i;
  Mem *pMem;
  sqlite_func ctx;






  VERIFY( if( n<=0 ) goto bad_instruction; )
  VERIFY( if( p->tos+1<n ) goto not_enough_stack; )
  VERIFY( if( aStack[p->tos].flags!=STK_Int ) goto bad_instruction; )
  for(i=p->tos-n; i<p->tos; i++){
    if( (aStack[i].flags & STK_Null)==0 ){
      if( Stringify(p, i) ) goto no_mem;
    }
  }
  i = aStack[p->tos].i;
  VERIFY( if( i<0 || i>=p->agg.nMem ) goto bad_instruction; )
  ctx.pFunc = (UserFunc*)pOp->p3;
  pMem = &p->agg.pCurrent->aMem[i];
  ctx.pAgg = pMem->z;
  ctx.cnt = ++pMem->s.i;
  ctx.isError = 0;
  ctx.isStep = 1;
  (ctx.pFunc->xStep)(&ctx, n, (const char**)&zStack[p->tos-n]);
  pMem->z = ctx.pAgg;
  pMem->s.flags = STK_AggCtx;
  PopStack(p, n+1);
  if( ctx.isError ){
    rc = SQLITE_ERROR;
  }
  break;
}

/* Opcode: AggFocus * P2 *
**
** Pop the top of the stack and use that as an aggregator key.  If
** an aggregator with that same key already exists, then make the
................................................................................
  }else{
    p->agg.pSearch = sqliteHashNext(p->agg.pSearch);
  }
  if( p->agg.pSearch==0 ){
    pc = pOp->p2 - 1;
  } else {
    int i;
    sqlite_func ctx;

    Mem *aMem;
    int nErr = 0;
    p->agg.pCurrent = sqliteHashData(p->agg.pSearch);
    aMem = p->agg.pCurrent->aMem;
    for(i=0; i<p->agg.nMem; i++){
      if( p->agg.apFunc[i]==0 ) continue;
      if( p->agg.apFunc[i]->xFinalize==0 ) continue;
      if( (aMem[i].s.flags & STK_AggCtx)==0 ) continue;
      ctx.s.flags = STK_Null;
      ctx.z = 0;
      ctx.pAgg = (void*)aMem[i].z;
      ctx.cnt = aMem[i].s.i;
      ctx.isStep = 0;
      ctx.pFunc = p->agg.apFunc[i];
      (*p->agg.apFunc[i]->xFinalize)(&ctx);
      sqliteFree( aMem[i].z );
      aMem[i].s = ctx.s;
      aMem[i].z = ctx.z;
      if( (aMem[i].s.flags & STK_Str) &&
              (aMem[i].s.flags & (STK_Dyn|STK_Static))==0 ){
        aMem[i].z = aMem[i].s.z;
      }
      nErr += ctx.isError;

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
136
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.46 2002/02/24 03:25:16 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................

#define OP_AggReset           58
#define OP_AggFocus           59
#define OP_AggIncr            60
#define OP_AggNext            61
#define OP_AggSet             62
#define OP_AggGet             63
#define OP_AggFinalizer       64
#define OP_AggFunc            65


#define OP_SetInsert          66
#define OP_SetFound           67
#define OP_SetNotFound        68

#define OP_MakeRecord         69
#define OP_MakeKey            70







|







 







<
|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150
151
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.47 2002/02/27 19:00:22 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................

#define OP_AggReset           58
#define OP_AggFocus           59
#define OP_AggIncr            60
#define OP_AggNext            61
#define OP_AggSet             62
#define OP_AggGet             63

#define OP_AggFunc            64
#define OP_AggInit            65

#define OP_SetInsert          66
#define OP_SetFound           67
#define OP_SetNotFound        68

#define OP_MakeRecord         69
#define OP_MakeKey            70