Compare commits

...

10 Commits

Author SHA1 Message Date
drh e93afdc3d0 Merge the latest trunk enhancements into the newbie-safe-aggregates branch.
FossilOrigin-Name: c8ef3b787419ccb70bceccc8c851ba357f85299c3fc0f972d6b73d4c4cb23c42
2023-06-12 14:26:29 +00:00
drh 944011cfd2 Merge the latest trunk enhancements into the newbie-safe-aggregates branch.
FossilOrigin-Name: 75a877a9239ef004e4249ab9379a7af8cbe7655e3cdf50b7349c14721cc6eca4
2023-06-11 22:05:55 +00:00
drh da258f52da Add documentation for SQLITE_DBCONFIG_STRICT_AGGREGATE.
FossilOrigin-Name: 76fb9151386d8c4557ea75b26af5b9a2c83b04f7bd5e635a2218ca30a48b5849
2023-06-10 17:27:59 +00:00
drh 0ff7a1da5f Merge the latest trunk enhancements into the newbie-safe-aggregates branch.
FossilOrigin-Name: e19e20fbaf6dedc5bf062120f3440eda86befb72a080d3ed70dbc45329ddf06d
2023-06-10 17:15:59 +00:00
drh 3a4e20ed16 Fix a potential UAF in the parser caused by the changes on this branch.
FossilOrigin-Name: c29ec76944e2ee62e3f3383047a92c05e97f59387874985381e74a47ffe69d28
2023-06-10 09:24:29 +00:00
stephan 0a7ef9b26c Add CFLAGS_FIDDLE to ext/wasm/fiddle.make as a way to pass on additional compilation flags to the fiddle build from the CLI, e.g. CFLAGS_FIDDLE=-DSQLITE_STRICT_AGGREGATE. Expose SQLITE_DBCONFIG_STRICT_AGGREGATE to JS.
FossilOrigin-Name: 0b0172087954d62fec532afce4532beb6a3882736e089bdd46aa5954bca2dbcd
2023-06-10 08:19:10 +00:00
drh 6ae69a4d02 Naming consistency: Always use the singular "STRICT AGGREGATE", not the plural.
FossilOrigin-Name: 275d056e461fa7f42a3df872cc9027799e8009a7296ea3546058e2c434886f68
2023-06-09 19:24:07 +00:00
drh 120b89afae Improved sqlite3_error_offset() values for bare column errors on
'*' and 'table.*' expressions in SELECT statements.

FossilOrigin-Name: 446ad162f76f2a32f3bfc5b5c1dadc8a139d4f338abb91fd912141ed8a768e8e
2023-06-09 18:58:15 +00:00
drh d8fdd21afe The -DSQLITE_STRICT_AGGREGATES compile-time option enables
SQLITE_DBCONFIG_STRICT_AGGREGATE by default.

FossilOrigin-Name: cd1f6b27d99272a2550fedf22fa1bf6fde0b2f29e51fe7c113a2441f210aa492
2023-06-09 18:30:36 +00:00
drh fbf3f098de Experimental change to add a per-connection option that raises an error if
a bare column appears in an aggregate query.

FossilOrigin-Name: f587891134158fa4c48b3a31b6e1b9d7688823953a8b434752199160f3a95ffd
2023-06-09 13:08:36 +00:00
21 changed files with 222 additions and 54 deletions
+1
View File
@@ -1570,6 +1570,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
case capi.SQLITE_DBCONFIG_TRUSTED_SCHEMA:
case capi.SQLITE_DBCONFIG_STMT_SCANSTATUS:
case capi.SQLITE_DBCONFIG_REVERSE_SCANORDER:
case capi.SQLITE_DBCONFIG_STRICT_AGGREGATE:
return this.ip(pDb, op, args[0], args[1] || 0);
case capi.SQLITE_DBCONFIG_LOOKASIDE:
return this.pii(pDb, op, args[0], args[1], args[2]);
+2
View File
@@ -570,6 +570,7 @@ const char * sqlite3_wasm_enum_json(void){
DefInt(SQLITE_DBCONFIG_STMT_SCANSTATUS);
DefInt(SQLITE_DBCONFIG_REVERSE_SCANORDER);
DefInt(SQLITE_DBCONFIG_MAX);
DefInt(SQLITE_DBCONFIG_STRICT_AGGREGATE);
} _DefGroup;
DefGroup(dbStatus){
@@ -1549,6 +1550,7 @@ int sqlite3_wasm_db_config_ip(sqlite3 *pDb, int op, int arg1, int* pArg2){
case SQLITE_DBCONFIG_TRUSTED_SCHEMA:
case SQLITE_DBCONFIG_STMT_SCANSTATUS:
case SQLITE_DBCONFIG_REVERSE_SCANORDER:
case SQLITE_DBCONFIG_STRICT_AGGREGATE:
return sqlite3_db_config(pDb, op, arg1, pArg2);
default: return SQLITE_MISUSE;
}
+3 -1
View File
@@ -22,7 +22,8 @@ $(dir.top)/shell.c: $(SHELL_SRC) $(dir.top)/tool/mkshellc.tcl
$(MAKE) -C $(dir.top) shell.c
# /shell.c
########################################################################
# Additional CFLAGS for fiddle.wasm can be passed on the CLI using
# CFLAGS_FIDDLE="the flags".
EXPORTED_FUNCTIONS.fiddle := $(dir.tmp)/EXPORTED_FUNCTIONS.fiddle
fiddle.emcc-flags = \
$(emcc.cflags) $(emcc_opt_full) \
@@ -40,6 +41,7 @@ fiddle.emcc-flags = \
-sEXPORTED_FUNCTIONS=@$(abspath $(EXPORTED_FUNCTIONS.fiddle)) \
-sEXPORTED_RUNTIME_METHODS=FS,wasmMemory \
$(SQLITE_OPT) $(SHELL_OPT) \
$(CFLAGS_FIDDLE) \
-DSQLITE_SHELL_FIDDLE
# -D_POSIX_C_SOURCE is needed for strdup() with emcc
+25 -25
View File
@@ -1,5 +1,5 @@
C Fix\sa\sproblem\scausing\sbloom\sfilters\sto\sbe\sused\sless\sefficiently\sthan\sthey\smight\sbe.\sProblem\sreported\sby\sforum\spost\s[forum:/info/06c3f01da6\s|\s06c3f01da6].
D 2023-06-12T13:49:37.074
C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\snewbie-safe-aggregates\sbranch.
D 2023-06-12T14:26:29.636
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -496,14 +496,14 @@ F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057af
F ext/wasm/api/sqlite3-api-cleanup.js cc21e3486da748463e02bbe51e2464c6ac136587cdfd5aa00cd0b5385f6ca808
F ext/wasm/api/sqlite3-api-glue.js f1b2dcb944de5138bb5bd9a1559d2e76a4f3ec25260963d709e8237476688803
F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8
F ext/wasm/api/sqlite3-api-prologue.js 17f4ec398ba34c5c666fea8e8c4eb82064a35b302f2f2eb355283cd8d3f68ed5
F ext/wasm/api/sqlite3-api-prologue.js 248f6511c2cf489fb546d1fcebad1dbdca86f438052e8a2ec36a4c529c536345
F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
F ext/wasm/api/sqlite3-opfs-async-proxy.js 961bbc3ccc1fa4e91d6519a96e8811ad7ae60173bd969fee7775dacb6eee1da2
F ext/wasm/api/sqlite3-v-helper.js e5c202a9ecde9ef818536d3f5faf26c03a1a9f5192b1ddea8bdabf30d75ef487
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 05f2563ddebfdc7a0f0ac0eb7cb381bb72043299aae1600ba9367c12f52b3fcc
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
F ext/wasm/api/sqlite3-wasm.c 12a096d8e58a0af0589142bae5a3c27a0c7e19846755a1a37d2c206352fbedda
F ext/wasm/api/sqlite3-wasm.c 65e4c58924b862d91d5c39d45a89711b98b4c41dc8a604fb9802626616ed7def
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
@@ -524,7 +524,7 @@ F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2
F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef
F ext/wasm/dist.make 451fb1b732257849f6e898d2a862512a0401500ed369ef53bdfeddf9c77bc3b9
F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f
F ext/wasm/fiddle.make dbe36b90b8907ae28ecb9c0e9fd8389dbdaecf117ea4fb2ea33864bdfa498a94
F ext/wasm/fiddle.make 983f3d99cb4bc507365241c007f3da90cf41f5d0979e108f471a2303b15acf46
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
F ext/wasm/fiddle/fiddle-worker.js 163d6139a93fab4bcb72064923df050d4e7c0ff0d8aa061ce8776a6e75da8a10
F ext/wasm/fiddle/fiddle.js 974b995119ac443685d7d94d3b3c58c6a36540e9eb3fed7069d5653284071715
@@ -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 2f159d0e904fa695b76811719563e6a75b61d5932559cd9b5a157d8127c97668
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 c787788005c6a41cc485f28921170ccd273dfda796b08b0a0652349ad6a64e5e
F src/malloc.c 47b82c5daad557d9b963e3873e99c22570fb470719082c6658bf64e3012f7d23
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2
@@ -625,7 +625,7 @@ F src/os_win.c 79ff2345aafe92be324e8d9062050c6c5ae714c2db6b4b5334d7d28e70ea81e6
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 0dfe6a9c76ca8ad8eb91a3867dd20ba1f5c854bc5e9cd9cde62112bdee1822be
F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3
F src/parse.y 396bdbaa15c3a9b2e7ea693e2db19cab6c7bd4bdb64573b471f7ef0bdbbb5584
F src/parse.y b1ac02e59fdd76d7613c4d75855fb51854f6566c5aa2c372f94023a12d7945f7
F src/pcache.c 4cd4a0043167da9ba7e19b4d179a0e6354e7fe32c16f781ecf9bf0a5ff63b40b
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00
@@ -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 5b2139b3033927d1c637e8ea0c577186b356357266c36b3bde20cdbdc2a23da6
F src/shell.c.in 359a1436b4cd24f30d98dc1bd751333e1ec670a6e752ba047545739187ad2910
F src/sqlite.h.in 013691ac3ca4e9ff0581b38219655c2dd36dd2da78e7a9432f434392b5895380
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
F src/sqliteInt.h 924ddd5bd9dad8a499005c2c02a492c67dbe784feafbd78fdd70d712cf839499
F src/sqliteInt.h 4698b109255c3c1473b1a08d81a7a285298caeb9ebe7f24ea4f8324f3823e95b
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,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 30dcc872eb1c9549708009c86357826c4f15ffa17e379dab5cd4aec596643728
R 8fa511ba4ba667879117ad7eb3fe3aed
U dan
Z ade47def489e35af0b5e22db38de72cb
P 75a877a9239ef004e4249ab9379a7af8cbe7655e3cdf50b7349c14721cc6eca4 56d9bb7aa63043f5db4a1e5e8eefe46762dba433145807c6e27a8316f1d03d7a
R a8e291f0bb7bf096e9038a0b9d46fe27
U drh
Z 1a4a5f3b7226c9d2c51a9cd464864621
# Remove this line to create a well-formed Fossil manifest.
+1 -1
View File
@@ -1 +1 @@
56d9bb7aa63043f5db4a1e5e8eefe46762dba433145807c6e27a8316f1d03d7a
c8ef3b787419ccb70bceccc8c851ba357f85299c3fc0f972d6b73d4c4cb23c42
+37
View File
@@ -890,6 +890,15 @@ void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
#define exprSetHeight(y)
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
/*
** Set the error offset for an Expr node, if possible.
*/
void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){
if( pExpr==0 ) return;
if( NEVER(ExprUseWJoin(pExpr)) ) return;
pExpr->w.iOfst = iOfst;
}
/*
** This routine is the core allocator for Expr nodes.
**
@@ -6493,6 +6502,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 +6533,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;
+4
View 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 */
@@ -3356,6 +3357,9 @@ static int openDatabase(
#endif
#if defined(SQLITE_ENABLE_STMT_SCANSTATUS)
| SQLITE_StmtScanStatus
#endif
#if defined(SQLITE_STRICT_AGGREGATE)
| SQLITE_StrictAgg
#endif
;
sqlite3HashInit(&db->aCollSeq);
+8 -5
View File
@@ -655,14 +655,17 @@ selcollist(A) ::= sclp(A) scanpt(B) expr(X) scanpt(Z) as(Y). {
if( Y.n>0 ) sqlite3ExprListSetName(pParse, A, &Y, 1);
sqlite3ExprListSetSpan(pParse,A,B,Z);
}
selcollist(A) ::= sclp(A) scanpt STAR. {
selcollist(A) ::= sclp(A) scanpt STAR(X). {
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
sqlite3ExprSetErrorOffset(p, (int)(X.z - pParse->zTail));
A = sqlite3ExprListAppend(pParse, A, p);
}
selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR. {
Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
Expr *pLeft = tokenExpr(pParse, TK_ID, X);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR(Y). {
Expr *pRight, *pLeft, *pDot;
pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
sqlite3ExprSetErrorOffset(pRight, (int)(Y.z - pParse->zTail));
pLeft = tokenExpr(pParse, TK_ID, X);
pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
A = sqlite3ExprListAppend(pParse,A, pDot);
}
+15
View File
@@ -6108,10 +6108,16 @@ static int selectExpander(Walker *pWalker, Select *p){
** expanded. */
int tableSeen = 0; /* Set to 1 when TABLE matches */
char *zTName = 0; /* text of name of TABLE */
int iErrOfst;
if( pE->op==TK_DOT ){
assert( pE->pLeft!=0 );
assert( !ExprHasProperty(pE->pLeft, EP_IntValue) );
zTName = pE->pLeft->u.zToken;
assert( ExprUseWOfst(pE->pLeft) );
iErrOfst = pE->pRight->w.iOfst;
}else{
assert( ExprUseWOfst(pE) );
iErrOfst = pE->w.iOfst;
}
for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
Table *pTab = pFrom->pTab; /* Table for this data source */
@@ -6148,6 +6154,7 @@ static int selectExpander(Walker *pWalker, Select *p){
for(ii=0; ii<pUsing->nId; ii++){
const char *zUName = pUsing->a[ii].zName;
pRight = sqlite3Expr(db, TK_ID, zUName);
sqlite3ExprSetErrorOffset(pRight, iErrOfst);
pNew = sqlite3ExprListAppend(pParse, pNew, pRight);
if( pNew ){
struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
@@ -6220,6 +6227,7 @@ static int selectExpander(Walker *pWalker, Select *p){
}else{
pExpr = pRight;
}
sqlite3ExprSetErrorOffset(pExpr, iErrOfst);
pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
if( pNew==0 ){
break; /* OOM */
@@ -7872,6 +7880,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 ){
+1
View 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 },
+18 -1
View File
@@ -2486,6 +2486,22 @@ struct sqlite3_mem_methods {
** then 0 or 1 is written into the integer that the second argument points to
** depending on if the reverse scan order flag is set after processing the
** first argument.
**
** [[SQLITE_DBCONFIG_STRICT_AGGREGATE]]
** <dt>SQLITE_DBCONFIG_STRICT_AGGREGATE</dt>
** <dd>The SQLITE_DBCONFIG_STRICT_AGGREGATE disables the SQLite-specific
** enhancement that allows bare columns that are not mentioned in the GROUP BY
** clause and that are not contained within an aggregate function to appear
** in aggregate queries. With that enhancement disabled, SQLite works more like
** other SQL database engines such as PostgreSQL. The strict-aggregate flag
** is off by default, meaning that the enhanced capabilities of SQLite are
** enabled by default. This [sqlite3_db_config()] option takes
** two arguments which are an integer and a pointer to an integer. The first
** argument is 1, 0, or -1 to enable, disable, or leave unchanged the
** strict-aggregate flag, respectively. If the second argument is not NULL,
** then 0 or 1 is written into the integer that the second argument points to
** depending on if the strict-aggregate flag is set after processing the
** first argument.
** </dd>
**
** </dl>
@@ -2510,7 +2526,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
+6 -2
View 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
@@ -3023,6 +3024,8 @@ struct Expr {
*/
#define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0)
#define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0)
#define ExprUseWOfst(E) (((E)->flags&(EP_InnerON|EP_OuterON))==0)
#define ExprUseWJoin(E) (((E)->flags&(EP_InnerON|EP_OuterON))!=0)
#define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0)
#define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0)
#define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0)
@@ -5491,6 +5494,7 @@ void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
#define sqlite3SelectExprHeight(x) 0
#define sqlite3ExprCheckHeight(x,y)
#endif
void sqlite3ExprSetErrorOffset(Expr*,int);
u32 sqlite3Get4byte(const u8*);
void sqlite3Put4byte(u8*, u32);
+11 -1
View 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;
}
+7
View 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}
+32 -14
View 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.0 1.0}
} {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;
} {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
+2
View 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.
+14
View 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 |}
+8
View 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 {
+11 -3
View 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}
+15 -1
View 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
+1
View 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;