Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions src/40select.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ yy.Select = class Select {
// todo?: 3. Compile SELECT clause
// For ROWNUM()
query.rownums = [];
query.grouprownums = [];

this.compileSelectGroup0(query);

Expand Down Expand Up @@ -371,6 +372,46 @@ yy.Select = class Select {
}
}

// Handle GROUP_ROW_NUMBER() and ROW_NUMBER() OVER (PARTITION BY ...) - restart numbering when grouping column(s) change
if (query.grouprownums && query.grouprownums.length > 0) {
for (var j = 0, jlen = query.grouprownums.length; j < jlen; j++) {
var config = query.grouprownums[j];
var partitionColumns;

// Determine which columns to partition by
if (config.partitionColumns && config.partitionColumns.length > 0) {
// Use explicit PARTITION BY columns
partitionColumns = config.partitionColumns;
} else {
// Fall back to first column for GROUP_ROW_NUMBER()
var columnKeys = Object.keys(res[0] || {});
partitionColumns = [columnKeys[0]];
}

var prevValues = null;
var rowNum = 0;

for (var i = 0, ilen = res.length; i < ilen; i++) {
// Get current partition key (combination of all partition columns)
var currentValues = partitionColumns
.map(function (col) {
return res[i][col];
})
.join('|');

// Reset counter when partition changes
if (i === 0 || currentValues !== prevValues) {
rowNum = 1;
} else {
rowNum++;
}

res[i][config.as] = rowNum;
prevValues = currentValues;
}
}
}

var res2 = modify(query, res);

if (cb) {
Expand Down
17 changes: 16 additions & 1 deletion src/424select.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,22 @@ yy.Select.prototype.compileSelectGroup0 = function (query) {
col.funcid &&
(col.funcid.toUpperCase() === 'ROWNUM' || col.funcid.toUpperCase() === 'ROW_NUMBER')
) {
query.rownums.push(col.as);
// Check if this has OVER clause with PARTITION BY
if (col.over && col.over.partition) {
// Window function with partition - track for post-processing
query.grouprownums.push({
as: col.as,
partitionColumns: col.over.partition.map(function (p) {
return p.columnid || p.toString();
}),
});
} else {
// Regular ROW_NUMBER without partition
query.rownums.push(col.as);
}
}
if (col.funcid && col.funcid.toUpperCase() === 'GROUP_ROW_NUMBER') {
query.grouprownums.push({as: col.as, columnIndex: 0}); // Track which column to use for grouping
}
// console.log("colas:",colas);
// }
Expand Down
9 changes: 9 additions & 0 deletions src/55functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ yy.FuncValue.prototype.toString = function () {
}
s += ')';
}

// Add OVER clause if present
if (this.over) {
s += ' ' + this.over.toString();
}

return s;
};

Expand Down Expand Up @@ -249,6 +255,9 @@ stdlib.ROWNUM = function () {
stdlib.ROW_NUMBER = function () {
return '1';
};
stdlib.GROUP_ROW_NUMBER = function () {
return '1';
};

stdlib.SQRT = function (s) {
return 'Math.sqrt(' + s + ')';
Expand Down
12 changes: 6 additions & 6 deletions src/alasqlparser.jison
Original file line number Diff line number Diff line change
Expand Up @@ -1377,21 +1377,21 @@ Aggregator
;

FuncValue
: Literal LPAR (DISTINCT|ALL)? ExprList RPAR
: Literal LPAR (DISTINCT|ALL)? ExprList RPAR OverClause
{
var funcid = $1;
var exprlist = $4;
if(exprlist.length > 1 && (funcid.toUpperCase() == 'MIN' || funcid.toUpperCase() == 'MAX')) {
$$ = new yy.FuncValue({funcid: funcid, args: exprlist});
$$ = new yy.FuncValue({funcid: funcid, args: exprlist, over: $6});
} else if(alasql.aggr[$1]) {
$$ = new yy.AggrValue({aggregatorid: 'REDUCE',
funcid: funcid, expression: exprlist.pop(),distinct:($3=='DISTINCT') });
funcid: funcid, expression: exprlist.pop(),distinct:($3=='DISTINCT'), over: $6 });
} else {
$$ = new yy.FuncValue({funcid: funcid, args: exprlist});
$$ = new yy.FuncValue({funcid: funcid, args: exprlist, over: $6});
};
}
| Literal LPAR RPAR
{ $$ = new yy.FuncValue({ funcid: $1 }) }
| Literal LPAR RPAR OverClause
{ $$ = new yy.FuncValue({ funcid: $1, over: $4 }) }
| IF LPAR ExprList RPAR
{ $$ = new yy.FuncValue({ funcid: 'IIF', args:$3 }) }
| REPLACE LPAR ExprList RPAR
Expand Down
Loading
Loading