/ Check-in [a8fa6719]
Login

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

Overview
Comment::-) (CVS 59)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:a8fa6719d55b43f8d194aecfcae5af42d17742af
User & Date: drh 2000-06-06 18:00:16
Context
2000-06-06
18:24
:-) (CVS 60) check-in: 4eca3bf6 user: drh tags: trunk
18:00
:-) (CVS 59) check-in: a8fa6719 user: drh tags: trunk
17:27
GROUP BY and HAVING installed (CVS 58) check-in: db88a0c2 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/select.c.

    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains C code routines that are called by the parser
    25     25   ** to handle SELECT statements.
    26     26   **
    27         -** $Id: select.c,v 1.11 2000/06/06 17:27:05 drh Exp $
           27  +** $Id: select.c,v 1.12 2000/06/06 18:00:16 drh Exp $
    28     28   */
    29     29   #include "sqliteInt.h"
    30     30   
    31     31   /*
    32     32   ** Allocate a new Select structure and return a pointer to that
    33     33   ** structure.
    34     34   */
................................................................................
   332    332         if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
   333    333           return 1;
   334    334         }
   335    335       }
   336    336     }
   337    337     if( pHaving ){
   338    338       if( pGroupBy==0 ){
   339         -      sqliteSetString(&pParse->zErrMsg, "a GROUP BY clause is required to "
   340         -         "use HAVING", 0);
          339  +      sqliteSetString(&pParse->zErrMsg, "a GROUP BY clause is required "
          340  +         "before HAVING", 0);
   341    341         pParse->nErr++;
   342    342         return 1;
   343    343       }
   344    344       if( sqliteExprResolveIds(pParse, pTabList, pHaving) ){
   345    345         return 1;
   346    346       }
   347         -    if( sqliteExprCheck(pParse, pHaving, 0, 0) ){
          347  +    if( sqliteExprCheck(pParse, pHaving, isAgg, 0) ){
   348    348         return 1;
   349    349       }
   350    350     }
   351    351   
   352    352     /* Do an analysis of aggregate expressions.
   353    353     */
   354    354     if( isAgg ){

Added test/select3.test.

            1  +# Copyright (c) 1999, 2000 D. Richard Hipp
            2  +#
            3  +# This program is free software; you can redistribute it and/or
            4  +# modify it under the terms of the GNU General Public
            5  +# License as published by the Free Software Foundation; either
            6  +# version 2 of the License, or (at your option) any later version.
            7  +#
            8  +# This program is distributed in the hope that it will be useful,
            9  +# but WITHOUT ANY WARRANTY; without even the implied warranty of
           10  +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
           11  +# General Public License for more details.
           12  +# 
           13  +# You should have received a copy of the GNU General Public
           14  +# License along with this library; if not, write to the
           15  +# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
           16  +# Boston, MA  02111-1307, USA.
           17  +#
           18  +# Author contact information:
           19  +#   drh@hwaci.com
           20  +#   http://www.hwaci.com/drh/
           21  +#
           22  +#***********************************************************************
           23  +# This file implements regression tests for SQLite library.  The
           24  +# focus of this file is testing aggregate functions and the
           25  +# GROUP BY and HAVING clauses of SELECT statements.
           26  +#
           27  +# $Id: select3.test,v 1.1 2000/06/06 18:00:16 drh Exp $
           28  +
           29  +set testdir [file dirname $argv0]
           30  +source $testdir/tester.tcl
           31  +
           32  +# Build some test data
           33  +#
           34  +do_test select3-1.0 {
           35  +  set fd [open data1.txt w]
           36  +  for {set i 1} {$i<32} {incr i} {
           37  +    for {set j 0} {pow(2,$j)<$i} {incr j} {}
           38  +    puts $fd "$i\t$j"
           39  +  }
           40  +  close $fd
           41  +  execsql {
           42  +    CREATE TABLE t1(n int, log int);
           43  +    COPY t1 FROM 'data1.txt'
           44  +  }
           45  +  file delete data1.txt
           46  +  execsql {SELECT DISTINCT log FROM t1 ORDER BY log}
           47  +} {0 1 2 3 4 5}
           48  +
           49  +# Basic aggregate functions.
           50  +#
           51  +do_test select3-1.1 {
           52  +  execsql {SELECT count(*) FROM t1}
           53  +} {31}
           54  +do_test select3-1.2 {
           55  +  execsql {
           56  +    SELECT min(n),min(log),max(n),max(log),sum(n),sum(log),avg(n),avg(log)
           57  +    FROM t1
           58  +  }
           59  +} {1 0 31 5 496 124 16 4}
           60  +do_test select3-1.3 {
           61  +  execsql {SELECT max(n)/avg(n), max(log)/avg(log) FROM t1}
           62  +} {1.9375 1.25}
           63  +
           64  +# Try some basic GROUP BY clauses
           65  +#
           66  +do_test select3-2.1 {
           67  +  execsql {SELECT log, count(*) FROM t1 GROUP BY log ORDER BY log}
           68  +} {0 1 1 1 2 2 3 4 4 8 5 15}
           69  +do_test select3-2.2 {
           70  +  execsql {SELECT log, min(n) FROM t1 GROUP BY log ORDER BY log}
           71  +} {0 1 1 2 2 3 3 5 4 9 5 17}
           72  +do_test select3-2.3 {
           73  +  execsql {SELECT log, avg(n) FROM t1 GROUP BY log ORDER BY log}
           74  +} {0 1 1 2 2 3.5 3 6.5 4 12.5 5 24}
           75  +do_test select3-2.3 {
           76  +  execsql {SELECT log, avg(n)+1 FROM t1 GROUP BY log ORDER BY log}
           77  +} {0 2 1 3 2 4.5 3 7.5 4 13.5 5 25}
           78  +do_test select3-2.4 {
           79  +  execsql {SELECT log, avg(n)-min(n) FROM t1 GROUP BY log ORDER BY log}
           80  +} {0 0 1 0 2 0.5 3 1.5 4 3.5 5 7}
           81  +do_test select3-2.5 {
           82  +  execsql {SELECT log*2+1, avg(n)-min(n) FROM t1 GROUP BY log ORDER BY log}
           83  +} {1 0 3 0 5 0.5 7 1.5 9 3.5 11 7}
           84  +
           85  +# Cannot have a HAVING without a GROUP BY
           86  +#
           87  +do_test select3-3.1 {
           88  +  set v [catch {execsql {SELECT log, count(*) FROM t1 HAVING log>=4}} msg]
           89  +  lappend v $msg
           90  +} {1 {a GROUP BY clause is required before HAVING}}
           91  +
           92  +# Toss in some HAVING clauses
           93  +#
           94  +do_test select3-4.1 {
           95  +  execsql {SELECT log, count(*) FROM t1 GROUP BY log HAVING log>=4 ORDER BY log}
           96  +} {4 8 5 15}
           97  +do_test select3-4.2 {
           98  +  execsql {
           99  +    SELECT log, count(*) FROM t1 
          100  +    GROUP BY log 
          101  +    HAVING count(*)>=4 
          102  +    ORDER BY log
          103  +  }
          104  +} {3 4 4 8 5 15}
          105  +do_test select3-4.3 {
          106  +  execsql {
          107  +    SELECT log, count(*) FROM t1 
          108  +    GROUP BY log 
          109  +    HAVING count(*)>=4 
          110  +    ORDER BY max(n)
          111  +  }
          112  +} {3 4 4 8 5 15}
          113  +
          114  +finish_test