Skip to content

Commit a7edde0

Browse files
authored
Merge pull request #150 from paustint/bug-149
GROUP BY does not allow multiple functions #149
2 parents d73d379 + 1a2abd2 commit a7edde0

File tree

11 files changed

+9342
-277
lines changed

11 files changed

+9342
-277
lines changed

CHANGELOG.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,143 @@
11
# Changelog
22

3+
## 4.0.0
4+
5+
April 13, 20201
6+
7+
💥 Breaking Changes 💥
8+
9+
Release 4.x has changed the way the `groupBy` and `having` clauses are parsed. (#149)
10+
Previously, the `groupBy` clause only allowed multiple entries for fields, but not functions.
11+
12+
The `groupBy` and `orderBy` are now always returned as arrays from parsed queries to normalize the returned data structure.
13+
14+
For backwards compatibility, a single `groupBy` or `orderBy` object is allowed to be passed in to `composeQuery()`, but a parsed query will always return an array.
15+
16+
The `Query` object now has
17+
18+
- A list of group by clauses (a single groupBy clause is allowed if you build the data structure yourself)
19+
- A Having clause (this was previously nested in the groupBy clause)
20+
- A list of orderBy clauses (a single orderBy clause is allowed if you build the data structure yourself)
21+
22+
```diff
23+
-groupBy?: GroupByClause;
24+
+groupBy?: GroupByClause | GroupByClause[]; // a parsed query will always be undefined or an array
25+
+having?: HavingClause;
26+
orderBy?: OrderByClause | OrderByClause[]; // a parsed query will always be undefined or an array
27+
```
28+
29+
Each groupBy clause
30+
31+
- No longer has a nested having clause
32+
- Is an object with a single `field` or `fn` property
33+
34+
```diff
35+
type GroupByClause = GroupByFieldClause | GroupByFnClause;
36+
37+
-interface GroupByOptionalFieldsClause {
38+
- having?: HavingClause;
39+
-}
40+
41+
-interface GroupByFieldClause extends GroupByOptionalFieldsClause {
42+
+interface GroupByFieldClause {
43+
- field: string | string[];
44+
+ field: string;
45+
}
46+
47+
-interface GroupByFnClause extends GroupByOptionalFieldsClause {
48+
+interface GroupByFnClause {
49+
fn: FunctionExp;
50+
}
51+
```
52+
53+
Here are a few examples of how the `groupBy` is parsed or expected when composing a query:
54+
55+
`SELECT UserId, CALENDAR_MONTH(LoginTime) month FROM LoginHistory WHERE NetworkId != NULL GROUP BY UserId, CALENDAR_MONTH(LoginTime)`
56+
57+
```javascript
58+
{
59+
fields: [
60+
{
61+
type: 'Field',
62+
field: 'UserId',
63+
},
64+
{
65+
type: 'FieldFunctionExpression',
66+
functionName: 'CALENDAR_MONTH',
67+
rawValue: 'CALENDAR_MONTH(LoginTime)',
68+
parameters: ['LoginTime'],
69+
alias: 'month',
70+
},
71+
],
72+
sObject: 'LoginHistory',
73+
where: {
74+
left: {
75+
field: 'NetworkId',
76+
operator: '!=',
77+
literalType: 'NULL',
78+
value: 'NULL',
79+
},
80+
},
81+
groupBy: [
82+
{ field: 'UserId' },
83+
{
84+
fn: {
85+
functionName: 'CALENDAR_MONTH',
86+
rawValue: 'CALENDAR_MONTH(LoginTime)',
87+
parameters: ['LoginTime'],
88+
},
89+
},
90+
],
91+
}
92+
```
93+
94+
`SELECT ProductCode FROM Product2 GROUP BY ProductCode HAVING COUNT(Id) > 1 ORDER BY COUNT(Id) DESC`
95+
96+
```javascript
97+
{
98+
fields: [{ type: 'Field', field: 'ProductCode' }],
99+
sObject: 'Product2',
100+
groupBy: [{
101+
field: 'ProductCode',
102+
}],
103+
having: {
104+
left: {
105+
operator: '>',
106+
value: '1',
107+
literalType: 'INTEGER',
108+
fn: { rawValue: 'COUNT(Id)', functionName: 'COUNT', parameters: ['Id'] },
109+
},
110+
},
111+
orderBy: [{
112+
fn: { rawValue: 'COUNT(Id)', functionName: 'COUNT', parameters: ['Id'] },
113+
order: 'DESC',
114+
}],
115+
}
116+
```
117+
118+
`SELECT SBQQ__Product__r.Name foo, SBQQ__Quote__c foo1 FROM SBQQ__Quoteline__c GROUP BY SBQQ__Quote__c, SBQQ__Product__r.Name`
119+
120+
```javascript
121+
{
122+
fields: [
123+
{
124+
type: 'FieldRelationship',
125+
field: 'Name',
126+
relationships: ['SBQQ__Product__r'],
127+
rawValue: 'SBQQ__Product__r.Name',
128+
alias: 'foo',
129+
},
130+
{
131+
type: 'Field',
132+
field: 'SBQQ__Quote__c',
133+
alias: 'foo1',
134+
},
135+
],
136+
sObject: 'SBQQ__Quoteline__c',
137+
groupBy: [{ field: 'SBQQ__Quote__c' }, { field: 'SBQQ__Product__r.Name' }],
138+
}
139+
```
140+
3141
## 3.2.0
4142

5143
March 27, 2021

0 commit comments

Comments
 (0)