Skip to content

Conversation

@martin-georgiev
Copy link
Owner

@martin-georgiev martin-georgiev commented Mar 29, 2025

Summary by CodeRabbit

  • New Features
    • Introduced a unified base for aggregate functions, enhancing consistency and flexibility.
  • Refactor
    • Streamlined aggregation behavior for array, JSON, and JSONB functions, including refined parameter handling.
  • Tests
    • Expanded test scenarios to cover varied SQL and query language cases, ensuring broader compatibility and reliability.

@martin-georgiev martin-georgiev enabled auto-merge (squash) March 29, 2025 02:41
@coveralls
Copy link

Coverage Status

coverage: 93.097%. remained the same
when pulling 67cc64f on json_agg-and-jsonb_agg
into 3c46021 on main.

@coderabbitai
Copy link

coderabbitai bot commented Mar 29, 2025

Walkthrough

This pull request refactors aggregate function classes within the Doctrine ORM query AST. The ArrayAgg, JsonAgg, and JsonbAgg classes now extend a new abstract class, BaseAggregateFunction, replacing their previous inheritance from BaseFunction. The ArrayAgg class has had its parsing and SQL generation methods removed, while JsonAgg and JsonbAgg have updated their function prototypes to support additional parameters. Additionally, tests for JSON aggregation functions now cover a broader set of SQL and DQL scenarios.

Changes

File(s) Change Summary
src/.../ArrayAgg.php Updated to extend BaseAggregateFunction; removed the parse and getSql methods; eliminated ordering and distinct trait usage.
src/.../JsonAgg.php and src/.../JsonbAgg.php Modified to extend BaseAggregateFunction; updated the customizeFunction method to adjust the function prototype strings for enhanced parameter handling.
src/.../BaseAggregateFunction.php New abstract class added that extends BaseFunction and incorporates OrderableTrait and DistinctableTrait; defines parse and getSql methods to standardize aggregate function processing.
tests/.../JsonAggTest.php and tests/.../JsonbAggTest.php Expanded test cases to include multiple SQL and DQL statements, ensuring broader coverage of aggregation scenarios.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant QueryParser
    participant AggregateFunction as BaseAggregateFunction
    Client->>QueryParser: Submit DQL query
    QueryParser->>AggregateFunction: Instantiate aggregate function (ArrayAgg/JsonAgg/JsonbAgg)
    AggregateFunction->>AggregateFunction: Parse function specifics
    AggregateFunction->>AggregateFunction: Generate SQL via getSql method
    AggregateFunction-->>QueryParser: Return SQL statement
    QueryParser->>Client: Deliver final SQL query
Loading

Possibly related PRs

Poem

Hopping along, I proudly declare,
A new class base with traits to share.
Array, Json, and Jsonb now unite,
Parsing and SQL in a unified light.
With tests expanded and structure so tight,
CodeRabbit hops on into the night!
🐇✨


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3c46021 and 67cc64f.

📒 Files selected for processing (6)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayAgg.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseAggregateFunction.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonAgg.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbAgg.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonAggTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbAggTest.php (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/**/*.php`: Use the PostgreSQL official documentation to verify that tests include comprehensive use cases and example SQL que...

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/**/*.php: Use the PostgreSQL official documentation to verify that tests include comprehensive use cases and example SQL queries for the tested SQL functions and operators.

  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbAggTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonAggTest.php
🧠 Learnings (1)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayAgg.php (1)
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#267
File: src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayAgg.php:30-37
Timestamp: 2025-03-26T16:52:34.228Z
Learning: In Doctrine ORM, the `OrderByClause->dispatch()` method already includes the complete "ORDER BY" phrase with proper spacing when converting DQL to SQL. No additional spacing is needed when using this method's output in SQL string construction.
🧬 Code Definitions (6)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbAgg.php (6)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseAggregateFunction.php (1)
  • BaseAggregateFunction (20-52)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayAgg.php (1)
  • customizeFunction (17-21)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonAgg.php (1)
  • customizeFunction (17-21)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/StringAgg.php (1)
  • customizeFunction (31-36)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonObjectAgg.php (1)
  • customizeFunction (17-22)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbObjectAgg.php (1)
  • customizeFunction (17-22)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseAggregateFunction.php (3)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayAgg.php (1)
  • customizeFunction (17-21)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonAgg.php (1)
  • customizeFunction (17-21)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbAgg.php (1)
  • customizeFunction (17-21)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbAggTest.php (2)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonAggTest.php (1)
  • getDqlStatements (33-45)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayAggTest.php (1)
  • getDqlStatements (35-49)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayAgg.php (1)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseAggregateFunction.php (1)
  • BaseAggregateFunction (20-52)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonAggTest.php (2)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbAggTest.php (1)
  • getDqlStatements (33-45)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayAggTest.php (1)
  • getDqlStatements (35-49)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonAgg.php (6)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseAggregateFunction.php (1)
  • BaseAggregateFunction (20-52)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayAgg.php (1)
  • customizeFunction (17-21)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbAgg.php (1)
  • customizeFunction (17-21)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/StringAgg.php (1)
  • customizeFunction (31-36)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonObjectAgg.php (1)
  • customizeFunction (17-22)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbObjectAgg.php (1)
  • customizeFunction (17-22)
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: PHP 8.2 + Doctrine ORM latest + Doctrine Lexer latest
  • GitHub Check: PHP 8.4 + Doctrine ORM latest + Doctrine Lexer latest
  • GitHub Check: PHP 8.4 + Doctrine ORM 3.0 + Doctrine Lexer latest
  • GitHub Check: PHP 8.4 + Doctrine ORM latest + Doctrine Lexer 2.1
  • GitHub Check: PHP 8.3 + Doctrine ORM 2.14 + Doctrine Lexer 2.1
  • GitHub Check: PHP 8.1 + Doctrine ORM latest + Doctrine Lexer latest
  • GitHub Check: sloth
🔇 Additional comments (13)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbAgg.php (2)

15-15: Migration to BaseAggregateFunction looks good.

Switching from BaseFunction to BaseAggregateFunction aligns JsonbAgg with the rest of the custom aggregate functions and leverages shared order/distinct parsing logic.


19-19: Expanded function prototype supports DISTINCT/ORDER BY.

Using jsonb_agg(%s%s%s) enables passing optional DISTINCT and ORDER BY clauses. Please ensure your test coverage includes scenarios that exercise these optional parameters.

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseAggregateFunction.php (4)

1-19: General structure and documentation are clear.

Declaring strict_types, setting up the namespace, and author-level docblocks are done correctly. This introduction of a base abstract class is a solid step toward code reuse and consistency across various aggregation functions.


20-23: Well-chosen traits promote extensibility.

By extending BaseFunction and using OrderableTrait and DistinctableTrait, you elegantly centralize the DISTINCT and ORDER BY logic. This approach keeps the subclass implementations concise.


25-40: Parsing logic is comprehensive.

Your parse method systematically handles different Doctrine versions, parentheses, DISTINCT, the main string expression, and optional ORDER BY clauses. This approach reduces duplicate logic across individual aggregate functions.


42-51: SQL generation aligns with the function prototype.

The getSql method dispatches all optional segments and formats them using \vsprintf. This design is clean and readable. Confirm via tests that each placeholder (distinct expression, main argument, order by clause) renders as expected in various combinations.

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonAgg.php (2)

15-15: Inheritance from BaseAggregateFunction is consistent.

Using the new base class fosters a uniform approach to parsing and SQL generation, aligning JsonAgg with other aggregate implementations.


19-19: Extended placeholders benefit DISTINCT/ORDER BY usage.

Refactoring the function prototype to json_agg(%s%s%s) opens the door for optional DISTINCT and ORDER BY handling. Ensure tests validate these new capabilities.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbAggTest.php (2)

22-29: Comprehensive coverage of jsonb_agg scenarios.

The newly added test statements effectively cover DISTINCT, concatenation, and multiple ORDER BY variations—mirroring real-world usage.


36-43: Validate ordering and DISTINCT operand syntax.

These additional DQL statements properly test ordering (ASC, DESC) combined with DISTINCT. Please ensure that all expected results are verified in actual DB tests or mocks to detect any syntax discrepancies early.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonAggTest.php (2)

22-29: Expanded test coverage aligns with json_agg enhancements.

The new SQL statements thoroughly exercise DISTINCT, ORDER BY clauses, and concatenation scenarios—consistent with PostgreSQL’s json_agg syntax.


36-43: Ensure expected DQL results match final SQL.

The expanded DQL statements are well structured. Confirm correct translation to SQL by running the updated tests in a real or CI environment to ensure correctness of all new variations.

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayAgg.php (1)

15-21: Proper extension and function prototype.

Shifting to BaseAggregateFunction and setting array_agg(%s%s%s) ensures consistency with the new approach for handling DISTINCT and ORDER BY. This change improves maintainability and clarity.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@martin-georgiev martin-georgiev merged commit 4cdc638 into main Mar 29, 2025
43 of 47 checks passed
@martin-georgiev martin-georgiev deleted the json_agg-and-jsonb_agg branch March 29, 2025 02:44
@github-actions github-actions bot mentioned this pull request Mar 29, 2025
@github-actions github-actions bot mentioned this pull request Mar 30, 2025
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.

3 participants