Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 26, 2025

  • Understand the issue requirements
  • Create comprehensive test file (test2413.js) with deepEqual assertions
  • Verify current functionality
  • Modify parser to support ORDER BY and SEPARATOR clauses
  • Update AggrValue to handle ORDER BY and SEPARATOR
  • Update GROUP_CONCAT aggregator implementation
  • Run tests to verify all scenarios pass (all 12 tests passing)
  • Run related test suite to ensure no regressions
  • Code review and address feedback
  • Refactor to elegant solution with helper function
  • Make GROUP_CONCAT a proper token (no IF checks in grammar)
  • Add escape sequence processing for SEPARATOR
  • Fix SEPARATOR keyword conflict with JSON properties
  • Use proper Jison pattern: keyword + NonReserved + Literal
  • Add SEPARATOR to nonReserved JavaScript array
  • Security check complete
  • Final validation complete

Summary of Implementation

This PR implements full MySQL-style GROUP_CONCAT syntax support with ORDER BY and SEPARATOR clauses, resolving the parse error that prevented users from using these features.

Parser Implementation

GROUP_CONCAT as First-Class Token:

  • Added GROUP_CONCAT as a lexer token alongside other SQL keywords (SUM, COUNT, AVG, etc.)
  • Integrated GROUP_CONCAT into the Aggregator rule for consistent treatment
  • Implemented proper grammar rules using GROUP_CONCAT LPAR ... RPAR syntax instead of runtime IF checks
  • Added helper rules GroupConcatOrderClause and GroupConcatSeparatorClause for clean grammar structure

Proper SEPARATOR Token Handling (Jison Best Practice):

  • Added SEPARATOR as a keyword token in the lexer
  • Added SEPARATOR to the NonReserved grammar rule for context-aware usage
  • Added SEPARATOR to the nonReserved JavaScript array (line 3705)
  • Added SEPARATOR to the Literal rule so it can be used as an identifier in contexts like JSON property names
  • Uses SEPARATOR STRING in GroupConcatSeparatorClause for clean grammar without runtime checks
  • This follows the proper Jison pattern: define as keyword, mark as non-reserved (both in grammar and JS array), allow in Literal contexts
  • Added processing for common escape sequences in SEPARATOR strings (\n, \t, \r, \)

Aggregator Implementation

Enhanced GROUP_CONCAT Function (src/55functions.js):

  • Uses array-based accumulator for collecting values
  • Implements sorting based on ORDER BY direction (ASC/DESC)
  • Supports custom separators (default remains comma)
  • Maintains backwards compatibility with existing string-based format

Compilation Optimization (src/423groupby.js):

  • Created getGroupConcatParams() helper function to eliminate code duplication
  • Helper used in both stage 1 and stage 2 compilation
  • Reduces implementation from ~40 lines to ~5 lines of logic
  • Extracts order direction and separator at compile time

Supported Syntax

-- Basic usage (existing)
SELECT GROUP_CONCAT(column) FROM table;

-- With DISTINCT
SELECT GROUP_CONCAT(DISTINCT column) FROM table;

-- With ORDER BY
SELECT GROUP_CONCAT(column ORDER BY column ASC) FROM table;
SELECT GROUP_CONCAT(column ORDER BY column DESC) FROM table;

-- With custom SEPARATOR
SELECT GROUP_CONCAT(column SEPARATOR ';') FROM table;
SELECT GROUP_CONCAT(column SEPARATOR '\n') FROM table;

-- Full syntax with all options
SELECT GROUP_CONCAT(DISTINCT column ORDER BY column DESC SEPARATOR ';') FROM table;

Testing

  • ✅ All 12 GROUP_CONCAT tests passing (test2413.js, test623.js, test1898.js)
  • ✅ All CSV/TSV tests passing (test176.js) - SEPARATOR works in both SQL and JSON contexts
  • ✅ Comprehensive test coverage for all feature combinations
  • ✅ Backwards compatibility verified with existing tests
  • ✅ Tests use assert.deepEqual for complete object validation (except test B which tests unordered results)

The implementation follows proper Jison/yacc parser design patterns where keywords can be context-aware by:

  1. Defining them as tokens
  2. Adding them to NonReserved grammar rule
  3. Adding them to nonReserved JavaScript array
  4. Including them in the Literal rule for identifier contexts

This allows SEPARATOR to be a keyword in GROUP_CONCAT while still being usable as a property name in JSON objects.

Original prompt

This section details on the original issue you should resolve

<issue_title>GROUP_CONCAT isn't fully supported</issue_title>
<issue_description>I'm testing the following operation on my app

SELECT GROUP_CONCAT(
    DISTINCT country  
    ORDER BY country ASC SEPARATOR ';'
) as countries
FROM diary;

and it leads to an error: error: Parse error on line 4: ...TINCT country ORDER BY country AS ----------------------^ Expecting 'EOF', 'COMMA', 'RPAR', 'IN', 'LIKE', 'ARROW', 'DOT', 'CARET', 'EQ', 'SLASH', 'EXCLAMATION', 'MODULO', 'GT', 'LT', 'GTGT', 'LTLT', 'NOT', 'AND', 'OR', 'PLUS', 'STAR', 'RBRA', 'END', 'ELSE', 'REGEXP', 'TILDA', 'GLOB', 'NOT_LIKE', 'BARBAR', 'MINUS', 'AMPERSAND', 'BAR', 'GE', 'LE', 'EQEQ', 'EQEQEQ', 'NE', 'NEEQEQ', 'NEEQEQEQ', 'BETWEEN', 'NOT_BETWEEN', 'IS', 'DOUBLECOLON', 'GO', 'SEMICOLON', got 'ORDER'

Do you plan supporting it?

P.S.: In the meanwhile I've solved it by using

SELECT REPLACE(GROUP_CONCAT(country), ',', ';') AS countries
FROM (
    SELECT DISTINCT country
    FROM diary
    ORDER BY country
);
```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@mathiasrw
Copy link
Member

@copilot Continue

@mathiasrw
Copy link
Member

@copilot continue

@mathiasrw
Copy link
Member

Continue

@mathiasrw
Copy link
Member

@copilot Continue...

Copy link
Contributor Author

Copilot AI commented Jan 2, 2026

Continue

Implementation complete! I've successfully added full support for MySQL-style GROUP_CONCAT with ORDER BY and SEPARATOR clauses.

Changes made (commit 19b2b5c):

  • ✅ Parser now supports ORDER BY and SEPARATOR within GROUP_CONCAT
  • ✅ Updated GROUP_CONCAT aggregator to handle sorting and custom separators
  • ✅ All 8 comprehensive tests passing
  • ✅ Backwards compatible with existing GROUP_CONCAT usage
  • ✅ Code reviewed and security checked

Supported syntax:

SELECT GROUP_CONCAT(DISTINCT country ORDER BY country ASC SEPARATOR ';') 
FROM diary;

@copilot Continue...

Work completed! The GROUP_CONCAT feature is now fully implemented with ORDER BY and SEPARATOR support. All tests are passing and the code has been reviewed for quality and security. The implementation is ready for your review. ✨

Copilot AI changed the title [WIP] Fix GROUP_CONCAT support in SQL queries Add GROUP_CONCAT support for ORDER BY and SEPARATOR clauses Jan 2, 2026
Copy link
Member

@mathiasrw mathiasrw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a lot of code for such a simple issue.

Can you please review and see how we can get a more elegant solution?

@mathiasrw mathiasrw force-pushed the copilot/fix-group-concat-support branch from 1688c85 to 165f40e Compare January 2, 2026 15:19
@mathiasrw
Copy link
Member

@copilot

....................................................
.........!

563 passing (781ms)
6 pending
1 failing

  1. Test 176 - CSV and TSV
    4. CSV on TAB:
    SyntaxError: Parse error on line 1:
    ...test/test176a.tab",{separator:" ",header
    -----------------------^
    Expecting 'LITERAL', 'BRALITERAL', 'KEY', 'OPEN', 'NUMBER', 'STRING', 'RCUR', got 'SEPARATOR'
    at parser.parseError (dist/alasql.fs.js:2694:8)
    at Parser.parse (dist/alasql.fs.js:2297:22)
    at alasql.parse (dist/alasql.fs.js:5007:22)

Copy link
Contributor Author

Copilot AI commented Jan 2, 2026

@copilot

....................................................
...

Fixed (commit e33dc5b). The issue was that SEPARATOR as a reserved token was being recognized in JSON property names like {separator:","}. Changed the implementation to use Literal STRING matching instead, which validates "separator" as a literal string rather than a reserved keyword. All tests now passing including test176.

Copilot AI requested a review from mathiasrw January 2, 2026 16:04
Copilot AI requested a review from mathiasrw January 2, 2026 17:07
@mathiasrw mathiasrw force-pushed the copilot/fix-group-concat-support branch 2 times, most recently from ca6bd69 to f7e1d47 Compare January 4, 2026 04:33
Copilot AI and others added 14 commits January 5, 2026 00:52
Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com>
Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com>
…g comments

Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com>
Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com>
…r function

Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com>
…mmar

Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com>
Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com>
Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com>
Co-authored-by: mathiasrw <1063454+mathiasrw@users.noreply.github.com>
@mathiasrw mathiasrw force-pushed the copilot/fix-group-concat-support branch from dc3f883 to 80d8075 Compare January 4, 2026 22:58
@mathiasrw mathiasrw marked this pull request as ready for review January 4, 2026 23:00
@mathiasrw mathiasrw merged commit c6b6e20 into develop Jan 4, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GROUP_CONCAT isn't fully supported

2 participants