/ Check-in [c490a1ff]
Login
Overview
Comment:Added support for user-defined normal functions. Support for user-defined aggregates is pending. (CVS 390)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:c490a1ff951c5d4a2de8e4f8d349189bfaef7f74
User & Date: drh 2002-02-23 23:45:45
Context
2002-02-24
01:55
Move the build-in function definitions into a new source file "func.c". (CVS 391) check-in: 530b0f4f user: drh tags: trunk
2002-02-23
23:45
Added support for user-defined normal functions. Support for user-defined aggregates is pending. (CVS 390) check-in: c490a1ff user: drh tags: trunk
19:39
Modify lemon to use much less memory for its parser tables. This reduces the size of the library by 50K, which is important for an embedded library. (CVS 389) check-in: 67a135a0 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
...
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
...
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
...
881
882
883
884
885
886
887












888
889
890
891
892
893
894
....
1241
1242
1243
1244
1245
1246
1247

















































**    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.42 2002/02/23 02:32:10 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
................................................................................
  switch( pExpr->op ){
    case TK_FUNCTION: {
      int id = sqliteFuncId(&pExpr->token);
      int n = pExpr->pList ? pExpr->pList->nExpr : 0;
      int no_such_func = 0;
      int too_many_args = 0;
      int too_few_args = 0;

      int is_agg = 0;
      int i;
      pExpr->iColumn = id;
      switch( id ){
        case FN_Unknown: { 






          no_such_func = 1;






          break;
        }
        case FN_Count: { 
          no_such_func = !allowAgg;
          too_many_args = n>1;
          is_agg = 1;
          break;
        }
        case FN_Max:
        case FN_Min: {
          too_few_args = allowAgg ? n<1 : n<2;
          is_agg = n==1;
          break;
        }
        case FN_Avg:
        case FN_Sum: {
          no_such_func = !allowAgg;
          too_many_args = n>1;
          too_few_args = n<1;
          is_agg = 1;
          break;
        }
        case FN_Abs:
        case FN_Length: {
................................................................................
        case FN_Substr: {
          too_few_args = n<3;
          too_many_args = n>3;
          break;
        }
        default: break;
      }






      if( no_such_func ){
        sqliteSetNString(&pParse->zErrMsg, "no such function: ", -1,
           pExpr->token.z, pExpr->token.n, 0);
        pParse->nErr++;
        nErr++;
      }else if( too_many_args ){
        sqliteSetNString(&pParse->zErrMsg, "too many arguments to function ",-1,
           pExpr->token.z, pExpr->token.n, "()", 2, 0);
        pParse->nErr++;
        nErr++;
      }else if( too_few_args ){
        sqliteSetNString(&pParse->zErrMsg, "too few arguments to function ",-1,
           pExpr->token.z, pExpr->token.n, "()", 2, 0);
        pParse->nErr++;






        nErr++;
      }
      if( is_agg ) pExpr->op = TK_AGG_FUNCTION;
      if( is_agg && pIsAgg ) *pIsAgg = 1;
      for(i=0; nErr==0 && i<n; i++){
        nErr = sqliteExprCheck(pParse, pExpr->pList->a[i].pExpr,
                               allowAgg && !is_agg, pIsAgg);
................................................................................
        }
        case FN_Substr: {
          for(i=0; i<pList->nExpr; i++){
            sqliteExprCode(pParse, pList->a[i].pExpr);
          }
          sqliteVdbeAddOp(v, OP_Substr, 0, 0);
          break;












        }
        default: {
          /* Can't happen! */
          break;
        }
      }
      break;
................................................................................
        }
      }
      break;
    }
  }
  return nErr;
}
























































|







 







>




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



<






|





<







 







>
>
>
>
>
>
|













>
>
>
>
>
>







 







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







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
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
...
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
...
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
....
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
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
**    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.43 2002/02/23 23:45:45 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
................................................................................
  switch( pExpr->op ){
    case TK_FUNCTION: {
      int id = sqliteFuncId(&pExpr->token);
      int n = pExpr->pList ? pExpr->pList->nExpr : 0;
      int no_such_func = 0;
      int too_many_args = 0;
      int too_few_args = 0;
      int wrong_num_args = 0;
      int is_agg = 0;
      int i;
      pExpr->iColumn = id;
      switch( id ){
        case FN_Unknown: {
          UserFunc *pUser = sqliteFindUserFunction(pParse->db,
             pExpr->token.z, pExpr->token.n, n, 0);
          if( pUser==0 ){
            pUser = sqliteFindUserFunction(pParse->db,
               pExpr->token.z, pExpr->token.n, -1, 0);
            if( pUser==0 ){
              no_such_func = 1;
            }else{
              wrong_num_args = 1;
            }
          }else{
            is_agg = pUser->xFunc==0;
          }
          break;
        }
        case FN_Count: { 

          too_many_args = n>1;
          is_agg = 1;
          break;
        }
        case FN_Max:
        case FN_Min: {
          too_few_args = n<1;
          is_agg = n==1;
          break;
        }
        case FN_Avg:
        case FN_Sum: {

          too_many_args = n>1;
          too_few_args = n<1;
          is_agg = 1;
          break;
        }
        case FN_Abs:
        case FN_Length: {
................................................................................
        case FN_Substr: {
          too_few_args = n<3;
          too_many_args = n>3;
          break;
        }
        default: break;
      }
      if( is_agg && !allowAgg ){
        sqliteSetNString(&pParse->zErrMsg, "misuse of aggregate function ", -1,
           pExpr->token.z, pExpr->token.n, "()", 2, 0);
        pParse->nErr++;
        nErr++;
        is_agg = 0;
      }else if( no_such_func ){
        sqliteSetNString(&pParse->zErrMsg, "no such function: ", -1,
           pExpr->token.z, pExpr->token.n, 0);
        pParse->nErr++;
        nErr++;
      }else if( too_many_args ){
        sqliteSetNString(&pParse->zErrMsg, "too many arguments to function ",-1,
           pExpr->token.z, pExpr->token.n, "()", 2, 0);
        pParse->nErr++;
        nErr++;
      }else if( too_few_args ){
        sqliteSetNString(&pParse->zErrMsg, "too few arguments to function ",-1,
           pExpr->token.z, pExpr->token.n, "()", 2, 0);
        pParse->nErr++;
        nErr++;
      }else if( wrong_num_args ){
        sqliteSetNString(&pParse->zErrMsg, 
           "wrong number of arguments to function ",-1,
           pExpr->token.z, pExpr->token.n, "()", 2, 0);
        pParse->nErr++;
        nErr++;
      }
      if( is_agg ) pExpr->op = TK_AGG_FUNCTION;
      if( is_agg && pIsAgg ) *pIsAgg = 1;
      for(i=0; nErr==0 && i<n; i++){
        nErr = sqliteExprCheck(pParse, pExpr->pList->a[i].pExpr,
                               allowAgg && !is_agg, pIsAgg);
................................................................................
        }
        case FN_Substr: {
          for(i=0; i<pList->nExpr; i++){
            sqliteExprCode(pParse, pList->a[i].pExpr);
          }
          sqliteVdbeAddOp(v, OP_Substr, 0, 0);
          break;
        }
        case FN_Unknown: {
          UserFunc *pUser;
          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;
        }
      }
      break;
................................................................................
        }
      }
      break;
    }
  }
  return nErr;
}

/*
** Locate a user function given a name and a number of arguments.
** Return a pointer to the UserFunc structure that defines that
** function, or return NULL if the function does not exist.
**
** If the createFlag argument is true, then a new (blank) UserFunc
** structure is created and liked into the "db" structure if a
** no matching function previously existed.  When createFlag is true
** and the nArg parameter is -1, then only a function that accepts
** any number of arguments will be returned.
**
** If createFlag is false and nArg is -1, then the first valid
** function found is returned.  A function is valid if either xFunc
** or xStep is non-zero.
*/
UserFunc *sqliteFindUserFunction(
  sqlite *db,        /* An open database */
  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( !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;
  }
  if( p && !createFlag && p->xFunc==0 && p->xStep==0 ){
    return 0;
  }
  if( p==0 && pMaybe ){
    assert( createFlag==0 );
    return pMaybe;
  }
  if( p==0 && createFlag ){
    p = sqliteMalloc( sizeof(*p) );
    p->nArg = nArg;
    p->pNext = pFirst;
    sqliteHashInsert(&db->userFunc, zName, nName, (void*)p);
  }
  return p;
}

Changes to src/hash.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
...
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.6 2002/01/14 09:28:20 drh Exp $
*/
#include "sqliteInt.h"
#include <assert.h>

/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**
................................................................................
** new data replaces the old data and the old data is returned.
** The key is not copied in this instance.  If a malloc fails, then
** the new data is returned and the hash table is unchanged.
**
** If the "data" parameter to this function is NULL, then the
** element corresponding to "key" is removed from the hash table.
*/
void *sqliteHashInsert(Hash *pH, void *pKey, int nKey, void *data){
  int hraw;             /* Raw hash value of the key */
  int h;                /* the hash of the key modulo hash table size */
  HashElem *elem;       /* Used to loop thru the element list */
  HashElem *new_elem;   /* New element added to the pH */
  int (*xHash)(const void*,int);  /* The hash function */

  assert( pH!=0 );
................................................................................
    new_elem->pKey = sqliteMalloc( nKey );
    if( new_elem->pKey==0 ){
      sqliteFree(new_elem);
      return data;
    }
    memcpy((void*)new_elem->pKey, pKey, nKey);
  }else{
    new_elem->pKey = pKey;
  }
  new_elem->nKey = nKey;
  pH->count++;
  if( pH->htsize==0 ) rehash(pH,8);
  if( pH->htsize==0 ){
    pH->count = 0;
    sqliteFree(new_elem);







|







 







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
...
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the implementation of generic hash-tables
** used in SQLite.
**
** $Id: hash.c,v 1.7 2002/02/23 23:45:45 drh Exp $
*/
#include "sqliteInt.h"
#include <assert.h>

/* Turn bulk memory into a hash table object by initializing the
** fields of the Hash structure.
**
................................................................................
** new data replaces the old data and the old data is returned.
** The key is not copied in this instance.  If a malloc fails, then
** the new data is returned and the hash table is unchanged.
**
** If the "data" parameter to this function is NULL, then the
** element corresponding to "key" is removed from the hash table.
*/
void *sqliteHashInsert(Hash *pH, const void *pKey, int nKey, void *data){
  int hraw;             /* Raw hash value of the key */
  int h;                /* the hash of the key modulo hash table size */
  HashElem *elem;       /* Used to loop thru the element list */
  HashElem *new_elem;   /* New element added to the pH */
  int (*xHash)(const void*,int);  /* The hash function */

  assert( pH!=0 );
................................................................................
    new_elem->pKey = sqliteMalloc( nKey );
    if( new_elem->pKey==0 ){
      sqliteFree(new_elem);
      return data;
    }
    memcpy((void*)new_elem->pKey, pKey, nKey);
  }else{
    new_elem->pKey = (const void*)pKey;
  }
  new_elem->nKey = nKey;
  pH->count++;
  if( pH->htsize==0 ) rehash(pH,8);
  if( pH->htsize==0 ){
    pH->count = 0;
    sqliteFree(new_elem);

Changes to src/hash.h.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the header file for the generic hash-table implemenation
** used in SQLite.
**
** $Id: hash.h,v 1.3 2002/02/03 03:34:09 drh Exp $
*/
#ifndef _SQLITE_HASH_H_
#define _SQLITE_HASH_H_

/* Forward declarations of structures. */
typedef struct Hash Hash;
typedef struct HashElem HashElem;
................................................................................
#define SQLITE_HASH_STRING    3
#define SQLITE_HASH_BINARY    4

/*
** Access routines.  To delete, insert a NULL pointer.
*/
void sqliteHashInit(Hash*, int keytype, int copyKey);
void *sqliteHashInsert(Hash*, void *pKey, int nKey, void *pData);
void *sqliteHashFind(const Hash*, const void *pKey, int nKey);
void sqliteHashClear(Hash*);

/*
** Macros for looping over all elements of a hash table.  The idiom is
** like this:
**







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This is the header file for the generic hash-table implemenation
** used in SQLite.
**
** $Id: hash.h,v 1.4 2002/02/23 23:45:45 drh Exp $
*/
#ifndef _SQLITE_HASH_H_
#define _SQLITE_HASH_H_

/* Forward declarations of structures. */
typedef struct Hash Hash;
typedef struct HashElem HashElem;
................................................................................
#define SQLITE_HASH_STRING    3
#define SQLITE_HASH_BINARY    4

/*
** Access routines.  To delete, insert a NULL pointer.
*/
void sqliteHashInit(Hash*, int keytype, int copyKey);
void *sqliteHashInsert(Hash*, const void *pKey, int nKey, void *pData);
void *sqliteHashFind(const Hash*, const void *pKey, int nKey);
void sqliteHashClear(Hash*);

/*
** Macros for looping over all elements of a hash table.  The idiom is
** like this:
**

Changes to src/main.c.

10
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
...
287
288
289
290
291
292
293
























294
295
296
297
298
299
300
...
309
310
311
312
313
314
315



316
317
318
319
320
321
322
...
404
405
406
407
408
409
410

411
412
413
414
415








416
417
418
419
420
421
422
...
609
610
611
612
613
614
615












































**
*************************************************************************
** 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.61 2002/02/21 12:01:27 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.
**
................................................................................
** following global constant always lets us know.
*/
#ifdef SQLITE_UTF8
const char sqlite_encoding[] = "UTF-8";
#else
const char sqlite_encoding[] = "iso8859";
#endif

























/*
** Open a new SQLite database.  Construct an "sqlite" structure to define
** the state of this database and return a pointer to that structure.
**
** An attempt is made to initialize the in-memory data structures that
** hold the database schema.  But if this fails (because the schema file
................................................................................
  db = sqliteMalloc( sizeof(sqlite) );
  if( pzErrMsg ) *pzErrMsg = 0;
  if( db==0 ) goto no_mem_on_open;
  sqliteHashInit(&db->tblHash, SQLITE_HASH_STRING, 0);
  sqliteHashInit(&db->idxHash, SQLITE_HASH_STRING, 0);
  sqliteHashInit(&db->tblDrop, SQLITE_HASH_POINTER, 0);
  sqliteHashInit(&db->idxDrop, SQLITE_HASH_POINTER, 0);



  db->onError = OE_Default;
  db->priorNewRowid = 0;
  
  /* Open the backend database driver */
  rc = sqliteBtreeOpen(zFilename, mode, MAX_PAGES, &db->pBe);
  if( rc!=SQLITE_OK ){
    switch( rc ){
................................................................................
  return db->lastRowid;
}

/*
** Close an existing SQLite database
*/
void sqlite_close(sqlite *db){

  sqliteBtreeClose(db->pBe);
  clearHashTable(db, 0);
  if( db->pBeTemp ){
    sqliteBtreeClose(db->pBeTemp);
  }








  sqliteFree(db);
}

/*
** Return TRUE if the given SQL string ends in a semicolon.
*/
int sqlite_complete(const char *zSql){
................................................................................

/*
** Windows systems need functions to call to return the sqlite_version
** and sqlite_encoding strings.
*/
const char *sqlite_libversion(void){ return sqlite_version; }
const char *sqlite_libencoding(void){ return sqlite_encoding; }



















































|

>







 







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







 







>
>
>







 







>





>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
...
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
...
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
...
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
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
**
*************************************************************************
** 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.62 2002/02/23 23:45:45 drh Exp $
*/
#include <ctype.h>
#include "sqliteInt.h"
#include "os.h"

/*
** This is the callback routine for the code that initializes the
** database.  See sqliteInit() below for additional information.
**
................................................................................
** following global constant always lets us know.
*/
#ifdef SQLITE_UTF8
const char sqlite_encoding[] = "UTF-8";
#else
const char sqlite_encoding[] = "iso8859";
#endif

/*
** 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]);
  }
}

/*
** Open a new SQLite database.  Construct an "sqlite" structure to define
** the state of this database and return a pointer to that structure.
**
** An attempt is made to initialize the in-memory data structures that
** hold the database schema.  But if this fails (because the schema file
................................................................................
  db = sqliteMalloc( sizeof(sqlite) );
  if( pzErrMsg ) *pzErrMsg = 0;
  if( db==0 ) goto no_mem_on_open;
  sqliteHashInit(&db->tblHash, SQLITE_HASH_STRING, 0);
  sqliteHashInit(&db->idxHash, SQLITE_HASH_STRING, 0);
  sqliteHashInit(&db->tblDrop, SQLITE_HASH_POINTER, 0);
  sqliteHashInit(&db->idxDrop, SQLITE_HASH_POINTER, 0);
  sqliteHashInit(&db->userFunc, SQLITE_HASH_STRING, 1);
  sqlite_create_function(db, "upper", 1, upperFunc);
  sqlite_create_function(db, "lower", 1, lowerFunc);
  db->onError = OE_Default;
  db->priorNewRowid = 0;
  
  /* Open the backend database driver */
  rc = sqliteBtreeOpen(zFilename, mode, MAX_PAGES, &db->pBe);
  if( rc!=SQLITE_OK ){
    switch( rc ){
................................................................................
  return db->lastRowid;
}

/*
** Close an existing SQLite database
*/
void sqlite_close(sqlite *db){
  HashElem *i;
  sqliteBtreeClose(db->pBe);
  clearHashTable(db, 0);
  if( db->pBeTemp ){
    sqliteBtreeClose(db->pBeTemp);
  }
  for(i=sqliteHashFirst(&db->userFunc); i; i=sqliteHashNext(i)){
    UserFunc *pFunc, *pNext;
    for(pFunc = (UserFunc*)sqliteHashData(i); pFunc; pFunc=pNext){
      pNext = pFunc->pNext;
      sqliteFree(pFunc);
    }
  }
  sqliteHashClear(&db->userFunc);
  sqliteFree(db);
}

/*
** Return TRUE if the given SQL string ends in a semicolon.
*/
int sqlite_complete(const char *zSql){
................................................................................

/*
** Windows systems need functions to call to return the sqlite_version
** and sqlite_encoding strings.
*/
const char *sqlite_libversion(void){ return sqlite_version; }
const char *sqlite_libencoding(void){ return sqlite_encoding; }

/*
** Create new user-defined functions.  The sqlite_create_function()
** routine creates a regular function and sqlite_create_aggregate()
** creates an aggregate function.
**
** Passing a NULL xFunc argument or NULL xStep and xFinalize arguments
** disables the function.  Calling sqlite_create_function() with the
** same name and number of arguments as a prior call to
** sqlite_create_aggregate() disables the prior call to
** sqlite_create_aggregate(), and vice versa.
**
** 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);
  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);
  p->xFunc = 0;
  p->xStep = xStep;
  p->xFinalize = xFinalize;
  return 0;
}

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
**    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.25 2002/01/16 21:00:27 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 */
);




































#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
**    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_ */

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
...
154
155
156
157
158
159
160

161
162
163
164
165
166
167
...
172
173
174
175
176
177
178

179
180
181
182
183
184
185
...
194
195
196
197
198
199
200
201



202
203







204
205
206
207
208
209
210
...
630
631
632
633
634
635
636

**    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.90 2002/02/23 02:32:10 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
................................................................................
** an array.
*/
#define ArraySize(X)    (sizeof(X)/sizeof(X[0]))

/*
** Integer identifiers for built-in SQL functions.
*/
#define FN_Unknown    0
#define FN_Count      1
#define FN_Min        2
#define FN_Max        3
#define FN_Sum        4
#define FN_Avg        5
#define FN_Fcnt       6
#define FN_Length     7
................................................................................
typedef struct Parse Parse;
typedef struct Token Token;
typedef struct IdList IdList;
typedef struct WhereInfo WhereInfo;
typedef struct WhereLevel WhereLevel;
typedef struct Select Select;
typedef struct AggExpr AggExpr;


/*
** Each database is an instance of the following structure
*/
struct sqlite {
  Btree *pBe;                   /* The B*Tree backend */
  Btree *pBeTemp;               /* Backend for session temporary tables */
................................................................................
  int nTable;                   /* Number of tables in the database */
  void *pBusyArg;               /* 1st Argument to the busy callback */
  int (*xBusyCallback)(void *,const char*,int);  /* The busy callback */
  Hash tblHash;                 /* All tables indexed by name */
  Hash idxHash;                 /* All (named) indices indexed by name */
  Hash tblDrop;                 /* Uncommitted DROP TABLEs */
  Hash idxDrop;                 /* Uncommitted DROP INDEXs */

  int lastRowid;                /* ROWID of most recent insert */
  int priorNewRowid;            /* Last randomly generated ROWID */
  int onError;                  /* Default conflict algorithm */
};

/*
** Possible values for the sqlite.flags.
................................................................................
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000080  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_ResultDetails  0x00000100  /* Details added to result set */

/*
** Current file format version



*/
#define SQLITE_FileFormat 2








/*
** information about each column of an SQL table is held in an instance
** of this structure.
*/
struct Column {
  char *zName;     /* Name of this column */
................................................................................
void sqliteCompleteInsertion(Parse*, Table*, int, char*, int, int);
void sqliteBeginWriteOperation(Parse*);
void sqliteBeginMultiWriteOperation(Parse*);
void sqliteEndWriteOperation(Parse*);
void sqliteExprMoveStrings(Expr*, int);
void sqliteExprListMoveStrings(ExprList*, int);
void sqliteSelectMoveStrings(Select*, int);








|







 







|







 







>







 







>







 







|
>
>
>

<
>
>
>
>
>
>
>







 







>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
...
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
...
196
197
198
199
200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
215
216
217
218
219
220
221
...
641
642
643
644
645
646
647
648
**    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.91 2002/02/23 23:45:45 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
................................................................................
** an array.
*/
#define ArraySize(X)    (sizeof(X)/sizeof(X[0]))

/*
** Integer identifiers for built-in SQL functions.
*/
#define FN_Unknown    0      /* Not a built-in.  Might be user defined */
#define FN_Count      1
#define FN_Min        2
#define FN_Max        3
#define FN_Sum        4
#define FN_Avg        5
#define FN_Fcnt       6
#define FN_Length     7
................................................................................
typedef struct Parse Parse;
typedef struct Token Token;
typedef struct IdList IdList;
typedef struct WhereInfo WhereInfo;
typedef struct WhereLevel WhereLevel;
typedef struct Select Select;
typedef struct AggExpr AggExpr;
typedef struct UserFunc UserFunc;

/*
** Each database is an instance of the following structure
*/
struct sqlite {
  Btree *pBe;                   /* The B*Tree backend */
  Btree *pBeTemp;               /* Backend for session temporary tables */
................................................................................
  int nTable;                   /* Number of tables in the database */
  void *pBusyArg;               /* 1st Argument to the busy callback */
  int (*xBusyCallback)(void *,const char*,int);  /* The busy callback */
  Hash tblHash;                 /* All tables indexed by name */
  Hash idxHash;                 /* All (named) indices indexed by name */
  Hash tblDrop;                 /* Uncommitted DROP TABLEs */
  Hash idxDrop;                 /* Uncommitted DROP INDEXs */
  Hash userFunc;                /* User defined functions */
  int lastRowid;                /* ROWID of most recent insert */
  int priorNewRowid;            /* Last randomly generated ROWID */
  int onError;                  /* Default conflict algorithm */
};

/*
** Possible values for the sqlite.flags.
................................................................................
                                          /*   DELETE, or UPDATE and return */
                                          /*   the count using a callback. */
#define SQLITE_NullCallback   0x00000080  /* Invoke the callback once if the */
                                          /*   result set is empty */
#define SQLITE_ResultDetails  0x00000100  /* Details added to result set */

/*
** 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 {
  char *zName;     /* Name of this column */
................................................................................
void sqliteCompleteInsertion(Parse*, Table*, int, char*, int, int);
void sqliteBeginWriteOperation(Parse*);
void sqliteBeginMultiWriteOperation(Parse*);
void sqliteEndWriteOperation(Parse*);
void sqliteExprMoveStrings(Expr*, int);
void sqliteExprListMoveStrings(ExprList*, int);
void sqliteSelectMoveStrings(Select*, int);
UserFunc *sqliteFindUserFunction(sqlite*,const char*,int,int,int);

Changes to src/table.c.

13
14
15
16
17
18
19

20
21
22
23
24
25
26
** interface routines.  These are just wrappers around the main
** interface routine of sqlite_exec().
**
** These routines are in a separate files so that they will not be linked
** if they are not used.
*/
#include <stdlib.h>

#include "sqlite.h"

/*
** This structure is used to pass data from sqlite_get_table() through
** to the callback function is uses to build the result.
*/
typedef struct TabResult {







>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
** interface routines.  These are just wrappers around the main
** interface routine of sqlite_exec().
**
** These routines are in a separate files so that they will not be linked
** if they are not used.
*/
#include <stdlib.h>
#include <string.h>
#include "sqlite.h"

/*
** This structure is used to pass data from sqlite_get_table() through
** to the callback function is uses to build the result.
*/
typedef struct TabResult {

Changes to src/vdbe.c.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
134
135
136
137
138
139
140










141
142
143
144
145
146
147
...
487
488
489
490
491
492
493



































































494
495
496
497
498
499
500
...
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
....
1689
1690
1691
1692
1693
1694
1695









































1696
1697
1698
1699
1700
1701
1702
** 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.121 2002/02/21 12:01:27 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_Null      0x0001   /* Value is NULL */
#define STK_Str       0x0002   /* Value is a string */
#define STK_Int       0x0004   /* Value is an integer */
#define STK_Real      0x0008   /* Value is a real number */
#define STK_Dyn       0x0010   /* Need to call sqliteFree() on zStack[*] */
#define STK_Static    0x0020   /* zStack[] points to a static string */











/*
** 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.
*/
................................................................................
    }else{
      z[j++] = z[i++];
    }
  }
  while( j>0 && isspace(z[j-1]) ){ j--; }
  z[j] = 0;
}




































































/*
** Reset an Agg structure.  Delete all its contents.
*/
static void AggReset(Agg *pAgg){
  int i;
  HashElem *p;
................................................................................
  "Divide",            "Remainder",         "BitAnd",            "BitOr",
  "BitNot",            "ShiftLeft",         "ShiftRight",        "AbsValue",
  "Precision",         "Min",               "Max",               "Like",
  "Glob",              "Eq",                "Ne",                "Lt",
  "Le",                "Gt",                "Ge",                "IsNull",
  "NotNull",           "Negative",          "And",               "Or",
  "Not",               "Concat",            "Noop",              "Strlen",
  "Substr",            "Limit",           
};

/*
** Given the name of an opcode, return its number.  Return 0 if
** there is no match.
**
** This routine is used for testing and debugging.
................................................................................
    aStack[tos].flags = 0;
  }else{
    Release(p, tos);
  }
  p->tos = nos;
  break;
}










































/* Opcode: BitAnd * * *
**
** Pop the top two elements from the stack.  Convert both elements
** to integers.  Push back onto the stack the bit-wise AND of the
** two elements.
*/







|







 







>
>
>
>
>
>
>
>
>
>







 







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







 







|







 







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







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
...
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
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
...
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
....
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
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
1816
1817
1818
1819
1820
** 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.122 2002/02/23 23:45:45 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_Null      0x0001   /* Value is NULL */
#define STK_Str       0x0002   /* Value is a string */
#define STK_Int       0x0004   /* Value is an integer */
#define STK_Real      0x0008   /* Value is a real number */
#define STK_Dyn       0x0010   /* Need to call sqliteFree() on zStack[*] */
#define STK_Static    0x0020   /* zStack[] points to a static string */

/*
** 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.
*/
................................................................................
    }else{
      z[j++] = z[i++];
    }
  }
  while( j>0 && isspace(z[j-1]) ){ j--; }
  z[j] = 0;
}

/*
** The following group or routines are employed by user-defined functions
** to return their results.
**
** The sqlite_set_result_string() routine can be used to return a string
** value or to return a NULL.  To return a NULL, pass in NULL for zResult.
** A copy is made of the string before this routine returns so it is safe
** to pass in a ephemeral string.
**
** 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;
  }else{
    if( n<0 ) n = strlen(zResult);
    if( n<NBFS-1 ){
      memcpy(p->s.z, zResult, n);
      p->s.z[n] = 0;
      p->s.flags = STK_Str;
      p->z = p->s.z;
    }else{
      p->z = sqliteMalloc( n+1 );
      if( p->z ){
        memcpy(p->z, zResult, n);
        p->z[n] = 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;
................................................................................
  "Divide",            "Remainder",         "BitAnd",            "BitOr",
  "BitNot",            "ShiftLeft",         "ShiftRight",        "AbsValue",
  "Precision",         "Min",               "Max",               "Like",
  "Glob",              "Eq",                "Ne",                "Lt",
  "Le",                "Gt",                "Ge",                "IsNull",
  "NotNull",           "Negative",          "And",               "Or",
  "Not",               "Concat",            "Noop",              "Strlen",
  "Substr",            "UserFunc",          "UserAgg",           "Limit",
};

/*
** Given the name of an opcode, return its number.  Return 0 if
** there is no match.
**
** This routine is used for testing and debugging.
................................................................................
    aStack[tos].flags = 0;
  }else{
    Release(p, tos);
  }
  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 ){
    zStack[p->tos] = aStack[p->tos].z;
  }else{
    zStack[p->tos] = 0;
  }
  if( ctx.isError ){
    sqliteSetString(pzErrMsg, 
       zStack[p->tos] ? zStack[p->tos] : "user function error", 0);
    rc = SQLITE_ERROR;
  }
  break;
}

/* Opcode: BitAnd * * *
**
** Pop the top two elements from the stack.  Convert both elements
** to integers.  Push back onto the stack the bit-wise AND of the
** two elements.
*/

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
194
195
196
197
198
199
200
201
202
203


204
205
206
207
208
209
210
211
212
213
214
*************************************************************************
** 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.44 2002/02/21 12:01:28 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_NotNull           109
#define OP_Negative          110
#define OP_And               111
#define OP_Or                112
#define OP_Not               113
#define OP_Concat            114
#define OP_Noop              115

#define OP_Strlen            116
#define OP_Substr            117



#define OP_Limit             118

#define OP_MAX               118

/*
** Prototypes for the VDBE interface.  See comments on the implementation
** for a description of what each of these routines does.
*/
Vdbe *sqliteVdbeCreate(sqlite*);
void sqliteVdbeCreateCallback(Vdbe*, int*);







|







 







<


>
>

|

|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
*************************************************************************
** 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.45 2002/02/23 23:45:46 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_NotNull           109
#define OP_Negative          110
#define OP_And               111
#define OP_Or                112
#define OP_Not               113
#define OP_Concat            114
#define OP_Noop              115

#define OP_Strlen            116
#define OP_Substr            117
#define OP_UserFunc          118
#define OP_UserAgg           119

#define OP_Limit             120

#define OP_MAX               120

/*
** Prototypes for the VDBE interface.  See comments on the implementation
** for a description of what each of these routines does.
*/
Vdbe *sqliteVdbeCreate(sqlite*);
void sqliteVdbeCreateCallback(Vdbe*, int*);

Changes to test/select1.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SELECT statement.
#
# $Id: select1.test,v 1.18 2002/01/22 14:11:30 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Try to select on a non-existant table.
#
do_test select1-1.1 {
................................................................................
do_test select1-2.19 {
  set v [catch {execsql {SELECT SUM(min(f1,f2)) FROM test1}} msg]
  lappend v $msg
} {0 44}
do_test select1-2.20 {
  set v [catch {execsql {SELECT SUM(min(f1)) FROM test1}} msg]
  lappend v $msg
} {1 {too few arguments to function min()}}

# WHERE clause expressions
#
do_test select1-3.1 {
  set v [catch {execsql {SELECT f1 FROM test1 WHERE f1<11}} msg]
  lappend v $msg
} {0 {}}
................................................................................
do_test select1-3.8 {
  set v [catch {execsql {SELECT f1 FROM test1 WHERE max(f1,f2)!=11}} msg]
  lappend v [lsort $msg]
} {0 {11 33}}
do_test select1-3.9 {
  set v [catch {execsql {SELECT f1 FROM test1 WHERE count(f1,f2)!=11}} msg]
  lappend v $msg
} {1 {no such function: count}}

# ORDER BY expressions
#
do_test select1-4.1 {
  set v [catch {execsql {SELECT f1 FROM test1 ORDER BY f1}} msg]
  lappend v $msg
} {0 {11 33}}
................................................................................
do_test select1-4.3 {
  set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1,f2)}} msg]
  lappend v $msg
} {0 {11 33}}
do_test select1-4.4 {
  set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1)}} msg]
  lappend v $msg
} {1 {too few arguments to function min()}}
do_test select1-4.5 {
  catchsql {
    SELECT f1 FROM test1 ORDER BY 8.4;
  }
} {1 {ORDER BY expressions should not be constant}}

# ORDER BY ignored on an aggregate query







|







 







|







 







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SELECT statement.
#
# $Id: select1.test,v 1.19 2002/02/23 23:45:47 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Try to select on a non-existant table.
#
do_test select1-1.1 {
................................................................................
do_test select1-2.19 {
  set v [catch {execsql {SELECT SUM(min(f1,f2)) FROM test1}} msg]
  lappend v $msg
} {0 44}
do_test select1-2.20 {
  set v [catch {execsql {SELECT SUM(min(f1)) FROM test1}} msg]
  lappend v $msg
} {1 {misuse of aggregate function min()}}

# WHERE clause expressions
#
do_test select1-3.1 {
  set v [catch {execsql {SELECT f1 FROM test1 WHERE f1<11}} msg]
  lappend v $msg
} {0 {}}
................................................................................
do_test select1-3.8 {
  set v [catch {execsql {SELECT f1 FROM test1 WHERE max(f1,f2)!=11}} msg]
  lappend v [lsort $msg]
} {0 {11 33}}
do_test select1-3.9 {
  set v [catch {execsql {SELECT f1 FROM test1 WHERE count(f1,f2)!=11}} msg]
  lappend v $msg
} {1 {misuse of aggregate function count()}}

# ORDER BY expressions
#
do_test select1-4.1 {
  set v [catch {execsql {SELECT f1 FROM test1 ORDER BY f1}} msg]
  lappend v $msg
} {0 {11 33}}
................................................................................
do_test select1-4.3 {
  set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1,f2)}} msg]
  lappend v $msg
} {0 {11 33}}
do_test select1-4.4 {
  set v [catch {execsql {SELECT f1 FROM test1 ORDER BY min(f1)}} msg]
  lappend v $msg
} {1 {misuse of aggregate function min()}}
do_test select1-4.5 {
  catchsql {
    SELECT f1 FROM test1 ORDER BY 8.4;
  }
} {1 {ORDER BY expressions should not be constant}}

# ORDER BY ignored on an aggregate query

Changes to www/changes.tcl.

21
22
23
24
25
26
27



28
29
30
31
32
33
34
<li>Change the name of the sanity_check PRAGMA to <b>integrity_check</b>
    and make it available in all compiles.</li>
<li>SELECT min() or max() of an indexed column with no WHERE or GROUP BY
    clause is handled as a special case which avoids a complete table scan.</li>
<li>Automatically generated ROWIDs are now sequential.</li>
<li>Do not allow dot-commands of the command-line shell to occur in the
    middle of a real SQL command.</li>



}

chng {2002 Feb 18 (2.3.3)} {
<li>Allow identifiers to be quoted in square brackets, for compatibility
    with MS-Access.</li>
<li>Added support for sub-queries in the FROM clause of a SELECT.</li>
<li>More efficient implementation of sqliteFileExists() under Windows.







>
>
>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<li>Change the name of the sanity_check PRAGMA to <b>integrity_check</b>
    and make it available in all compiles.</li>
<li>SELECT min() or max() of an indexed column with no WHERE or GROUP BY
    clause is handled as a special case which avoids a complete table scan.</li>
<li>Automatically generated ROWIDs are now sequential.</li>
<li>Do not allow dot-commands of the command-line shell to occur in the
    middle of a real SQL command.</li>
<li>Modifications to the "lemon" parser generator so that the parser tables
    are 4 times smaller.</li>
<li>Added support for user-defined functions implemented in C.</li>
}

chng {2002 Feb 18 (2.3.3)} {
<li>Allow identifiers to be quoted in square brackets, for compatibility
    with MS-Access.</li>
<li>Added support for sub-queries in the FROM clause of a SELECT.</li>
<li>More efficient implementation of sqliteFileExists() under Windows.