/ Check-in [b00cf110]
Login

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

Overview
Comment:The new function code passes regression tests. (CVS 403)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:b00cf110b1cc671b7200a5ce8b9e704f660763c9
User & Date: drh 2002-02-28 03:04:48
Context
2002-02-28
03:14
Change the IFNULL and NVL functions to COALESCE. Change MIN and MAX so that they require at least one argument. (CVS 404) check-in: 7d86749d user: drh tags: trunk
03:04
The new function code passes regression tests. (CVS 403) check-in: b00cf110 user: drh tags: trunk
01:46
Fix the coredump. There are still problems in the test suite though. (CVS 402) check-in: 6af10cc5 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
...
648
649
650
651
652
653
654
655

656
657
658
659
660
661
662
...
850
851
852
853
854
855
856

857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
....
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
**    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.50 2002/02/28 01:46:12 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
................................................................................
      int n = pExpr->pList ? pExpr->pList->nExpr : 0;
      int no_such_func = 0;
      int wrong_num_args = 0;
      int is_agg = 0;
      int i;
      FuncDef *pDef;

      pDef = sqliteFindFunction(pParse->db, pExpr->token.z, pExpr->token.n,n,0);

      if( pDef==0 ){
        pDef = sqliteFindFunction(pParse->db,
           pExpr->token.z, pExpr->token.n, -1, 0);
        if( pDef==0 ){
          no_such_func = 1;
        }else{
          wrong_num_args = 1;
................................................................................
    case TK_AGG_FUNCTION: {
      sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
      break;
    }
    case TK_FUNCTION: {
      int i;
      ExprList *pList = pExpr->pList;

      FuncDef *pDef;
      pDef = sqliteFindFunction(pParse->db,
                      pExpr->token.z, pExpr->token.n, pList->nExpr, 0);
      assert( pDef!=0 );
      for(i=0; i<pList->nExpr; i++){
        sqliteExprCode(pParse, pList->a[i].pExpr);
      }
      sqliteVdbeAddOp(v, OP_Function, pList->nExpr, 0);
      sqliteVdbeChangeP3(v, -1, (char*)pDef, P3_POINTER);
      break;
    }
    case TK_SELECT: {
      sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
      break;
    }
................................................................................
  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->aFunc, zName, nName, (void*)p);
  }
  return p;
}







|







 







|
>







 







>


|

|


|







 







|
<






8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
...
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
....
1244
1245
1246
1247
1248
1249
1250
1251

1252
1253
1254
1255
1256
1257
**    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.51 2002/02/28 03:04:48 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
................................................................................
      int n = pExpr->pList ? pExpr->pList->nExpr : 0;
      int no_such_func = 0;
      int wrong_num_args = 0;
      int is_agg = 0;
      int i;
      FuncDef *pDef;

      pDef = sqliteFindFunction(pParse->db,
         pExpr->token.z, pExpr->token.n, n, 0);
      if( pDef==0 ){
        pDef = sqliteFindFunction(pParse->db,
           pExpr->token.z, pExpr->token.n, -1, 0);
        if( pDef==0 ){
          no_such_func = 1;
        }else{
          wrong_num_args = 1;
................................................................................
    case TK_AGG_FUNCTION: {
      sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
      break;
    }
    case TK_FUNCTION: {
      int i;
      ExprList *pList = pExpr->pList;
      int nExpr = pList ? pList->nExpr : 0;
      FuncDef *pDef;
      pDef = sqliteFindFunction(pParse->db,
                      pExpr->token.z, pExpr->token.n, nExpr, 0);
      assert( pDef!=0 );
      for(i=0; i<nExpr; i++){
        sqliteExprCode(pParse, pList->a[i].pExpr);
      }
      sqliteVdbeAddOp(v, OP_Function, nExpr, 0);
      sqliteVdbeChangeP3(v, -1, (char*)pDef, P3_POINTER);
      break;
    }
    case TK_SELECT: {
      sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
      break;
    }
................................................................................
  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)))!=0 ){

    p->nArg = nArg;
    p->pNext = pFirst;
    sqliteHashInsert(&db->aFunc, zName, nName, (void*)p);
  }
  return p;
}

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
47
48
49
50
51
52
...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
** 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.8 2002/02/28 01:46:13 drh Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "sqliteInt.h"

................................................................................
/*
** Implementation of the non-aggregate min() and max() functions
*/
static void minFunc(sqlite_func *context, int argc, const char **argv){
  const char *zBest; 
  int i;


  zBest = argv[0];
  for(i=1; i<argc; i++){
    if( sqliteCompare(argv[i], zBest)<0 ){
      zBest = argv[i];
    }
  }
  sqlite_set_result_string(context, zBest, -1);
}
static void maxFunc(sqlite_func *context, int argc, const char **argv){
  const char *zBest; 
  int i;


  zBest = argv[0];
  for(i=1; i<argc; i++){
    if( sqliteCompare(argv[i], zBest)>0 ){
      zBest = argv[i];
    }
  }
  sqlite_set_result_string(context, zBest, -1);
................................................................................
  p2 = atoi(argv[2]?argv[2]:0);
#ifdef SQLITE_UTF8
  for(len=0, z2=z; *z2; z2++){ if( (0xc0&*z)!=0x80 ) len++; }
#else
  len = strlen(z);
#endif
  if( p1<0 ){
    p1 = len-p1;
  }else if( p1>0 ){
    p1--;
  }
  if( p1+p2>len ){
    p2 = len-p1;
  }
#ifdef SQLITE_UTF8
................................................................................
  if( p==0 ) return;
  x = argv[0] ? atof(argv[0]) : 0.0;
  p->sum += x;
}
static void sumFinalize(sqlite_func *context){
  SumCtx *p;
  p = sqlite_aggregate_context(context, sizeof(*p));
  if( p ){
    sqlite_set_result_double(context, p->sum);
  }
}
static void avgFinalize(sqlite_func *context){
  SumCtx *p;
  double rN;
  p = sqlite_aggregate_context(context, sizeof(*p));
  rN = sqlite_aggregate_count(context);
  if( p && rN>0.0 ){







|







 







>












>







 







|







 







<
|
<







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
47
48
49
50
51
52
53
54
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
...
199
200
201
202
203
204
205

206

207
208
209
210
211
212
213
** 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.9 2002/02/28 03:04:48 drh Exp $
*/
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include "sqliteInt.h"

................................................................................
/*
** Implementation of the non-aggregate min() and max() functions
*/
static void minFunc(sqlite_func *context, int argc, const char **argv){
  const char *zBest; 
  int i;

  if( argc==0 ) return;
  zBest = argv[0];
  for(i=1; i<argc; i++){
    if( sqliteCompare(argv[i], zBest)<0 ){
      zBest = argv[i];
    }
  }
  sqlite_set_result_string(context, zBest, -1);
}
static void maxFunc(sqlite_func *context, int argc, const char **argv){
  const char *zBest; 
  int i;

  if( argc==0 ) return;
  zBest = argv[0];
  for(i=1; i<argc; i++){
    if( sqliteCompare(argv[i], zBest)>0 ){
      zBest = argv[i];
    }
  }
  sqlite_set_result_string(context, zBest, -1);
................................................................................
  p2 = atoi(argv[2]?argv[2]:0);
#ifdef SQLITE_UTF8
  for(len=0, z2=z; *z2; z2++){ if( (0xc0&*z)!=0x80 ) len++; }
#else
  len = strlen(z);
#endif
  if( p1<0 ){
    p1 += len;
  }else if( p1>0 ){
    p1--;
  }
  if( p1+p2>len ){
    p2 = len-p1;
  }
#ifdef SQLITE_UTF8
................................................................................
  if( p==0 ) return;
  x = argv[0] ? atof(argv[0]) : 0.0;
  p->sum += x;
}
static void sumFinalize(sqlite_func *context){
  SumCtx *p;
  p = sqlite_aggregate_context(context, sizeof(*p));

  sqlite_set_result_double(context, p ? p->sum : 0.0);

}
static void avgFinalize(sqlite_func *context){
  SumCtx *p;
  double rN;
  p = sqlite_aggregate_context(context, sizeof(*p));
  rN = sqlite_aggregate_count(context);
  if( p && rN>0.0 ){

Changes to src/vdbe.c.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
548
549
550
551
552
553
554

555
556
557
558
559
560
561
...
563
564
565
566
567
568
569

570
571
572
573
574
575
576
577
578
....
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
** 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.127 2002/02/28 01:46:13 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
................................................................................
  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;
................................................................................
      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(sqlite_func *p, int iResult){
  assert( !p->isStep );
  if( p->s.flags & STK_Dyn ){
    sqliteFree(p->z);
  }
................................................................................
** See also: AggFunc
*/
case OP_Function: {
  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 = (FuncDef*)pOp->p3;







|







 







>







 







>

<







 







|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
...
564
565
566
567
568
569
570
571
572

573
574
575
576
577
578
579
....
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
** 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.128 2002/02/28 03:04:48 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
................................................................................
  if( p->s.flags & STK_Dyn ){
    sqliteFree(p->z);
  }
  if( zResult==0 ){
    p->s.flags = STK_Null;
    n = 0;
    p->z = 0;
    p->s.n = 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;
................................................................................
      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+1;
  }

  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);
  }
................................................................................
** See also: AggFunc
*/
case OP_Function: {
  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 = (FuncDef*)pOp->p3;

Changes to test/func.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
158
159
160
161
162
163
164
165
166
167
#    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 built-in functions.
#
# $Id: func.test,v 1.7 2001/12/22 14:49:26 drh Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
#
do_test func-1.0 {
  execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
} {4 2 7 8 4}
do_test func-1.1 {
  set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg]
  lappend r $msg
} {1 {too few arguments to function length()}}
do_test func-1.2 {
  set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg]
  lappend r $msg
} {1 {too many arguments to function length()}}
do_test func-1.3 {
  execsql {SELECT length(t1), count(*) FROM tbl1 GROUP BY length(t1)
           ORDER BY length(t1)}
} {2 1 4 2 7 1 8 1}

# Check out the substr() function
#
................................................................................
  execsql {
    CREATE TABLE t1(a,b,c);
    INSERT INTO t1 VALUES(1,2,3);
    INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890);
    INSERT INTO t1 VALUES(3,-2,-5);
  }
  catchsql {SELECT abs(a,b) FROM t1}
} {1 {too many arguments to function abs()}}
do_test func-4.2 {
  catchsql {SELECT abs() FROM t1}
} {1 {too few arguments to function abs()}}
do_test func-4.3 {
  catchsql {SELECT abs(b) FROM t1 ORDER BY a}
} {0 {2 1.2345678901234 2}}
do_test func-4.4 {
  catchsql {SELECT abs(c) FROM t1 ORDER BY a}
} {0 {3 12345.6789 5}}

do_test func-4.5 {
  catchsql {SELECT round(a,b,c) FROM t1}
} {1 {too many arguments to function round()}}
do_test func-4.6 {
  catchsql {SELECT round(b,2) FROM t1 ORDER BY b}
} {0 {-2.00 1.23 2.00}}
do_test func-4.7 {
  catchsql {SELECT round(b,0) FROM t1 ORDER BY a}
} {0 {2 1 -2}}
do_test func-4.8 {
................................................................................
  catchsql {SELECT round(c,a) FROM t1 ORDER BY a}
} {0 {3.0 -12345.68 -5.000}}
do_test func-4.10 {
  catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a}
} {0 {x3.0y x-12345.68y x-5.000y}}
do_test func-4.11 {
  catchsql {SELECT round() FROM t1 ORDER BY a}
} {1 {too few arguments to function round()}}

finish_test







|







 







|



|







 







|


|





|



|







 







|


7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
158
159
160
161
162
163
164
165
166
167
#    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 built-in functions.
#
# $Id: func.test,v 1.8 2002/02/28 03:04:48 drh Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
................................................................................
#
do_test func-1.0 {
  execsql {SELECT length(t1) FROM tbl1 ORDER BY t1}
} {4 2 7 8 4}
do_test func-1.1 {
  set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg]
  lappend r $msg
} {1 {wrong number of arguments to function length()}}
do_test func-1.2 {
  set r [catch {execsql {SELECT length(t1,5) FROM tbl1 ORDER BY t1}} msg]
  lappend r $msg
} {1 {wrong number of arguments to function length()}}
do_test func-1.3 {
  execsql {SELECT length(t1), count(*) FROM tbl1 GROUP BY length(t1)
           ORDER BY length(t1)}
} {2 1 4 2 7 1 8 1}

# Check out the substr() function
#
................................................................................
  execsql {
    CREATE TABLE t1(a,b,c);
    INSERT INTO t1 VALUES(1,2,3);
    INSERT INTO t1 VALUES(2,1.2345678901234,-12345.67890);
    INSERT INTO t1 VALUES(3,-2,-5);
  }
  catchsql {SELECT abs(a,b) FROM t1}
} {1 {wrong number of arguments to function abs()}}
do_test func-4.2 {
  catchsql {SELECT abs() FROM t1}
} {1 {wrong number of arguments to function abs()}}
do_test func-4.3 {
  catchsql {SELECT abs(b) FROM t1 ORDER BY a}
} {0 {2 1.2345678901234 2}}
do_test func-4.4 {
  catchsql {SELECT abs(c) FROM t1 ORDER BY a}
} {0 {3 12345.67890 5}}

do_test func-4.5 {
  catchsql {SELECT round(a,b,c) FROM t1}
} {1 {wrong number of arguments to function round()}}
do_test func-4.6 {
  catchsql {SELECT round(b,2) FROM t1 ORDER BY b}
} {0 {-2.00 1.23 2.00}}
do_test func-4.7 {
  catchsql {SELECT round(b,0) FROM t1 ORDER BY a}
} {0 {2 1 -2}}
do_test func-4.8 {
................................................................................
  catchsql {SELECT round(c,a) FROM t1 ORDER BY a}
} {0 {3.0 -12345.68 -5.000}}
do_test func-4.10 {
  catchsql {SELECT 'x' || round(c,a) || 'y' FROM t1 ORDER BY a}
} {0 {x3.0y x-12345.68y x-5.000y}}
do_test func-4.11 {
  catchsql {SELECT round() FROM t1 ORDER BY a}
} {1 {wrong number of arguments to function round()}}

finish_test

Changes to test/select1.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
...
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
#    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 {
................................................................................
execsql {INSERT INTO test1 VALUES(33,44)}

# Error messges from sqliteExprCheck
#
do_test select1-2.1 {
  set v [catch {execsql {SELECT count(f1,f2) FROM test1}} msg]
  lappend v $msg
} {1 {too many arguments to function count()}}
do_test select1-2.2 {
  set v [catch {execsql {SELECT count(f1) FROM test1}} msg]
  lappend v $msg
} {0 2}
do_test select1-2.3 {
  set v [catch {execsql {SELECT Count() FROM test1}} msg]
  lappend v $msg
................................................................................
do_test select1-2.5 {
  set v [catch {execsql {SELECT COUNT(*)+1 FROM test1}} msg]
  lappend v $msg
} {0 3}
do_test select1-2.6 {
  set v [catch {execsql {SELECT min(*) FROM test1}} msg]
  lappend v $msg
} {1 {too few arguments to function min()}}
do_test select1-2.7 {
  set v [catch {execsql {SELECT Min(f1) FROM test1}} msg]
  lappend v $msg
} {0 11}
do_test select1-2.8 {
  set v [catch {execsql {SELECT MIN(f1,f2) FROM test1}} msg]
  lappend v [lsort $msg]
} {0 {11 33}}
do_test select1-2.9 {
  set v [catch {execsql {SELECT MAX(*) FROM test1}} msg]
  lappend v $msg
} {1 {too few arguments to function MAX()}}
do_test select1-2.10 {
  set v [catch {execsql {SELECT Max(f1) FROM test1}} msg]
  lappend v $msg
} {0 33}
do_test select1-2.11 {
  set v [catch {execsql {SELECT max(f1,f2) FROM test1}} msg]
  lappend v [lsort $msg]
................................................................................
do_test select1-2.13 {
  set v [catch {execsql {SELECT MAX(f1)+1 FROM test1}} msg]
  lappend v $msg
} {0 34}
do_test select1-2.14 {
  set v [catch {execsql {SELECT SUM(*) FROM test1}} msg]
  lappend v $msg
} {1 {too few arguments to function SUM()}}
do_test select1-2.15 {
  set v [catch {execsql {SELECT Sum(f1) FROM test1}} msg]
  lappend v $msg
} {0 44}
do_test select1-2.16 {
  set v [catch {execsql {SELECT sum(f1,f2) FROM test1}} msg]
  lappend v $msg
} {1 {too many arguments to function sum()}}
do_test select1-2.17 {
  set v [catch {execsql {SELECT SUM(f1)+1 FROM test1}} msg]
  lappend v $msg
} {0 45}
do_test select1-2.18 {
  set v [catch {execsql {SELECT XYZZY(f1) FROM test1}} msg]
  lappend v $msg
................................................................................
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}}
................................................................................
  }
} {11 33}
do_test select1-8.4 {
  execsql {
    SELECT f1/(f1-11), min(f1/(f1-11),5), max(f1/(f1-33),6)
    FROM test1 ORDER BY f1
  }
} {{} 5 6 1.5 1.5 6}
do_test select1-8.5 {
  execsql {
    SELECT min(1,2,3), -max(1,2,3)
    FROM test1 ORDER BY f1
  }
} {1 -3 1 -3}








|







 







|







 







|











|







 







|







|







 







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
...
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
#    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.20 2002/02/28 03:04:48 drh Exp $

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

# Try to select on a non-existant table.
#
do_test select1-1.1 {
................................................................................
execsql {INSERT INTO test1 VALUES(33,44)}

# Error messges from sqliteExprCheck
#
do_test select1-2.1 {
  set v [catch {execsql {SELECT count(f1,f2) FROM test1}} msg]
  lappend v $msg
} {1 {wrong number of arguments to function count()}}
do_test select1-2.2 {
  set v [catch {execsql {SELECT count(f1) FROM test1}} msg]
  lappend v $msg
} {0 2}
do_test select1-2.3 {
  set v [catch {execsql {SELECT Count() FROM test1}} msg]
  lappend v $msg
................................................................................
do_test select1-2.5 {
  set v [catch {execsql {SELECT COUNT(*)+1 FROM test1}} msg]
  lappend v $msg
} {0 3}
do_test select1-2.6 {
  set v [catch {execsql {SELECT min(*) FROM test1}} msg]
  lappend v $msg
} {0 {{} {}}}
do_test select1-2.7 {
  set v [catch {execsql {SELECT Min(f1) FROM test1}} msg]
  lappend v $msg
} {0 11}
do_test select1-2.8 {
  set v [catch {execsql {SELECT MIN(f1,f2) FROM test1}} msg]
  lappend v [lsort $msg]
} {0 {11 33}}
do_test select1-2.9 {
  set v [catch {execsql {SELECT MAX(*) FROM test1}} msg]
  lappend v $msg
} {0 {{} {}}}
do_test select1-2.10 {
  set v [catch {execsql {SELECT Max(f1) FROM test1}} msg]
  lappend v $msg
} {0 33}
do_test select1-2.11 {
  set v [catch {execsql {SELECT max(f1,f2) FROM test1}} msg]
  lappend v [lsort $msg]
................................................................................
do_test select1-2.13 {
  set v [catch {execsql {SELECT MAX(f1)+1 FROM test1}} msg]
  lappend v $msg
} {0 34}
do_test select1-2.14 {
  set v [catch {execsql {SELECT SUM(*) FROM test1}} msg]
  lappend v $msg
} {1 {wrong number of arguments to function SUM()}}
do_test select1-2.15 {
  set v [catch {execsql {SELECT Sum(f1) FROM test1}} msg]
  lappend v $msg
} {0 44}
do_test select1-2.16 {
  set v [catch {execsql {SELECT sum(f1,f2) FROM test1}} msg]
  lappend v $msg
} {1 {wrong number of arguments to function sum()}}
do_test select1-2.17 {
  set v [catch {execsql {SELECT SUM(f1)+1 FROM test1}} msg]
  lappend v $msg
} {0 45}
do_test select1-2.18 {
  set v [catch {execsql {SELECT XYZZY(f1) FROM test1}} msg]
  lappend v $msg
................................................................................
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 {wrong number of arguments to 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}}
................................................................................
  }
} {11 33}
do_test select1-8.4 {
  execsql {
    SELECT f1/(f1-11), min(f1/(f1-11),5), max(f1/(f1-33),6)
    FROM test1 ORDER BY f1
  }
} {{} {} 6 1.5 1.5 6}
do_test select1-8.5 {
  execsql {
    SELECT min(1,2,3), -max(1,2,3)
    FROM test1 ORDER BY f1
  }
} {1 -3 1 -3}