Skip to content

Commit ec7831f

Browse files
Copilotmathiasrw
andauthored
Add multi-column user-defined aggregate functions to close #1966 (#2396)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com> Co-authored-by: M. Wulff <m@rawu.dk>
1 parent d90bccd commit ec7831f

File tree

5 files changed

+892
-461
lines changed

5 files changed

+892
-461
lines changed

src/38query.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,19 @@ function queryfn3(query) {
123123
if (query.aggrKeys.length > 0) {
124124
var gfns = '';
125125
query.aggrKeys.forEach(function (col) {
126+
// For multi-column aggregates, pass undefined for each column parameter
127+
var undefinedArgs = '';
128+
if (col.args && col.args.length > 1) {
129+
// Multi-column: pass undefined for each argument, then accumulator, then stage
130+
undefinedArgs = Array(col.args.length).fill('undefined').join(',') + ',';
131+
} else {
132+
// Single column: pass undefined, accumulator, stage
133+
undefinedArgs = 'undefined,';
134+
}
126135
gfns += `
127136
g[${JSON.stringify(col.nick)}] = alasql.aggr[${JSON.stringify(
128137
col.funcid
129-
)}](undefined,g[${JSON.stringify(col.nick)}],3); `;
138+
)}](${undefinedArgs}g[${JSON.stringify(col.nick)}],3); `;
130139
});
131140
var gfn = new Function('g,params,alasql', 'var y;' + gfns);
132141
}

src/423groupby.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,15 @@ yy.Select.prototype.compileGroup = function (query) {
164164
} else if (col.aggregatorid === 'REDUCE') {
165165
query.aggrKeys.push(col);
166166
const extraParams = getGroupConcatParams(col);
167-
return `'${colas}':alasql.aggr['${col.funcid}'](${colexp},undefined,1${extraParams}),`;
167+
// Support multiple arguments for user-defined aggregates
168+
if (col.args && col.args.length > 1) {
169+
// Multiple arguments - pass all of them
170+
let argExpressions = col.args.map(arg => arg.toJS('p', tableid, defcols)).join(',');
171+
return `'${colas}':alasql.aggr['${col.funcid}'](${argExpressions},undefined,1${extraParams}),`;
172+
} else {
173+
// Single argument - backward compatibility
174+
return `'${colas}':alasql.aggr['${col.funcid}'](${colexp},undefined,1${extraParams}),`;
175+
}
168176
}
169177
return '';
170178
}
@@ -435,11 +443,20 @@ yy.Select.prototype.compileGroup = function (query) {
435443
${post}`;
436444
} else if (col.aggregatorid === 'REDUCE') {
437445
const extraParams = getGroupConcatParams(col);
438-
return `${pre}
439-
g['${colas}'] = alasql.aggr.${col.funcid}(${colexp},g['${colas}'],2${extraParams});
440-
${post}`;
446+
// Support multiple arguments for user-defined aggregates
447+
if (col.args && col.args.length > 1) {
448+
// Multiple arguments - pass all of them
449+
let argExpressions = col.args.map(arg => arg.toJS('p', tableid, defcols)).join(',');
450+
return `${pre}
451+
g['${colas}'] = alasql.aggr.${col.funcid}(${argExpressions},g['${colas}'],2${extraParams});
452+
${post}`;
453+
} else {
454+
// Single argument - backward compatibility
455+
return `${pre}
456+
g['${colas}'] = alasql.aggr.${col.funcid}(${colexp},g['${colas}'],2${extraParams});
457+
${post}`;
458+
}
441459
}
442-
443460
return '';
444461
}
445462

src/alasqlparser.jison

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,7 @@ Aggregator
14621462
| AGGR { $$ = "AGGR"; }
14631463
| ARRAY { $$ = "ARRAY"; }
14641464
| GROUP_CONCAT { $$ = "GROUP_CONCAT"; }
1465+
| CORR { $$ = "CORR"; }
14651466
/* | REDUCE { $$ = "REDUCE"; } */
14661467
;
14671468

@@ -1474,7 +1475,7 @@ FuncValue
14741475
$$ = new yy.FuncValue({funcid: funcid, args: exprlist, over: $6});
14751476
} else if(alasql.aggr[$1]) {
14761477
$$ = new yy.AggrValue({aggregatorid: 'REDUCE',
1477-
funcid: funcid, expression: exprlist.pop(),distinct:($3=='DISTINCT'), over: $6 });
1478+
funcid: funcid, expression: exprlist[0], args: exprlist, distinct:($3=='DISTINCT'), over: $6 });
14781479
} else {
14791480
$$ = new yy.FuncValue({funcid: funcid, args: exprlist, over: $6});
14801481
};

0 commit comments

Comments
 (0)