]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Experimental change to add a per-connection option that raises an error if
authordrh <>
Fri, 9 Jun 2023 13:08:36 +0000 (13:08 +0000)
committerdrh <>
Fri, 9 Jun 2023 13:08:36 +0000 (13:08 +0000)
a bare column appears in an aggregate query.

FossilOrigin-Name: f587891134158fa4c48b3a31b6e1b9d7688823953a8b434752199160f3a95ffd

17 files changed:
manifest
manifest.uuid
src/expr.c
src/main.c
src/select.c
src/shell.c.in
src/sqlite.h.in
src/sqliteInt.h
src/test1.c
test/select1.test
test/select3.test
test/select4.test
test/select5.test
test/select6.test
test/select7.test
test/select8.test
test/selectC.test

index 1ba77bf2152ac1b0c8b6e552ef23486f174d4068..582d970b6f4cabf26627441e65bb5d3c04e6ec0b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\sSQLITE_EXTENSION_INIT\smacros\sfrom\sdbdata.c.
-D 2023-06-08T20:49:25.974
+C Experimental\schange\sto\sadd\sa\sper-connection\soption\sthat\sraises\san\serror\sif\na\sbare\scolumn\sappears\sin\san\saggregate\squery.
+D 2023-06-09T13:08:36.651
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -586,7 +586,7 @@ F src/date.c 6e9549239d08957ffeff481bb131d071c969833b230d1dbfb836cf9dab1501b8
 F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387
 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef
 F src/delete.c 1b00589aa4f2c50beba39f9da5166fc2161234580ea8c0d087b6d5c2c7a17c21
-F src/expr.c b7dabf7f5ab42ed0b70437e9725aea25700eaff8a268cc42d682b1d67bb797f8
+F src/expr.c bdaff0996d8651ee158d1ff20cc0750b967d390c32db7b752333ee795f7873f8
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 03c134cc8bffe54835f742ddea0b72ebfc8f6b32773d175c71b8afeea6cb5c83
 F src/func.c 6303e1ccb80dbd0d9b52f902a01d3b105981486fdfd66f9e1ddfd74aaf3032fc
@@ -599,7 +599,7 @@ F src/insert.c a38bbb944a4f2771d70140db9c5d57e36c37e28d5a366497b4f93272a6d2567e
 F src/json.c 14c474fb1249a46eb44e878e2361f36abfe686b134039b0d1883d93d61505b4a
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465
-F src/main.c 5fd4b65d61ae6155f36756ed508a39b38b49355b031188961e8d923f43f4bc49
+F src/main.c 4c04e6c772ce42663e9f2f73fe053f4a38fefcdd0e98511ade49fb7ed3065a33
 F src/malloc.c 47b82c5daad557d9b963e3873e99c22570fb470719082c6658bf64e3012f7d23
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -636,17 +636,17 @@ F src/printf.c b9320cdbeca0b336c3f139fd36dd121e4167dd62b35fbe9ccaa9bab44c0af38d
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c c1457b920aeb33ed106bf478fad31b7473a8950a755ea898980c428928f3a514
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c 1ddfe4450101c3d4890ecb2d6b97ab80b78764d5a3e7022b171721df1620c419
-F src/shell.c.in 0c420738cf95292c394c2451281f76f2638c9234943805375974a20d2a5be8c3
-F src/sqlite.h.in 3076d78836b6dac53b3ab0875fc8fd15bca8077aad4d33c85336e05af6aef8c7
+F src/select.c dc7daf795c53421ba9f78e8345b8a7501b078479d95b3fe91f5e523a48ca57bb
+F src/shell.c.in 359a1436b4cd24f30d98dc1bd751333e1ec670a6e752ba047545739187ad2910
+F src/sqlite.h.in 54623b116932859b1bc56b5f74ffa0c77ac9c3657cd2d5797590874afe2dbb08
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
-F src/sqliteInt.h 924ddd5bd9dad8a499005c2c02a492c67dbe784feafbd78fdd70d712cf839499
+F src/sqliteInt.h 435d393dd67d9c50a8abe6b0c814c3882679d95d7f6a1f9495555635987ede0e
 F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6
 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
 F src/tclsqlite.c 9952874a1f1bb9fa6406b334cadf748c273cd2f2d4501152022a95dd37dc7958
-F src/test1.c 8ae514d6a0d030f7953a99ff5dca6419cb7a5ad1a1c392d1fdf0f069e6ca792b
+F src/test1.c 54c127625d25c004a59b5f671a9dfd6c436661c461b0ececaabb4b0979260469
 F src/test2.c 827446e259a3b7ab949da1542953edda7b5117982576d3e6f1c24a0dd20a5cef
 F src/test3.c e5178558c41ff53236ae0271e9acb3d6885a94981d2eb939536ee6474598840e
 F src/test4.c 4533b76419e7feb41b40582554663ed3cd77aaa54e135cf76b3205098cd6e664
@@ -1435,18 +1435,18 @@ F test/schemafault.test 1936bceca55ac82c5efbcc9fc91a1933e45c8d1e1d106b9a7e56c972
 F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2ff09384
 F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
 F test/seekscan1.test 31af16e3bb3203d153aea320939c5da97ec44705c2710d153c06a01397d45b09
-F test/select1.test 692e84cfa29c405854c69e8a4027183d64c22952866a123fabbce741a379e889
+F test/select1.test 1f3f154481c8ad4dc6f8192720fd86bf667f3ce1b636c3f4987f1d3c3cc459c5
 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
-F test/select3.test 8d04b66df7475275a65f7e4a786d6a724c30bd9929f8ae5bd59c8d3d6e75e6cd
-F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b
-F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae
-F test/select6.test 9b2fb4ffedf52e1b5703cfcae1212e7a4a063f014c0458d78d29aca3db766d1f
-F test/select7.test f659f231489349e8c5734e610803d7654207318f
-F test/select8.test 8c8f5ae43894c891efc5755ed905467d1d67ad5d
+F test/select3.test 398ba6069fd6e9e90b24723cf2287e352280c1dce3a54db29420ea518d7e2c49
+F test/select4.test b5b57fb83dd0891cebc6b4d7e1159deac6a075816a473805694a2d52dc859d11
+F test/select5.test b75d12932232b35791ba6c0b1298f60c3b008e6e8bf9a9123c5244845836dbd7
+F test/select6.test b3ec3ae543922683567afebeb4199d4694eba642110275a21bb363524b5e47bd
+F test/select7.test ee6369be33d5eb857fb1dd32f71d4bcbbc6550cdcf6d154290cd20142e7fca20
+F test/select8.test 705dbdc6c9cde7e62dfa92f506e95895d75f1a88d42942ab493c1aacb9eb88f9
 F test/select9.test f7586b207ce2304ab80dc93d3146469a28fd4403621dd3a82d06644563d3c812
 F test/selectA.test 6aef8b2136a4ac7a3e2e4161d2b8ca7bc6ebe2779de084f9bb66ca9e2323a937
 F test/selectB.test 954e4e49cf1f896d61794e440669e03a27ceea25
-F test/selectC.test 38c530b0cc5728b793c3c11f52b52c70290d39822224acd39011c89c1853bd31
+F test/selectC.test 294b7566a3eda0b4226e90de384a4ff32252df9551ebf4edafd08d02aaddecc9
 F test/selectD.test 6d1909b49970bf92f45ce657505befcef5fc7cbc13544e18103a316d32189bfb
 F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf
 F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3
@@ -2040,8 +2040,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 157b5d25e0c99eabfa3c32cb867fe7e3c05031c12354f734d2cd8a4062b9439c
-R fd6d21412985b1945f5582d66d783118
-U dan
-Z bb3a1dd8e6d17e8c766f86f2b38d20ee
+P 106ec745766ac59131f975d5ab5487c8a24b9c3be1766411c018b42c6ae4672a
+R d727d1de40f238a882594204f8ca1f35
+T *branch * newbie-safe-aggregates
+T *sym-newbie-safe-aggregates *
+T -sym-trunk *
+U drh
+Z a5115ea6cc9f8846539ef3c6d5cf6027
 # Remove this line to create a well-formed Fossil manifest.
index a757a264acb132fb5b4dfce98254df9058c30088..da26d2edec68852e12394d7cfac9b4d8707dd7b0 100644 (file)
@@ -1 +1 @@
-106ec745766ac59131f975d5ab5487c8a24b9c3be1766411c018b42c6ae4672a
\ No newline at end of file
+f587891134158fa4c48b3a31b6e1b9d7688823953a8b434752199160f3a95ffd
\ No newline at end of file
index 795f6505243d5b77d917ee2bf5701f89f8b74198..8007ad7c5d9be033b1444af36f06215be737f2bc 100644 (file)
@@ -6493,6 +6493,11 @@ static void findOrCreateAggInfoColumn(
     }
   }
   if( pCol->iSorterColumn<0 ){
+    if( pAggInfo->nAccumulator<0 ){
+      assert( pParse->db->flags & SQLITE_StrictAgg );
+      sqlite3ErrorMsg(pParse, "bare column in aggregate query");
+      sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr);
+    }
     pCol->iSorterColumn = pAggInfo->nSortingColumn++;
   }
 fix_up_expr:
@@ -6519,10 +6524,33 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
 
   assert( pNC->ncFlags & NC_UAggInfo );
   assert( pAggInfo->iFirstReg==0 );
+
+
   switch( pExpr->op ){
     default: {
       IndexedExpr *pIEpr;
       Expr tmp;
+
+      /* If this expression node matches an entry in the GROUP BY clause
+      ** then disable bare-column error reporting for all subexpressions
+      ** within this expression. */
+      if( pAggInfo->nAccumulator<0 && pAggInfo->pGroupBy!=0 ){
+        int j, n;
+        ExprList *pGB = pAggInfo->pGroupBy;
+        struct ExprList_item *pTerm = pGB->a;
+        n = pGB->nExpr;
+        for(j=0; j<n; j++, pTerm++){
+          if( sqlite3ExprCompare(0, pTerm->pExpr, pExpr, 0)==0 ){
+            pAggInfo->nAccumulator = 0;
+            sqlite3WalkExpr(pWalker, pExpr);
+            pAggInfo->nAccumulator = -1;
+            return WRC_Prune;
+          }
+        }
+      }
+
+      /* Check to see if the current expression can be satisfied using
+      ** and index on an expression. */
       assert( pParse->iSelfTab==0 );
       if( (pNC->ncFlags & NC_InAggFunc)==0 ) break;
       if( pParse->pIdxEpr==0 ) break;
index 7e3fab88614885a374f5e3207459e0302bd1508c..9f4d429410a0b85a3ed4542b2256a3e4e6b9e7fb 100644 (file)
@@ -960,6 +960,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){
         { SQLITE_DBCONFIG_TRUSTED_SCHEMA,        SQLITE_TrustedSchema  },
         { SQLITE_DBCONFIG_STMT_SCANSTATUS,       SQLITE_StmtScanStatus },
         { SQLITE_DBCONFIG_REVERSE_SCANORDER,     SQLITE_ReverseOrder   },
+        { SQLITE_DBCONFIG_STRICT_AGGREGATE,      SQLITE_StrictAgg      },
       };
       unsigned int i;
       rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
index b492d5374d0f8c935311fd8a5a843e5742277a03..69e921c208c39e803beb927f7ee0fb78f06af206 100644 (file)
@@ -7872,6 +7872,13 @@ int sqlite3Select(
     VVA_ONLY( sNC.ncFlags = NC_UAggInfo; )
     pAggInfo->nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
     pAggInfo->pGroupBy = pGroupBy;
+    if( db->flags & SQLITE_StrictAgg ){
+      /* nAccumulator<0 indicates that bare columns on a table to be
+      ** aggregated should be considered an error.  nAccumulator will
+      ** become non-negative before we start processing the arguments of
+      ** aggregate queries further below. */
+      pAggInfo->nAccumulator = -1;
+    }
     sqlite3ExprAnalyzeAggList(&sNC, pEList);
     sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
     if( pHaving ){
index d02ec7fb9cda72a5ec430d74b6bb2ff28c0ebfc8..6cbc4df092350e760203ece272796c2ed1c04a54 100644 (file)
@@ -8281,6 +8281,7 @@ static int do_meta_command(char *zLine, ShellState *p){
         { "reset_database",     SQLITE_DBCONFIG_RESET_DATABASE        },
         { "reverse_scanorder",  SQLITE_DBCONFIG_REVERSE_SCANORDER     },
         { "stmt_scanstatus",    SQLITE_DBCONFIG_STMT_SCANSTATUS       },
+        { "strict_aggregate",   SQLITE_DBCONFIG_STRICT_AGGREGATE      },
         { "trigger_eqp",        SQLITE_DBCONFIG_TRIGGER_EQP           },
         { "trusted_schema",     SQLITE_DBCONFIG_TRUSTED_SCHEMA        },
         { "writable_schema",    SQLITE_DBCONFIG_WRITABLE_SCHEMA       },
index c5a50c01be90d72da43d0e691497ca89382f5842..ea2fc2ec413eeb735ed20343b30e4d7e650111b6 100644 (file)
@@ -2510,7 +2510,8 @@ struct sqlite3_mem_methods {
 #define SQLITE_DBCONFIG_TRUSTED_SCHEMA        1017 /* int int* */
 #define SQLITE_DBCONFIG_STMT_SCANSTATUS       1018 /* int int* */
 #define SQLITE_DBCONFIG_REVERSE_SCANORDER     1019 /* int int* */
-#define SQLITE_DBCONFIG_MAX                   1019 /* Largest DBCONFIG */
+#define SQLITE_DBCONFIG_STRICT_AGGREGATE      1020 /* int int* */
+#define SQLITE_DBCONFIG_MAX                   1020 /* Largest DBCONFIG */
 
 /*
 ** CAPI3REF: Enable Or Disable Extended Result Codes
index d4e255ea217102e9fae36ecbd02b52003adf04c6..14d1aa947b311196400d46f90f23cf9073383b52 100644 (file)
@@ -1761,8 +1761,7 @@ struct sqlite3 {
 #define SQLITE_ShortColNames  0x00000040  /* Show short columns names */
 #define SQLITE_TrustedSchema  0x00000080  /* Allow unsafe functions and
                                           ** vtabs in the schema definition */
-#define SQLITE_NullCallback   0x00000100  /* Invoke the callback once if the */
-                                          /*   result set is empty */
+#define SQLITE_StrictAgg      0x00000100  /* No bare columns in agg queries */
 #define SQLITE_IgnoreChecks   0x00000200  /* Do not enforce check constraints */
 #define SQLITE_StmtScanStatus 0x00000400  /* Enable stmt_scanstats() counters */
 #define SQLITE_NoCkptOnClose  0x00000800  /* No checkpoint on close()/DETACH */
@@ -1791,6 +1790,8 @@ struct sqlite3 {
                                           /*   the count using a callback. */
 #define SQLITE_CorruptRdOnly  HI(0x00002) /* Prohibit writes due to error */
 #define SQLITE_ReadUncommit   HI(0x00004) /* READ UNCOMMITTED in shared-cache */
+#define SQLITE_NullCallback   HI(0x00008) /* Invoke the callback once if the */
+                                          /*   result set is empty */
 
 /* Flags used only if debugging */
 #ifdef SQLITE_DEBUG
index ac30a0d5cba1246acbebc5022db3cb4c7f706ab0..89d41ee5306c6d531b50333f4b16fca972d4db43 100644 (file)
@@ -8336,6 +8336,7 @@ static int SQLITE_TCLAPI test_sqlite3_db_config(
     { "DQS_DDL",            SQLITE_DBCONFIG_DQS_DDL },
     { "LEGACY_FILE_FORMAT", SQLITE_DBCONFIG_LEGACY_FILE_FORMAT },
     { "STMT_SCANSTATUS",    SQLITE_DBCONFIG_STMT_SCANSTATUS },
+    { "STRICT_AGGREGATE",   SQLITE_DBCONFIG_STRICT_AGGREGATE },
   };
   int i;
   int v = 0;
@@ -8360,7 +8361,16 @@ static int SQLITE_TCLAPI test_sqlite3_db_config(
     return TCL_ERROR;
   }
   if( objc==4 ){
-    if( Tcl_GetIntFromObj(interp, objv[3], &v) ) return TCL_ERROR;
+    if( Tcl_GetIntFromObj(interp, objv[3], &v) ){
+      const char *zVal = Tcl_GetString(objv[3]);
+      if( strcmp(zVal,"on")==0 || strcmp(zVal,"true")==0 ){
+        v = 1;
+      }else if( strcmp(zVal,"off")==0 || strcmp(zVal,"false")==0 ){
+        v = 0;
+      }else{
+        return TCL_ERROR;
+      }
+    }
   }else{
     v = -1;
   }
index 44e63d252d1ee531a08aa26276aac893540d4e5f..4c0b39b7b08e48c1c45a1906e9ca108ad75ba0e1 100644 (file)
@@ -403,10 +403,16 @@ do_test select1-4.13 {
 
 # ORDER BY ignored on an aggregate query
 #
+sqlite3_db_config db STRICT_AGGREGATE off
 do_test select1-5.1 {
   set v [catch {execsql {SELECT max(f1) FROM test1 ORDER BY f2}} msg]
   lappend v $msg
 } {0 33}
+sqlite3_db_config db STRICT_AGGREGATE on
+do_test select1-5.2 {
+  set v [catch {execsql {SELECT max(f1) FROM test1 ORDER BY f2}} msg]
+  lappend v $msg
+} {1 {bare column in aggregate query}}
 
 execsql {CREATE TABLE test2(t1 text, t2 text)}
 execsql {INSERT INTO test2 VALUES('abc','xyz')}
@@ -1197,6 +1203,7 @@ do_execsql_test select1-20.10 {
    WHERE ((SELECT t1.a FROM t1 AS x GROUP BY b) AND b=0)
       OR a = 10;
 } {10 Y}
+sqlite3_db_config db STRICT_AGGREGATE off
 do_execsql_test select1-20.20 {
   SELECT ifnull(a, max((SELECT 123))), count(a) FROM t1 ;
 } {10 1}
index 4c9d71b4f5cac4f11d27e05de7463ed2852341be..17a5755952d210408bac07bc87ae254bd19cbe01 100644 (file)
@@ -12,7 +12,6 @@
 # focus of this file is testing aggregate functions and the
 # GROUP BY and HAVING clauses of SELECT statements.
 #
-# $Id: select3.test,v 1.23 2008/01/16 18:20:42 danielk1977 Exp $
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
@@ -121,6 +120,7 @@ do_test select3-2.14 {
 # 
 # Update: As of 3.39.0, you can.
 #
+sqlite3_db_config db STRICT_AGGREGATE off
 do_execsql_test select3-3.1 {
   SELECT log, count(*) FROM t1 HAVING log>=4
 } {}
@@ -318,17 +318,34 @@ reset_db
 do_execsql_test select3-9.100 {
   CREATE TABLE t0(c0 REAL, c1 REAL GENERATED ALWAYS AS (c0));
   INSERT INTO t0(c0) VALUES (1);
+}
+sqlite3_db_config db STRICT_AGGREGATE on
+do_catchsql_test select3-9.110 {
+  SELECT * FROM t0 GROUP BY c0;
+} {1 {bare column in aggregate query}}
+sqlite3_db_config db STRICT_AGGREGATE off
+do_catchsql_test select3-9.120 {
   SELECT * FROM t0 GROUP BY c0;
-} {1.0 1.0}
+} {0 {1.0 1.0}}
 
 reset_db
-do_execsql_test select3.10.100 {
+do_execsql_test select3-10.100 {
   CREATE TABLE t1(a, b);
   CREATE TABLE t2(c, d);
+}
+sqlite3_db_config db STRICT_AGGREGATE on
+do_catchsql_test select3-10.110 {
   SELECT max(t1.a), 
          (SELECT 'xyz' FROM (SELECT * FROM t2 WHERE 0) WHERE t1.b=1) 
   FROM t1;
-} {{} {}}
+} {1 {bare column in aggregate query}}
+sqlite3_db_config db STRICT_AGGREGATE off
+db null NULL
+do_catchsql_test select3-10.120 {
+  SELECT max(t1.a), 
+         (SELECT 'xyz' FROM (SELECT * FROM t2 WHERE 0) WHERE t1.b=1) 
+  FROM t1;
+} {0 {NULL NULL}}
 
 #-------------------------------------------------------------------------
 # dbsqlfuzz crash-8e17857db2c5a9294c975123ac807156a6559f13.txt
@@ -354,6 +371,7 @@ foreach {tn sql} {
   }
 } {
   reset_db
+  sqlite3_db_config db STRICT_AGGREGATE off
   do_execsql_test select3-11.$tn.1 $sql 
   do_execsql_test select3.11.$tn.2 {
     SELECT max(a), val FROM t1 LEFT JOIN (
@@ -375,14 +393,15 @@ foreach {tn sql} {
 }
 
 reset_db
-do_execsql_test 12.0 {
+sqlite3_db_config db STRICT_AGGREGATE off
+do_execsql_test select3-12.0 {
   CREATE TABLE t1(a);
   CREATE TABLE t2(x);
 }
-do_execsql_test 12.1 {
+do_execsql_test select3-12.1 {
   SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
 }
-do_execsql_test 12.2 {
+do_execsql_test select3-12.2 {
   INSERT INTO t1 VALUES(1), (1), (2), (3);
   SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
 } {
@@ -390,7 +409,7 @@ do_execsql_test 12.2 {
   0 {}
   0 {}
 }
-do_execsql_test 12.3 {
+do_execsql_test select3-12.3 {
   INSERT INTO t2 VALUES(45);
   SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
 } {
@@ -398,7 +417,7 @@ do_execsql_test 12.3 {
   1 59
   1 59
 }
-do_execsql_test 12.4 {
+do_execsql_test select3-12.4 {
   INSERT INTO t2 VALUES(210);
   SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
 } {
@@ -406,7 +425,7 @@ do_execsql_test 12.4 {
   2 59
   2 59
 }
-do_execsql_test 12.5 {
+do_execsql_test select3-12.5 {
   INSERT INTO t2 VALUES(NULL);
   SELECT count(x), m FROM t1 LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
 } {
@@ -414,19 +433,19 @@ do_execsql_test 12.5 {
   2 59
   2 59
 }
-do_execsql_test 12.6 {
+do_execsql_test select3-12.6 {
   DELETE FROM t2;
   DELETE FROM t1;
   INSERT INTO t1 VALUES('value');
   INSERT INTO t2 VALUES('hello');
 } {}
-do_execsql_test 12.7 {
+do_execsql_test select3-12.7 {
   SELECT group_concat(x), m FROM t1 
     LEFT JOIN (SELECT x, 59 AS m FROM t2) GROUP BY a;
 } {
   hello 59
 }
-do_execsql_test 12.8 {
+do_execsql_test select3-12.8 {
   SELECT group_concat(x), m, n FROM t1 
     LEFT JOIN (SELECT x, 59 AS m, 60 AS n FROM t2) GROUP BY a;
 } {
@@ -434,4 +453,3 @@ do_execsql_test 12.8 {
 }
 
 finish_test
-
index d49708ece87ce49907477bf8da2b47737b147430..01b627c1b7435f2663f4743f4330c508ba7cd150 100644 (file)
@@ -690,11 +690,13 @@ do_test select4-10.8 {
     SELECT DISTINCT log FROM t1 ORDER BY log LIMIT 0 OFFSET 3
   }
 } {}
+sqlite3_db_config db STRICT_AGGREGATE off
 do_test select4-10.9 {
   execsql {
     SELECT DISTINCT max(n), log FROM t1 ORDER BY +log; -- LIMIT 2 OFFSET 1
   }
 } {31 5}
+sqlite3_db_config db STRICT_AGGREGATE on
 
 # Make sure compound SELECTs with wildly different numbers of columns
 # do not cause assertion faults due to register allocation issues.
index 8de306cf40708148443488f79db4113b9480f1a8..679da2dd962314c2f3adc92cbc1432762ffd5ff6 100644 (file)
@@ -149,11 +149,18 @@ do_test select5-5.4 {
     SELECT a, b FROM t2 GROUP BY a, b;
   } 
 } {1 2 1 4 6 4}
+sqlite3_db_config db STRICT_AGGREGATE off
 do_test select5-5.5 {
   execsql {
     SELECT a, b FROM t2 GROUP BY a;
   } 
 } {1 2 6 4}
+sqlite3_db_config db STRICT_AGGREGATE on
+do_test select5-5.6 {
+  catchsql {
+    SELECT a, b FROM t2 GROUP BY a;
+  } 
+} {1 {bare column in aggregate query}}
 
 # Test rendering of columns for the GROUP BY clause.
 #
@@ -256,6 +263,13 @@ do_execsql_test select5-9.1 {
   CREATE TABLE t1(a INT, b INT);
   INSERT INTO t1(a,b) VALUES(1,null),(null,null),(1,null);
   CREATE UNIQUE INDEX t1b ON t1(abs(b));
+}
+sqlite3_db_config db STRICT_AGGREGATE on
+do_catchsql_test select5-9.2 {
+  SELECT quote(a), quote(b), '|' FROM t1 GROUP BY a, abs(b);
+} {1 {bare column in aggregate query}}
+sqlite3_db_config db STRICT_AGGREGATE off
+do_execsql_test select5-9.3 {
   SELECT quote(a), quote(b), '|' FROM t1 GROUP BY a, abs(b);
 } {NULL NULL | 1 NULL |}
 
index 612afefa6f358355f8ddb02bcda740792bdc9db2..a22158390fe02b287a77f2fa855c236128616b54 100644 (file)
@@ -267,6 +267,7 @@ do_test select6-4.3 {
     SELECT DISTINCT y FROM (SELECT y FROM t1) WHERE y<5 ORDER BY y
   }
 } {1 2 3 4}
+sqlite3_db_config db STRICT_AGGREGATE off
 do_test select6-4.4 {
   execsql {
     SELECT avg(y) FROM (SELECT DISTINCT y FROM t1) WHERE y<5 ORDER BY y
@@ -277,6 +278,13 @@ do_test select6-4.5 {
     SELECT avg(y) FROM (SELECT DISTINCT y FROM t1 WHERE y<5) ORDER BY y
   }
 } {2.5}
+sqlite3_db_config db STRICT_AGGREGATE on
+do_catchsql_test select6-4.6 {
+  SELECT avg(y) FROM (SELECT DISTINCT y FROM t1) WHERE y<5 ORDER BY y
+} {1 {bare column in aggregate query}}
+do_catchsql_test select6-4.7 {
+  SELECT avg(y) FROM (SELECT DISTINCT y FROM t1 WHERE y<5) ORDER BY y
+} {1 {bare column in aggregate query}}
 
 do_test select6-5.1 {
   execsql {
index d705ebfaf4e021fab7338d06abb2f5fbbcec390c..65c5d86fbc52bb7c7cfa8fd50e8e7a60fae7e59d 100644 (file)
@@ -61,16 +61,24 @@ do_test select7-2.1 {
 # an aggregate query, whether it contains aggregates or not.
 #
 ifcapable subquery {
-  # do_test select7-3.1 {
+  # do_test select7-3.1.0 {
   #   catchsql {
   #     SELECT * FROM (SELECT * FROM sqlite_master) GROUP BY name
   #   }
   # } {1 {GROUP BY may only be used on aggregate queries}}
-  do_test select7-3.1 {
+  sqlite3_db_config db STRICT_AGGREGATE on
+  do_test select7-3.1.1 {
+    catchsql {
+      SELECT * FROM (SELECT * FROM sqlite_master) GROUP BY name
+    }
+  } [list 1 {bare column in aggregate query}]
+  sqlite3_db_config db STRICT_AGGREGATE off
+  do_test select7-3.1.2 {
     catchsql {
       SELECT * FROM (SELECT * FROM sqlite_master) GROUP BY name
     }
   } [list 0 [execsql {SELECT * FROM sqlite_master ORDER BY name}]]
+  sqlite3_db_config db STRICT_AGGREGATE on
 }
 
 # Ticket #2018 - Make sure names are resolved correctly on all
@@ -194,7 +202,7 @@ do_test select7-7.7 {
   execsql {
     CREATE TABLE t5(a TEXT, b INT);
     INSERT INTO t5 VALUES(123, 456);
-    SELECT typeof(a), a FROM t5 GROUP BY a HAVING a<b;
+    SELECT typeof(a), a FROM t5 GROUP BY a, b HAVING a<b;
   }
 } {text 123}
 
index 39b27394993db59d7e70b160eacda8ce6bf75118..326665a376ac68693aeb4494e372ebe254fc8d7b 100644 (file)
@@ -19,7 +19,7 @@ set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 
 execsql {
-  CREATE TABLE songs(songid, artist, timesplayed);
+  CREATE TABLE songs(songid INT, artist TEXT, timesplayed INT);
   INSERT INTO songs VALUES(1,'one',1);
   INSERT INTO songs VALUES(2,'one',2);
   INSERT INTO songs VALUES(3,'two',3);
@@ -27,6 +27,20 @@ execsql {
   INSERT INTO songs VALUES(5,'one',7);
   INSERT INTO songs VALUES(6,'two',11);
 }
+sqlite3_db_config db STRICT_AGGREGATE on
+do_catchsql_test select8-0.9.1 {
+  SELECT DISTINCT artist, sum(timesplayed) AS total
+    FROM songs
+   GROUP BY lower(artist);
+} {1 {bare column in aggregate query}}
+do_catchsql_test select8-0.9.2 {
+  SELECT DISTINCT lower(artist), sum(timesplayed) AS total
+    FROM songs
+   GROUP BY lower(artist)
+   ORDER BY lower(artist);
+} {0 {one 10 three 5 two 14}}
+
+sqlite3_db_config db STRICT_AGGREGATE off
 set result [execsql {
   SELECT DISTINCT artist,sum(timesplayed) AS total      
   FROM songs      
index 42fa1d11b8ee929be06d24a1dd3567ac5fbf1040..bfb756d6e656fc5edb6e2d4cf94943c33648caba 100644 (file)
@@ -205,6 +205,7 @@ do_test selectC-3.2 {
     SELECT a, max(b || a) FROM t2 WHERE (b||b||b)!='value' GROUP BY a;
   }
 } {abc xxxabc def yyydef}
+sqlite3_db_config db STRICT_AGGREGATE off
 do_test selectC-3.3 {
   execsql {
     SELECT b, max(a || b) FROM t2 WHERE (b||b||b)!='value' GROUP BY a;