mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Ensure that queries like "SELECT indeterministic(a) FROM tbl GROUP BY 1" invoke the indeterministic function only once for each row of tbl.
FossilOrigin-Name: 4555d66547e28cb110e1012b145bcf3aafb5d4bde05e9d27bcb4ca33837b28f5
This commit is contained in:
23
manifest
23
manifest
@ -1,5 +1,5 @@
|
||||
C Add\sthe\sstmtrand()\sextension\sfunction\sfor\suse\sin\stesting.
|
||||
D 2024-05-24T14:16:06.243
|
||||
C Ensure\sthat\squeries\slike\s"SELECT\sindeterministic(a)\sFROM\stbl\sGROUP\sBY\s1"\sinvoke\sthe\sindeterministic\sfunction\sonly\sonce\sfor\seach\srow\sof\stbl.
|
||||
D 2024-05-24T18:31:39.505
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -705,7 +705,7 @@ F src/date.c 126ba2ab10aeb2e7ba6e089b5f07b747c0625b8287f78b60da346eda8d23c875
|
||||
F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
|
||||
F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43
|
||||
F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500
|
||||
F src/expr.c 50e71ed518f1b1ba8401006922a309e200d205b2ca5b93d6fd8a006a336dbf67
|
||||
F src/expr.c 585109ab97149b2d484697e7469f28c91d495cd1330cc760d24711b7be8d22fb
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c 852f93c0ef995e0c2b8983059a2b97151c194cc8259e21f5bc2b7ac508348c2a
|
||||
F src/func.c f1f57c6863c1380f31ecf3d61732495bfff847a8e35a832c7e306e310db5a799
|
||||
@ -755,12 +755,12 @@ F src/printf.c 8b250972305e14b365561be5117ed0fd364e4fd58968776df1ce64c6280b90f9
|
||||
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
|
||||
F src/resolve.c 22f1fa3423b377c02ae78d451cfeb1c2d96dcf0389c0642cbdcd19d3bfd7ae01
|
||||
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
|
||||
F src/select.c 1a841c38974d45cf15a7611398479182b61ad4c187423c380741d8b1688fe607
|
||||
F src/select.c cbdaf9cb2d9a697ee9ce1484f27d2e96762d33cc19259aedfb818a68b9d3be10
|
||||
F src/shell.c.in 31249f26684467e95e529915bf486961c535ae8288ed7e79890cc9ed3d781d8f
|
||||
F src/sqlite.h.in c71d9ef76a6d32dc7ff2d373f2e57ce09056af26c1457bcadae5358b7628c7c3
|
||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
|
||||
F src/sqliteInt.h 6a9fa3902c9faca2b57060e822f2afadfbf96d64c4ede81e201f0e0c42d7e4aa
|
||||
F src/sqliteInt.h 98ba756789b37f8d8217407ce077c31faf0b9b21d593b327c2b9667ad5bea1ac
|
||||
F src/sqliteLimit.h 6878ab64bdeb8c24a1d762d45635e34b96da21132179023338c93f820eee6728
|
||||
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
|
||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||
@ -1074,7 +1074,7 @@ F test/descidx2.test a0ba347037ff3b811f4c6ceca5fd0f9d5d72e74e59f2d9de346a9d2f6ad
|
||||
F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a1999b926
|
||||
F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e
|
||||
F test/distinct.test 691c9e850b0d0b56b66e7e235453198cb4cf0760e324b7403d3c5abbeab0a014
|
||||
F test/distinct2.test bb71cc7b5e58e895787f9910a788c254f679928d324732d063fe9bc202ecbe71
|
||||
F test/distinct2.test c936bb8652258c04bf066706284f5cd54ec693817399dbd6503c49d41ace626e
|
||||
F test/distinctagg.test 40d7169ae5846caaf62c6e307d2ca3c333daf9b6f7cde888956a339a97afe85f
|
||||
F test/e_blobbytes.test 4c01dfe4f12087b92b20705a3fdfded45dc4ed16d5a211fed4e1d2786ba68a52
|
||||
F test/e_blobclose.test 692fc02a058476c2222a63d97e3f3b2b809c1842e5525ded7f854d540ac2e075
|
||||
@ -2193,8 +2193,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 b8442d2a6012b1f2e15381613267db0982e36bb4c748b15b56e668e0d0a3d0d2
|
||||
R 01f61db2371d56efe0fc89de21914b9a
|
||||
U drh
|
||||
Z 5bafe7bbe2cfe723081ab4c42a45e0a5
|
||||
P 5c97a5b9d163b1c427e002f3734687ca0384bc0da6a90fc4bfd358c654d3a7b3
|
||||
R 5fdf8e25d08374c3b6caf60dac9645e5
|
||||
T *branch * group-by-consistency
|
||||
T *sym-group-by-consistency *
|
||||
T -sym-trunk *
|
||||
U dan
|
||||
Z 5149149f75ab1db4d2d6bfcada9a5ce2
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
5c97a5b9d163b1c427e002f3734687ca0384bc0da6a90fc4bfd358c654d3a7b3
|
||||
4555d66547e28cb110e1012b145bcf3aafb5d4bde05e9d27bcb4ca33837b28f5
|
@ -4243,7 +4243,7 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
|
||||
** register iReg. The caller must ensure that iReg already contains
|
||||
** the correct value for the expression.
|
||||
*/
|
||||
static void exprToRegister(Expr *pExpr, int iReg){
|
||||
void sqlite3ExprToRegister(Expr *pExpr, int iReg){
|
||||
Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr);
|
||||
if( NEVER(p==0) ) return;
|
||||
p->op2 = p->op;
|
||||
@ -5252,7 +5252,7 @@ expr_code_doover:
|
||||
break;
|
||||
}
|
||||
testcase( pX->op==TK_COLUMN );
|
||||
exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
|
||||
sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
|
||||
testcase( regFree1==0 );
|
||||
memset(&opCompare, 0, sizeof(opCompare));
|
||||
opCompare.op = TK_EQ;
|
||||
@ -5602,7 +5602,7 @@ static void exprCodeBetween(
|
||||
compRight.op = TK_LE;
|
||||
compRight.pLeft = pDel;
|
||||
compRight.pRight = pExpr->x.pList->a[1].pExpr;
|
||||
exprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
|
||||
sqlite3ExprToRegister(pDel, exprCodeVector(pParse, pDel, ®Free1));
|
||||
if( xJump ){
|
||||
xJump(pParse, &exprAnd, dest, jumpIfNull);
|
||||
}else{
|
||||
|
14
src/select.c
14
src/select.c
@ -7847,12 +7847,18 @@ int sqlite3Select(
|
||||
*/
|
||||
if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
|
||||
&& sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0
|
||||
&& OptimizationEnabled(db, SQLITE_GroupByOrder)
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
&& p->pWin==0
|
||||
#endif
|
||||
){
|
||||
p->selFlags &= ~SF_Distinct;
|
||||
pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0);
|
||||
if( pGroupBy ){
|
||||
for(i=0; i<pGroupBy->nExpr; i++){
|
||||
pGroupBy->a[i].u.x.iOrderByCol = i+1;
|
||||
}
|
||||
}
|
||||
p->selFlags |= SF_Aggregate;
|
||||
/* Notice that even thought SF_Distinct has been cleared from p->selFlags,
|
||||
** the sDistinct.isTnct is still set. Hence, isTnct represents the
|
||||
@ -8315,12 +8321,18 @@ int sqlite3Select(
|
||||
sortOut, sortPTab);
|
||||
}
|
||||
for(j=0; j<pGroupBy->nExpr; j++){
|
||||
int iOrderByCol = pGroupBy->a[j].u.x.iOrderByCol;
|
||||
|
||||
if( groupBySort ){
|
||||
sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
|
||||
}else{
|
||||
pAggInfo->directMode = 1;
|
||||
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
|
||||
}
|
||||
|
||||
if( iOrderByCol ){
|
||||
sqlite3ExprToRegister(p->pEList->a[iOrderByCol-1].pExpr, iAMem+j);
|
||||
}
|
||||
}
|
||||
sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
|
||||
(char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
|
||||
@ -8336,9 +8348,9 @@ int sqlite3Select(
|
||||
** and resets the aggregate accumulator registers in preparation
|
||||
** for the next GROUP BY batch.
|
||||
*/
|
||||
sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
|
||||
VdbeComment((v, "output one row"));
|
||||
sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
|
||||
sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v);
|
||||
VdbeComment((v, "check abort flag"));
|
||||
sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
|
||||
|
@ -5025,6 +5025,7 @@ void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int);
|
||||
int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8);
|
||||
void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int);
|
||||
void sqlite3ExprCodeMove(Parse*, int, int, int);
|
||||
void sqlite3ExprToRegister(Expr *pExpr, int iReg);
|
||||
void sqlite3ExprCode(Parse*, Expr*, int);
|
||||
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
|
||||
void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int);
|
||||
|
@ -313,4 +313,27 @@ do_execsql_test 4020 {
|
||||
SELECT b FROM t1 UNION SELECT 1;
|
||||
} {1 { }}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 5010 {
|
||||
CREATE TABLE cnt(a);
|
||||
WITH RECURSIVE cnt2(x) AS (
|
||||
VALUES(1) UNION ALL SELECT x+1 FROM cnt2 WHERE x<50
|
||||
)
|
||||
INSERT INTO cnt SELECT x FROM cnt2;
|
||||
}
|
||||
|
||||
do_execsql_test 5020 {
|
||||
SELECT DISTINCT abs(random())%5 AS r FROM cnt ORDER BY r;
|
||||
} {0 1 2 3 4}
|
||||
|
||||
do_execsql_test 5030 {
|
||||
SELECT abs(random())%5 AS r FROM cnt GROUP BY 1 ORDER BY 1;
|
||||
} {0 1 2 3 4}
|
||||
|
||||
do_execsql_test 5040 {
|
||||
SELECT a FROM cnt WHERE a>45 GROUP BY 1;
|
||||
} {46 47 48 49 50}
|
||||
|
||||
finish_test
|
||||
|
Reference in New Issue
Block a user