From a2baf3a2e5014ade006960374f76c72c5fd23a50 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 18 Jun 2008 15:34:09 +0000 Subject: [PATCH] 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 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/func.c | 25 ++++++++++++++----------- src/vdbeaux.c | 10 ++++------ test/func.test | 14 +++++++++++++- 5 files changed, 40 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index dfabee5476..bf2af3b858 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sdocumentation\son\sthe\ssqlite3_mutex_methods\sobject.\s(CVS\s5232) -D 2008-06-18T13:47:04 +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-18T15:34:10 F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7 F Makefile.in dc5608df93faf4406cfd7a1c8ed9ab93d8bfbfd5 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -106,7 +106,7 @@ F src/date.c bbc4114d1b946d6a94d060bc5b9edce7142c6086 F src/delete.c d3fc5987f2eb88f7b9549d58a5dfea079a83fe8b F src/expr.c ecb3b23d3543427cba3e2ac12a6c6ae4bb20d39b F src/fault.c 1f6177188edb00641673e462f3fab8cba9f7422b -F src/func.c 6ebd44016c5a6c6d5dd9fe4cbbef2bd517313d0d +F src/func.c 1e7d9569570134ac0771a00382d9d4b41c4aa052 F src/global.c 2304cfa3288763bd2fed10caf8c6fbaa2b383f4e F src/hash.c 283864c1adf546d4f0a6ee3694b62beeda8fbd35 F src/hash.h 031cd9f915aff27e12262cb9eb570ac1b8326b53 @@ -185,7 +185,7 @@ F src/vdbe.c f6866986de706b98c2738040bc65907728650e8d F src/vdbe.h 1e3722d471739c2b213c6283b60373290e52f7ea F src/vdbeInt.h de321b2c02593e1420106634ed1f5a7d77ad35a7 F src/vdbeapi.c 22b01ed175e4d4c613ee82cabc7a44a275641206 -F src/vdbeaux.c 34b9478ea0c8b41a6dbce6b1bb1c392c87bb0264 +F src/vdbeaux.c 09d7a6923d4d71d7028e0d72b9d146d3ece6054e F src/vdbeblob.c 9345f6dcd675fdcfdb537d2d2f487542d9ea136a F src/vdbefifo.c c46dae1194e4277bf007144d7e5b0c0b1c24f136 F src/vdbemem.c a39a822e6ae61c4cab4a512df4a315888b206911 @@ -330,7 +330,7 @@ F test/fts3ao.test 0aa29dd4fc1c8d46b1f7cfe5926f7ac97551bea9 F test/fts3atoken.test 25c2070e1e8755d414bf9c8200427b277a9f99fa F test/fts3b.test b3a25180a633873d37d86e1ccd00ed690d37237a F test/fts3near.test 2d4dadcaac5025ab65bb87e66c45f39e92966194 -F test/func.test b9f4cd2171891c258d025b10413024bb9ebcf068 +F test/func.test 2c929a20e15b4d9121890393a892e91b74fe9fda F test/fuzz.test 62fc19dd36a427777fd671b569df07166548628a F test/fuzz2.test ea38692ce2da99ad79fe0be5eb1a452c1c4d37bb F test/fuzz_common.tcl ff4bc2dfc465f6878f8e2d819620914365382731 @@ -596,7 +596,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P e36201a352f832c97c5c0fcb872c1f094cac03d2 -R 8648cd5178619fc653bfd259b7c7bae3 +P c3c7bfc9db6774824be14a1394e1842716dce8ec +R 03ee4502eba907b49b63dcad3c223959 U drh -Z 67e332d2264b741dc268059d30026b9b +Z 84afc1583f0d4ac82122bd3650c7f8b5 diff --git a/manifest.uuid b/manifest.uuid index 404b912aef..a733e649ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c3c7bfc9db6774824be14a1394e1842716dce8ec \ No newline at end of file +70c6739f4e84b3433e14960346b54d0e9e0bb9c6 \ No newline at end of file diff --git a/src/func.c b/src/func.c index bb2ba49005..014d0af7f4 100644 --- a/src/func.c +++ b/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** 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 @@ -1166,8 +1166,8 @@ static void groupConcatStep( const char *zVal; StrAccum *pAccum; const char *zSep; - int nVal, nSep; - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + int nVal, nSep, i; + if( argc==0 || sqlite3_value_type(argv[0])==SQLITE_NULL ) return; pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); if( pAccum ){ @@ -1175,18 +1175,22 @@ static void groupConcatStep( pAccum->useMalloc = 1; pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; if( pAccum->nChar ){ - if( argc==2 ){ - zSep = (char*)sqlite3_value_text(argv[1]); - nSep = sqlite3_value_bytes(argv[1]); + if( argc>1 ){ + zSep = (char*)sqlite3_value_text(argv[argc-1]); + nSep = sqlite3_value_bytes(argv[argc-1]); }else{ zSep = ","; nSep = 1; } sqlite3StrAccumAppend(pAccum, zSep, nSep); } - zVal = (char*)sqlite3_value_text(argv[0]); - nVal = sqlite3_value_bytes(argv[0]); - sqlite3StrAccumAppend(pAccum, zVal, nVal); + i = 0; + do{ + zVal = (char*)sqlite3_value_text(argv[i]); + nVal = sqlite3_value_bytes(argv[i]); + sqlite3StrAccumAppend(pAccum, zVal, nVal); + i++; + }while( i @@ -270,15 +270,13 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ u8 opcode = pOp->opcode; - if( opcode==OP_Function ){ + if( opcode==OP_Function || opcode==OP_AggStep ){ if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5; - }else if( opcode==OP_AggStep #ifndef SQLITE_OMIT_VIRTUALTABLE - || opcode==OP_VUpdate -#endif - ){ + }else if( opcode==OP_VUpdate ){ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; } +#endif if( opcode==OP_Halt ){ if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){ doesStatementRollback = 1; diff --git a/test/func.test b/test/func.test index 7ab6c04b29..67ab7f6557 100644 --- a/test/func.test +++ b/test/func.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # 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] source $testdir/tester.tcl @@ -929,6 +929,18 @@ do_test func-24.6 { SELECT 'BEGIN-'||group_concat(t1) FROM tbl1 } } {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 # on function arguments do not effect subsequent arguments.