aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2008-06-18 15:34:09 +0000
committerdrh <drh@noemail.net>2008-06-18 15:34:09 +0000
commita2baf3a2e5014ade006960374f76c72c5fd23a50 (patch)
tree63967666fc99bd75b4f5b742ad6e63b219c5efdc /src
parent56a40a801094b02b6b8db84eaa7dca51e9e81895 (diff)
downloadsqlite-a2baf3a2e5014ade006960374f76c72c5fd23a50.tar.gz
sqlite-a2baf3a2e5014ade006960374f76c72c5fd23a50.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/func.c25
-rw-r--r--src/vdbeaux.c10
2 files changed, 18 insertions, 17 deletions
diff --git a/src/func.c b/src/func.c
index bb2ba4900..014d0af7f 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 <ctype.h>
@@ -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<argc-1 );
}
}
static void groupConcatFinalize(sqlite3_context *context){
@@ -1275,8 +1279,7 @@ void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
{ "avg", 1, 0, 0, sumStep, avgFinalize },
{ "count", 0, 0, 0, countStep, countFinalize },
{ "count", 1, 0, 0, countStep, countFinalize },
- { "group_concat", 1, 0, 0, groupConcatStep, groupConcatFinalize },
- { "group_concat", 2, 0, 0, groupConcatStep, groupConcatFinalize },
+ { "group_concat", -1, 0, 0, groupConcatStep, groupConcatFinalize },
};
int i;
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index cb670edf5..8f82ee04f 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -14,7 +14,7 @@
** 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.
**
-** $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 <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++){
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;