Repository: paustint/soql-parser-js (ts)

Issue:
Date functions should be allowed in where clause
- [ ] Feature
- [x] Bug

<!--If this is a bug, please include the steps to reproduce the bug-->
## Description

Date functions throw and error are not parsed when used in a `WHERE` clause.

https://developer.salesforce.com/docs/atlas.en-us.soql_sosl.meta/soql_sosl/sforce_api_calls_soql_select_date_functions.htm

Example query:
`SELECT Id, convertCurrency(Amount) FROM Opportunity WHERE Amount > 0 AND CALENDAR_YEAR(CloseDate) = 2020`

Pull request description:
Date functions should be allowed in where clause #100
Updated date functions to allow use within a WHERE clause

resolves #100

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ba4aeb5..eac1923 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## 2.5.1
+
+April 23, 2020
+
+1. Queries with date functions in a WHERE clause would throw an error when parsing. (#100)
+
 ## 2.5.0
 
 April 3, 2020
diff --git a/src/parser/parser.ts b/src/parser/parser.ts
index db0aa7c..5d15618 100644
--- a/src/parser/parser.ts
+++ b/src/parser/parser.ts
@@ -494,6 +494,7 @@ export class SoqlParser extends CstParser {
       this.OR1([
         { GATE: () => alowAggregateFn, ALT: () => this.SUBRULE(this.aggregateFunction, { LABEL: 'lhs' }) },
         { GATE: () => allowLocationFn, ALT: () => this.SUBRULE(this.locationFunction, { LABEL: 'lhs' }) },
+        { ALT: () => this.SUBRULE(this.dateFunction, { LABEL: 'lhs' }) },
         { ALT: () => this.SUBRULE(this.otherFunction, { LABEL: 'lhs' }) },
         { ALT: () => this.CONSUME(lexer.Identifier, { LABEL: 'lhs' }) },
       ]);


Test patch:
diff --git a/test/test-cases.ts b/test/test-cases.ts
index 4fe3207..cd4bafc 100644
--- a/test/test-cases.ts
+++ b/test/test-cases.ts
@@ -1837,6 +1837,43 @@ export const testCases: TestCase[] = [
       },
     },
   },
+  {
+    testCase: 100,
+    soql: `SELECT Id, convertCurrency(Amount) FROM Opportunity WHERE Amount > 0 AND CALENDAR_YEAR(CloseDate) = 2020`,
+    output: {
+      fields: [
+        { type: 'Field', field: 'Id' },
+        {
+          type: 'FieldFunctionExpression',
+          functionName: 'convertCurrency',
+          rawValue: 'convertCurrency(Amount)',
+          parameters: ['Amount'],
+        },
+      ],
+      sObject: 'Opportunity',
+      where: {
+        left: {
+          field: 'Amount',
+          literalType: 'INTEGER',
+          operator: '>',
+          value: '0',
+        },
+        operator: 'AND',
+        right: {
+          left: {
+            operator: '=',
+            value: '2020',
+            literalType: 'INTEGER',
+            fn: {
+              functionName: 'CALENDAR_YEAR',
+              parameters: ['CloseDate'],
+              rawValue: 'CALENDAR_YEAR(CloseDate)',
+            },
+          },
+        },
+      },
+    },
+  },
 ];
 
 export default testCases;
diff --git a/test/test.spec.ts b/test/test.spec.ts
index 6bd8cf7..e7ebfa2 100644
--- a/test/test.spec.ts
+++ b/test/test.spec.ts
@@ -11,7 +11,7 @@ const replacements = [{ matching: / last /i, replace: ' LAST ' }];
 // Uncomment these to easily test one specific query - useful for troubleshooting/bugfixing
 
 // describe.only('parse queries', () => {
-//   const testCase = testCases.find(tc => tc.testCase === 99);
+//   const testCase = testCases.find(tc => tc.testCase === 100);
 //   it(`should correctly parse test case ${testCase.testCase} - ${testCase.soql}`, () => {
 //     const soqlQuery = parseQuery(testCase.soql, testCase.options);
 //     const soqlQueryWithoutUndefinedProps = JSON.parse(JSON.stringify(soqlQuery));