jetstreamapp / soql-parser-js

Javascript SOQL parser
https://jetstreamapp.github.io/soql-parser-js/
MIT License
77 stars 20 forks source link

Date functions should be allowed in ORDER BY clause #139

Closed 0x17h closed 3 years ago

0x17h commented 3 years ago

Description

SOQL parser dislikes some functions in 'ORDER BY' and throws the error: "Redundant input, expecting EOF but found: (". Although the query is completely valid: you can execute it in Salesforce developer console and observe, that objects are ordered.

Steps to reproduce

Execute the following query:

SELECT WEEK_IN_YEAR(CloseDate), SUM(amount)
FROM Opportunity 
GROUP BY WEEK_IN_YEAR(CloseDate)
ORDER BY WEEK_IN_YEAR(CloseDate)

Affected versions

Observed behavior

Parser throws "Redundant input, expecting EOF but found: (" for 'WEEK_IN_YEAR' function call in 'ORDER BY' clause

Expected behavior

Query is parsed and parsing result contains something like this:

{
  ...
  "orderBy": {
    "fn": {
      "functionName": "WEEK_IN_YEAR",
      "parameters": [
        "CloseDate"
      ],
      "rawValue": "WEEK_IN_YEAR(CloseDate)"
    },
  ...
}
paustint commented 3 years ago

Thank you for reporting this, I will try to investigate and resolve in the next few days.

paustint commented 3 years ago

@0x17h - I have resolved this bug and have released the changes to two new versions 2.5.6 and 3.0.2. All date functions are now parsed properly in order by causes.

These test-cases have been added, which also generate the examples for the documentation.

Thanks again for the detailed bug report!

[{
    testCase: 106,
    soql: `SELECT WEEK_IN_YEAR(CloseDate), SUM(amount) FROM Opportunity GROUP BY WEEK_IN_YEAR(CloseDate) ORDER BY WEEK_IN_YEAR(CloseDate)`,
    output: {
      fields: [
        {
          type: 'FieldFunctionExpression',
          functionName: 'WEEK_IN_YEAR',
          parameters: ['CloseDate'],
          rawValue: 'WEEK_IN_YEAR(CloseDate)',
        },
        {
          type: 'FieldFunctionExpression',
          functionName: 'SUM',
          parameters: ['amount'],
          isAggregateFn: true,
          rawValue: 'SUM(amount)',
        },
      ],
      sObject: 'Opportunity',
      groupBy: {
        fn: {
          functionName: 'WEEK_IN_YEAR',
          parameters: ['CloseDate'],
          rawValue: 'WEEK_IN_YEAR(CloseDate)',
        },
      },
      orderBy: {
        fn: {
          functionName: 'WEEK_IN_YEAR',
          parameters: ['CloseDate'],
          rawValue: 'WEEK_IN_YEAR(CloseDate)',
        },
      },
    },
  },
  {
    testCase: 107,
    soql: `SELECT WEEK_IN_YEAR(CloseDate), SUM(amount) FROM Opportunity GROUP BY WEEK_IN_YEAR(CloseDate) ORDER BY WEEK_IN_YEAR(CloseDate) DESC NULLS FIRST`,
    output: {
      fields: [
        {
          type: 'FieldFunctionExpression',
          functionName: 'WEEK_IN_YEAR',
          parameters: ['CloseDate'],
          rawValue: 'WEEK_IN_YEAR(CloseDate)',
        },
        {
          type: 'FieldFunctionExpression',
          functionName: 'SUM',
          parameters: ['amount'],
          isAggregateFn: true,
          rawValue: 'SUM(amount)',
        },
      ],
      sObject: 'Opportunity',
      groupBy: {
        fn: {
          functionName: 'WEEK_IN_YEAR',
          parameters: ['CloseDate'],
          rawValue: 'WEEK_IN_YEAR(CloseDate)',
        },
      },
      orderBy: {
        fn: {
          functionName: 'WEEK_IN_YEAR',
          parameters: ['CloseDate'],
          rawValue: 'WEEK_IN_YEAR(CloseDate)',
        },
        order: 'DESC',
        nulls: 'FIRST',
      },
    },
  },
  {
    testCase: 108,
    soql: `SELECT WEEK_IN_YEAR(CloseDate), SUM(amount) FROM Opportunity GROUP BY WEEK_IN_YEAR(CloseDate) ORDER BY WEEK_IN_YEAR(CloseDate) DESC NULLS LAST, SUM(amount) ASC NULLS LAST`,
    output: {
      fields: [
        {
          type: 'FieldFunctionExpression',
          functionName: 'WEEK_IN_YEAR',
          parameters: ['CloseDate'],
          rawValue: 'WEEK_IN_YEAR(CloseDate)',
        },
        {
          type: 'FieldFunctionExpression',
          functionName: 'SUM',
          parameters: ['amount'],
          isAggregateFn: true,
          rawValue: 'SUM(amount)',
        },
      ],
      sObject: 'Opportunity',
      groupBy: {
        fn: {
          functionName: 'WEEK_IN_YEAR',
          parameters: ['CloseDate'],
          rawValue: 'WEEK_IN_YEAR(CloseDate)',
        },
      },
      orderBy: [
        {
          fn: {
            functionName: 'WEEK_IN_YEAR',
            parameters: ['CloseDate'],
            rawValue: 'WEEK_IN_YEAR(CloseDate)',
          },
          order: 'DESC',
          nulls: 'LAST',
        },
        {
          fn: {
            functionName: 'SUM',
            parameters: ['amount'],
            rawValue: 'SUM(amount)',
          },
          order: 'ASC',
          nulls: 'LAST',
        },
      ],
    },
  },
]
0x17h commented 3 years ago

@paustint Thank you so much for such a quick response and fix! Outstanding support from your side