mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Make sure aggregate functions can take any number of arguments up to the
limit imposed by SQLITE_LIMIT_FUNCTION_ARGS. Ticket #3179. Modify the group_concat() function to take an unlimited number of arguments in order to facilitate testing this behavior. (CVS 5233) FossilOrigin-Name: 70c6739f4e84b3433e14960346b54d0e9e0bb9c6
This commit is contained in:
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\sdocumentation\son\sthe\ssqlite3_mutex_methods\sobject.\s(CVS\s5232)
|
C Make\ssure\saggregate\sfunctions\scan\stake\sany\snumber\sof\sarguments\sup\sto\sthe\nlimit\simposed\sby\sSQLITE_LIMIT_FUNCTION_ARGS.\s\sTicket\s#3179.\s\sModify\nthe\sgroup_concat()\sfunction\sto\stake\san\sunlimited\snumber\sof\sarguments\sin\norder\sto\sfacilitate\stesting\sthis\sbehavior.\s(CVS\s5233)
|
||||||
D 2008-06-18T13:47:04
|
D 2008-06-18T15:34:10
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in dc5608df93faf4406cfd7a1c8ed9ab93d8bfbfd5
|
F Makefile.in dc5608df93faf4406cfd7a1c8ed9ab93d8bfbfd5
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@ -106,7 +106,7 @@ F src/date.c bbc4114d1b946d6a94d060bc5b9edce7142c6086
|
|||||||
F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b
|
F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b
|
||||||
F src/expr.c ecb3b23d3543427cba3e2ac12a6c6ae4bb20d39b
|
F src/expr.c ecb3b23d3543427cba3e2ac12a6c6ae4bb20d39b
|
||||||
F src/fault.c 1f6177188edb00641673e462f3fab8cba9f7422b
|
F src/fault.c 1f6177188edb00641673e462f3fab8cba9f7422b
|
||||||
F src/func.c 6ebd44016c5a6c6d5dd9fe4cbbef2bd517313d0d
|
F src/func.c 1e7d9569570134ac0771a00382d9d4b41c4aa052
|
||||||
F src/global.c 2304cfa3288763bd2fed10caf8c6fbaa2b383f4e
|
F src/global.c 2304cfa3288763bd2fed10caf8c6fbaa2b383f4e
|
||||||
F src/hash.c 283864c1adf546d4f0a6ee3694b62beeda8fbd35
|
F src/hash.c 283864c1adf546d4f0a6ee3694b62beeda8fbd35
|
||||||
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53
|
||||||
@ -185,7 +185,7 @@ F src/vdbe.c f6866986de706b98c2738040bc65907728650e8d
|
|||||||
F src/vdbe.h 1e3722d471739c2b213c6283b60373290e52f7ea
|
F src/vdbe.h 1e3722d471739c2b213c6283b60373290e52f7ea
|
||||||
F src/vdbeInt.h de321b2c02593e1420106634ed1f5a7d77ad35a7
|
F src/vdbeInt.h de321b2c02593e1420106634ed1f5a7d77ad35a7
|
||||||
F src/vdbeapi.c 22b01ed175e4d4c613ee82cabc7a44a275641206
|
F src/vdbeapi.c 22b01ed175e4d4c613ee82cabc7a44a275641206
|
||||||
F src/vdbeaux.c 34b9478ea0c8b41a6dbce6b1bb1c392c87bb0264
|
F src/vdbeaux.c 09d7a6923d4d71d7028e0d72b9d146d3ece6054e
|
||||||
F src/vdbeblob.c 9345f6dcd675fdcfdb537d2d2f487542d9ea136a
|
F src/vdbeblob.c 9345f6dcd675fdcfdb537d2d2f487542d9ea136a
|
||||||
F src/vdbefifo.c c46dae1194e4277bf007144d7e5b0c0b1c24f136
|
F src/vdbefifo.c c46dae1194e4277bf007144d7e5b0c0b1c24f136
|
||||||
F src/vdbemem.c a39a822e6ae61c4cab4a512df4a315888b206911
|
F src/vdbemem.c a39a822e6ae61c4cab4a512df4a315888b206911
|
||||||
@ -330,7 +330,7 @@ F test/fts3ao.test 0aa29dd4fc1c8d46b1f7cfe5926f7ac97551bea9
|
|||||||
F test/fts3atoken.test 25c2070e1e8755d414bf9c8200427b277a9f99fa
|
F test/fts3atoken.test 25c2070e1e8755d414bf9c8200427b277a9f99fa
|
||||||
F test/fts3b.test b3a25180a633873d37d86e1ccd00ed690d37237a
|
F test/fts3b.test b3a25180a633873d37d86e1ccd00ed690d37237a
|
||||||
F test/fts3near.test 2d4dadcaac5025ab65bb87e66c45f39e92966194
|
F test/fts3near.test 2d4dadcaac5025ab65bb87e66c45f39e92966194
|
||||||
F test/func.test b9f4cd2171891c258d025b10413024bb9ebcf068
|
F test/func.test 2c929a20e15b4d9121890393a892e91b74fe9fda
|
||||||
F test/fuzz.test 62fc19dd36a427777fd671b569df07166548628a
|
F test/fuzz.test 62fc19dd36a427777fd671b569df07166548628a
|
||||||
F test/fuzz2.test ea38692ce2da99ad79fe0be5eb1a452c1c4d37bb
|
F test/fuzz2.test ea38692ce2da99ad79fe0be5eb1a452c1c4d37bb
|
||||||
F test/fuzz_common.tcl ff4bc2dfc465f6878f8e2d819620914365382731
|
F test/fuzz_common.tcl ff4bc2dfc465f6878f8e2d819620914365382731
|
||||||
@ -596,7 +596,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
|
|||||||
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||||
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
P e36201a352f832c97c5c0fcb872c1f094cac03d2
|
P c3c7bfc9db6774824be14a1394e1842716dce8ec
|
||||||
R 8648cd5178619fc653bfd259b7c7bae3
|
R 03ee4502eba907b49b63dcad3c223959
|
||||||
U drh
|
U drh
|
||||||
Z 67e332d2264b741dc268059d30026b9b
|
Z 84afc1583f0d4ac82122bd3650c7f8b5
|
||||||
|
@ -1 +1 @@
|
|||||||
c3c7bfc9db6774824be14a1394e1842716dce8ec
|
70c6739f4e84b3433e14960346b54d0e9e0bb9c6
|
25
src/func.c
25
src/func.c
@ -16,7 +16,7 @@
|
|||||||
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
|
** sqliteRegisterBuildinFunctions() found at the bottom of the file.
|
||||||
** All other code has file scope.
|
** All other code has file scope.
|
||||||
**
|
**
|
||||||
** $Id: func.c,v 1.193 2008/06/15 02:51:47 drh Exp $
|
** $Id: func.c,v 1.194 2008/06/18 15:34:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -1166,8 +1166,8 @@ static void groupConcatStep(
|
|||||||
const char *zVal;
|
const char *zVal;
|
||||||
StrAccum *pAccum;
|
StrAccum *pAccum;
|
||||||
const char *zSep;
|
const char *zSep;
|
||||||
int nVal, nSep;
|
int nVal, nSep, i;
|
||||||
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
|
if( argc==0 || sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
|
||||||
pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
|
pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
|
||||||
|
|
||||||
if( pAccum ){
|
if( pAccum ){
|
||||||
@ -1175,18 +1175,22 @@ static void groupConcatStep(
|
|||||||
pAccum->useMalloc = 1;
|
pAccum->useMalloc = 1;
|
||||||
pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
|
pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
|
||||||
if( pAccum->nChar ){
|
if( pAccum->nChar ){
|
||||||
if( argc==2 ){
|
if( argc>1 ){
|
||||||
zSep = (char*)sqlite3_value_text(argv[1]);
|
zSep = (char*)sqlite3_value_text(argv[argc-1]);
|
||||||
nSep = sqlite3_value_bytes(argv[1]);
|
nSep = sqlite3_value_bytes(argv[argc-1]);
|
||||||
}else{
|
}else{
|
||||||
zSep = ",";
|
zSep = ",";
|
||||||
nSep = 1;
|
nSep = 1;
|
||||||
}
|
}
|
||||||
sqlite3StrAccumAppend(pAccum, zSep, nSep);
|
sqlite3StrAccumAppend(pAccum, zSep, nSep);
|
||||||
}
|
}
|
||||||
zVal = (char*)sqlite3_value_text(argv[0]);
|
i = 0;
|
||||||
nVal = sqlite3_value_bytes(argv[0]);
|
do{
|
||||||
sqlite3StrAccumAppend(pAccum, zVal, nVal);
|
zVal = (char*)sqlite3_value_text(argv[i]);
|
||||||
|
nVal = sqlite3_value_bytes(argv[i]);
|
||||||
|
sqlite3StrAccumAppend(pAccum, zVal, nVal);
|
||||||
|
i++;
|
||||||
|
}while( i<argc-1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void groupConcatFinalize(sqlite3_context *context){
|
static void groupConcatFinalize(sqlite3_context *context){
|
||||||
@ -1275,8 +1279,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
|
|||||||
{ "avg", 1, 0, 0, sumStep, avgFinalize },
|
{ "avg", 1, 0, 0, sumStep, avgFinalize },
|
||||||
{ "count", 0, 0, 0, countStep, countFinalize },
|
{ "count", 0, 0, 0, countStep, countFinalize },
|
||||||
{ "count", 1, 0, 0, countStep, countFinalize },
|
{ "count", 1, 0, 0, countStep, countFinalize },
|
||||||
{ "group_concat", 1, 0, 0, groupConcatStep, groupConcatFinalize },
|
{ "group_concat", -1, 0, 0, groupConcatStep, groupConcatFinalize },
|
||||||
{ "group_concat", 2, 0, 0, groupConcatStep, groupConcatFinalize },
|
|
||||||
};
|
};
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
** to version 2.8.7, all this code was combined into the vdbe.c source file.
|
** to version 2.8.7, all this code was combined into the vdbe.c source file.
|
||||||
** But that file was getting too big so this subroutines were split out.
|
** But that file was getting too big so this subroutines were split out.
|
||||||
**
|
**
|
||||||
** $Id: vdbeaux.c,v 1.387 2008/06/15 02:51:48 drh Exp $
|
** $Id: vdbeaux.c,v 1.388 2008/06/18 15:34:10 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -270,15 +270,13 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
|
|||||||
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
|
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
|
||||||
u8 opcode = pOp->opcode;
|
u8 opcode = pOp->opcode;
|
||||||
|
|
||||||
if( opcode==OP_Function ){
|
if( opcode==OP_Function || opcode==OP_AggStep ){
|
||||||
if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
|
if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
|
||||||
}else if( opcode==OP_AggStep
|
|
||||||
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
#ifndef SQLITE_OMIT_VIRTUALTABLE
|
||||||
|| opcode==OP_VUpdate
|
}else if( opcode==OP_VUpdate ){
|
||||||
#endif
|
|
||||||
){
|
|
||||||
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
|
if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if( opcode==OP_Halt ){
|
if( opcode==OP_Halt ){
|
||||||
if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){
|
if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){
|
||||||
doesStatementRollback = 1;
|
doesStatementRollback = 1;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
# This file implements regression tests for SQLite library. The
|
# This file implements regression tests for SQLite library. The
|
||||||
# focus of this file is testing built-in functions.
|
# focus of this file is testing built-in functions.
|
||||||
#
|
#
|
||||||
# $Id: func.test,v 1.78 2008/04/16 12:58:54 drh Exp $
|
# $Id: func.test,v 1.79 2008/06/18 15:34:10 drh Exp $
|
||||||
|
|
||||||
set testdir [file dirname $argv0]
|
set testdir [file dirname $argv0]
|
||||||
source $testdir/tester.tcl
|
source $testdir/tester.tcl
|
||||||
@ -929,6 +929,18 @@ do_test func-24.6 {
|
|||||||
SELECT 'BEGIN-'||group_concat(t1) FROM tbl1
|
SELECT 'BEGIN-'||group_concat(t1) FROM tbl1
|
||||||
}
|
}
|
||||||
} {BEGIN-this,program,is,free,software}
|
} {BEGIN-this,program,is,free,software}
|
||||||
|
set midargs {}
|
||||||
|
set midres {}
|
||||||
|
for {set i 1} {$i<[sqlite3_limit db SQLITE_LIMIT_FUNCTION_ARG -1]-1} {incr i} {
|
||||||
|
append midargs ,'/$i'
|
||||||
|
append midres /$i
|
||||||
|
set result \
|
||||||
|
"this$midres:program$midres:is$midres:free$midres:software$midres"
|
||||||
|
set sql "SELECT group_concat(t1$midargs,':') FROM tbl1"
|
||||||
|
do_test func-24.7.$i {
|
||||||
|
db eval $::sql
|
||||||
|
} $result
|
||||||
|
}
|
||||||
|
|
||||||
# Use the test_isolation function to make sure that type conversions
|
# Use the test_isolation function to make sure that type conversions
|
||||||
# on function arguments do not effect subsequent arguments.
|
# on function arguments do not effect subsequent arguments.
|
||||||
|
Reference in New Issue
Block a user