Skip to content

Commit

Permalink
Fix Analytic orderBy and partitionBy to follow the SQL documentation (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfcomp committed Aug 30, 2021
1 parent 9573fd0 commit 4c79ac1
Show file tree
Hide file tree
Showing 5 changed files with 204 additions and 175 deletions.
8 changes: 4 additions & 4 deletions lib/query/analytic.js
Expand Up @@ -18,7 +18,7 @@ class Analytic {
this.grouping = 'columns';
}

partitionBy(column) {
partitionBy(column, direction) {
assert(
Array.isArray(column) || typeof column === 'string',
`The argument to an analytic partitionBy function must be either a string
Expand All @@ -28,12 +28,12 @@ class Analytic {
if (Array.isArray(column)) {
this.partitions = this.partitions.concat(column);
} else {
this.partitions.push(column);
this.partitions.push({ column: column, order: direction });
}
return this;
}

orderBy(column) {
orderBy(column, direction) {
assert(
Array.isArray(column) || typeof column === 'string',
`The argument to an analytic orderBy function must be either a string
Expand All @@ -43,7 +43,7 @@ class Analytic {
if (Array.isArray(column)) {
this.order = this.order.concat(column);
} else {
this.order.push(column);
this.order.push({ column: column, order: direction });
}
return this;
}
Expand Down
15 changes: 9 additions & 6 deletions lib/query/querybuilder.js
Expand Up @@ -1247,15 +1247,18 @@ class Builder extends EventEmitter {
typeof second === 'function' ||
second.isRawInstance ||
Array.isArray(second) ||
typeof second === 'string',
typeof second === 'string' ||
typeof second === 'object',
`The second argument to an analytic function must be either a function, a raw,
an array of string or a single string.`
an array of string or object, an object or a single string.`
);

if (third) {
assert(
Array.isArray(third) || typeof third === 'string',
'The third argument to an analytic function must be either a string or an array of string.'
Array.isArray(third) ||
typeof third === 'string' ||
typeof third === 'object',
'The third argument to an analytic function must be either a string, an array of string or object or an object.'
);
}

Expand All @@ -1272,9 +1275,9 @@ class Builder extends EventEmitter {
alias: alias,
};
} else {
const order = typeof second === 'string' ? [second] : second;
const order = !Array.isArray(second) ? [second] : second;
let partitions = third || [];
partitions = typeof partitions === 'string' ? [partitions] : partitions;
partitions = !Array.isArray(partitions) ? [partitions] : partitions;
analytic = {
grouping: 'columns',
type: 'analytic',
Expand Down
8 changes: 6 additions & 2 deletions lib/query/querycompiler.js
Expand Up @@ -1035,13 +1035,17 @@ class QueryCompiler {
sql += 'partition by ';
sql +=
map(stmt.partitions, function (partition) {
return self.formatter.columnize(partition);
if (isString(partition)) {
return self.formatter.columnize(partition);
} else return self.formatter.columnize(partition.column) + (partition.order ? ' ' + partition.order : '');
}).join(', ') + ' ';
}

sql += 'order by ';
sql += map(stmt.order, function (order) {
return self.formatter.columnize(order);
if (isString(order)) {
return self.formatter.columnize(order);
} else return self.formatter.columnize(order.column) + (order.order ? ' ' + order.order : '');
}).join(', ');
}

Expand Down
23 changes: 23 additions & 0 deletions test/unit/query/builder.js
Expand Up @@ -7854,6 +7854,29 @@ describe('QueryBuilder', () => {
);
});

it('row_number with object', function () {
testsql(
qb()
.select('*')
.from('accounts')
.rowNumber(null, { column: 'email', order: 'asc' }, [
{ column: 'address', order: 'asc' },
'phone',
]),
{
mssql: {
sql: 'select *, row_number() over (partition by [address] asc, [phone] order by [email] asc) from [accounts]',
},
pg: {
sql: 'select *, row_number() over (partition by "address" asc, "phone" order by "email" asc) from "accounts"',
},
oracledb: {
sql: 'select *, row_number() over (partition by "address" asc, "phone" order by "email" asc) from "accounts"',
},
}
);
});

it('row_number with string', function () {
testsql(
qb().select('*').from('accounts').rowNumber(null, 'email', 'address'),
Expand Down

0 comments on commit 4c79ac1

Please sign in to comment.