Skip to content

Conversation

@janklan
Copy link
Contributor

@janklan janklan commented Sep 3, 2025

websearch_to_tsquery is an alternative to to_tsquery, taking a more user-friendly input. I find it pretty useful, and I believe it would benefit users of this bundle.

Summary by CodeRabbit

  • New Features

    • Added support for PostgreSQL WEBSEARCH_TO_TSQUERY in queries, accepting one or two arguments (optional text search configuration).
  • Tests

    • Added unit tests for SQL/DQL generation, uppercase handling, argument validation, and error on too many arguments.
    • Added integration tests verifying tsquery output and error behavior for invalid text search configurations.

@coderabbitai
Copy link

coderabbitai bot commented Sep 3, 2025

Walkthrough

Adds a new Doctrine DQL variadic function WebsearchToTsquery mapping to PostgreSQL WEBSEARCH_TO_TSQUERY, plus unit and integration tests validating SQL/DQL generation, argument bounds (1–2), and error behavior for invalid regconfig.

Changes

Cohort / File(s) Summary of Changes
New DQL function implementation
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php
Adds WebsearchToTsquery extending BaseVariadicFunction; defines node mapping ['StringPrimary'], function name websearch_to_tsquery, and argument bounds (min 1, max 2).
Integration tests
tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
Adds integration tests registering the function, executing DQL with and without explicit regconfig, asserting expected TSQuery output, and asserting a DriverException for invalid regconfig.
Unit tests
tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
Adds unit tests: fixture creation, SQL/DQL expectation cases for default/UPPER/specific config, and a test asserting an exception when too many arguments are provided.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Developer
  participant DQL as Doctrine DQL Parser
  participant Fn as WebsearchToTsquery
  participant DB as PostgreSQL

  Developer->>DQL: SELECT WEBSEARCH_TO_TSQUERY('english', e.text1)
  DQL->>Fn: construct function node with args
  Note right of Fn #DDEEFE: validate argument count (1–2)\nmap node types to SQL
  Fn-->>DQL: websearch_to_tsquery('english', c0_.text1)
  DQL->>DB: execute SQL
  alt valid regconfig
    DB-->>DQL: return TSQuery string
  else invalid regconfig
    DB-->>DQL: DriverException (missing text search config)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

I nibble through queries with whiskered cheer,
From DQL to TS I hop, precise and clear.
One arg or two, I count with care,
Invalid configs make me stare.
websearch_to_tsquery — a rabbit's small cheer! 🐇


📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 2ea89bd and ee50f22.

📒 Files selected for processing (3)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php (1 hunks)
  • tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php (1 hunks)
  • tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php
  • tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: sloth
  • GitHub Check: Code Quality
  • GitHub Check: PostgreSQL 16 + PostGIS 3.5 + PHP 8.4
  • GitHub Check: PostgreSQL 17 + PostGIS 3.4 + PHP 8.3
  • GitHub Check: PostgreSQL 16 + PostGIS 3.5 + PHP 8.1
  • GitHub Check: PostgreSQL 16 + PostGIS 3.5 + PHP 8.3
  • GitHub Check: PostgreSQL 17 + PostGIS 3.5 + PHP 8.1
  • GitHub Check: PostgreSQL 17 + PostGIS 3.4 + PHP 8.2
  • GitHub Check: PostgreSQL 16 + PostGIS 3.5 + PHP 8.2
  • GitHub Check: PostgreSQL 16 + PostGIS 3.4 + PHP 8.1
  • GitHub Check: PostgreSQL 17 + PostGIS 3.4 + PHP 8.1
  • GitHub Check: PHP 8.1 + Doctrine ORM 2.14 + Doctrine Lexer 1.2
  • GitHub Check: PHP 8.4 + Doctrine ORM latest + Doctrine Lexer 3.0
  • GitHub Check: PHP 8.3 + Doctrine ORM latest + Doctrine Lexer latest
  • GitHub Check: PHP 8.2 + Doctrine ORM 3.0 + Doctrine Lexer latest
  • GitHub Check: PHP 8.1 + Doctrine ORM 2.18 + Doctrine Lexer 2.1
  • GitHub Check: wait-for-tests-worflows-before-upload
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit 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.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@coveralls
Copy link

coveralls commented Sep 3, 2025

Coverage Status

coverage: 95.104% (+0.02%) from 95.088%
when pulling ee50f22 on janklan:feat/websearch
into 9724452 on martin-georgiev:main.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php (3)

21-26: Test name nit: clarify intent

Consider a more descriptive name for discoverability.

-    public function totsquery(): void
+    public function websearch_to_tsquery_produces_expected_tsquery(): void

28-35: Loosen error-message assertion for portability

PG error wording/quotes can vary slightly across versions/locales. Make the regex case-insensitive and less brittle.

-        $this->expectExceptionMessageMatches('/text search configuration "invalid_regconfig" does not exist/');
+        $this->expectExceptionMessageMatches('/text search configuration .*invalid_regconfig.* does not exist/i');

20-26: Optional: add a 1-arg integration case

Covers default-config path end-to-end.

@@
     #[Test]
-    public function totsquery(): void
+    public function websearch_to_tsquery_with_explicit_config(): void
     {
@@
     }
 
+    #[Test]
+    public function websearch_to_tsquery_with_default_config(): void
+    {
+        $dql = "SELECT websearch_to_tsquery('\"sad cat\" or \"fat rat\"') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsTexts t WHERE t.id = 1";
+        $result = $this->executeDqlQuery($dql);
+        $this->assertSame("'sad' <-> 'cat' | 'fat' <-> 'rat'", $result[0]['result']);
+    }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1de5aaf and b8a8436.

📒 Files selected for processing (3)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php (1 hunks)
  • tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php (1 hunks)
  • tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#357
File: tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpMatchTest.php:28-62
Timestamp: 2025-04-22T00:03:37.733Z
Learning: This project focuses on providing Doctrine ORM interfaces to PostgreSQL functions. Tests should validate correct DQL-to-SQL translation rather than PostgreSQL functionality itself. Test cases should focus on parameter passing and SQL generation, not on testing specific PostgreSQL regex pattern behaviors.
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#352
File: tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpInstrTest.php:1-67
Timestamp: 2025-04-20T11:24:18.300Z
Learning: This PostgreSQL-for-Doctrine project is a translation layer only, focusing on correctly converting Doctrine DQL to PostgreSQL SQL syntax. It ensures arguments are passed in the expected format but does not test or handle PostgreSQL's actual function behavior or data handling. Test cases should focus on DQL-to-SQL translation and argument validation, not on PostgreSQL-specific behaviors.
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#0
File: :0-0
Timestamp: 2025-08-24T16:52:32.488Z
Learning: All new features in this repository must include proper test coverage before approval - this ltree implementation demonstrates exemplary test coverage with comprehensive unit tests, integration tests, data providers for edge cases, and validation of all relationships and error conditions.
📚 Learning: 2025-04-22T00:03:37.733Z
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#357
File: tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpMatchTest.php:28-62
Timestamp: 2025-04-22T00:03:37.733Z
Learning: This project focuses on providing Doctrine ORM interfaces to PostgreSQL functions. Tests should validate correct DQL-to-SQL translation rather than PostgreSQL functionality itself. Test cases should focus on parameter passing and SQL generation, not on testing specific PostgreSQL regex pattern behaviors.

Applied to files:

  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php
  • tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
  • tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
📚 Learning: 2025-03-29T03:31:17.114Z
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#318
File: tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/XmlAggTest.php:1-9
Timestamp: 2025-03-29T03:31:17.114Z
Learning: Tests in the `Tests\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions` namespace extend a custom `TestCase` class from the same namespace (`Tests\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\TestCase`), rather than PHPUnit's TestCase, and therefore don't need an explicit import.

Applied to files:

  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php
  • tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
  • tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
📚 Learning: 2025-05-23T11:11:57.951Z
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#383
File: tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RadiansTest.php:1-9
Timestamp: 2025-05-23T11:11:57.951Z
Learning: Tests in the `Tests\Unit\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions` namespace extend a custom `TestCase` class from the same namespace (`Tests\Unit\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\TestCase`), rather than PHPUnit's TestCase directly, and therefore don't need an explicit import.

Applied to files:

  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php
  • tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
  • tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
📚 Learning: 2025-03-29T03:31:17.114Z
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#318
File: tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/XmlAggTest.php:1-9
Timestamp: 2025-03-29T03:31:17.114Z
Learning: Tests in the `Tests\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions` namespace extend a custom `TestCase` class from the same namespace (`Tests\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\TestCase`), not PHPUnit's TestCase, and therefore don't need an explicit import statement.

Applied to files:

  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php
  • tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
  • tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
📚 Learning: 2025-09-01T18:48:28.508Z
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#434
File: tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/PostGIS/ST_CrossesTest.php:12-31
Timestamp: 2025-09-01T18:48:28.508Z
Learning: When analyzing unit test files in this codebase, always verify the actual file structure and existing patterns before suggesting changes. The ContainsGeometries fixture exists at ./fixtures/MartinGeorgiev/Doctrine/Entity/ContainsGeometries.php and the PostGIS unit tests use the namespace Tests\Unit\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\PostGIS consistently.

Applied to files:

  • tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
  • tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php
🧬 Code graph analysis (3)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php (1)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-143)
tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php (4)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php (1)
  • WebsearchToTsquery (15-36)
tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php (3)
  • Test (45-52)
  • WebsearchToTsqueryTest (13-53)
  • getStringFunctions (20-25)
tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TextTestCase.php (1)
  • TextTestCase (9-48)
tests/Integration/MartinGeorgiev/TestCase.php (1)
  • executeDqlQuery (271-285)
tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php (5)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-143)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php (1)
  • InvalidArgumentForVariadicFunctionException (7-56)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php (1)
  • WebsearchToTsquery (15-36)
tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (1)
  • BaseVariadicFunctionTestCase (17-106)
tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php (1)
  • assertSqlFromDql (109-113)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: PHP 8.3 + Doctrine ORM 3.0 + Doctrine Lexer 3.0
  • GitHub Check: PHP 8.2 + Doctrine ORM latest + Doctrine Lexer latest
  • GitHub Check: PHP 8.2 + Doctrine ORM 2.18 + Doctrine Lexer 3.0
  • GitHub Check: PHP 8.2 + Doctrine ORM 2.18 + Doctrine Lexer latest
  • GitHub Check: PHP 8.1 + Doctrine ORM 2.14 + Doctrine Lexer latest
  • GitHub Check: PHP 8.2 + Doctrine ORM 2.14 + Doctrine Lexer 2.1
  • GitHub Check: PHP 8.1 + Doctrine ORM 3.0 + Doctrine Lexer latest
  • GitHub Check: PHP 8.1 + Doctrine ORM 3.0 + Doctrine Lexer 3.0
  • GitHub Check: PHP 8.1 + Doctrine ORM 2.18 + Doctrine Lexer 2.1
  • GitHub Check: sloth
  • GitHub Check: PostgreSQL 17 + PostGIS 3.4 + PHP 8.4
  • GitHub Check: PostgreSQL 16 + PostGIS 3.5 + PHP 8.4
  • GitHub Check: PostgreSQL 17 + PostGIS 3.5 + PHP 8.3
  • GitHub Check: PostgreSQL 16 + PostGIS 3.5 + PHP 8.3
  • GitHub Check: PostgreSQL 16 + PostGIS 3.4 + PHP 8.3
  • GitHub Check: PostgreSQL 16 + PostGIS 3.5 + PHP 8.1
  • GitHub Check: wait-for-tests-worflows-before-upload
🔇 Additional comments (10)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsquery.php (4)

17-20: Node mapping looks correct for 1–2 string args

Using a simple pattern allows both 1-arg (default config) and 2-arg (explicit regconfig) calls.


22-35: Function name and arity align with PostgreSQL

Name matches SQL function and min/max argument counts are correct.


7-14: Verify the @SInCE version tag

Confirm the next library version before merging to avoid drift.

If needed, update inline:

- * @since 3.5
+ * @since 3.x

17-35: No issues found in BaseVariadicFunction naming
The variable $isNodeMappingASimplePattern is consistently defined and used (lines 72 and 91), so there’s no typo to correct.

tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php (1)

13-18: Registration is correct

Lowercase DQL function name mapped to the class is consistent with the query usage below.

tests/Unit/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/WebsearchToTsqueryTest.php (5)

15-18: Fixture creation LGTM

Correctly instantiates with DQL name used in this test suite.


20-25: Function map LGTM

Uppercase alias mapping matches DQL in this file; case-insensitivity is exercised across unit/integration suites.


27-34: SQL expectations are precise

Covers default, expression, and explicit-config cases.


36-43: DQL generation coverage is sufficient

Mirrors SQL cases; good parity.


45-52: Too-many-args path tested correctly

Exception expectation with parser-driven getSQL() is the established pattern here.

coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 3, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 3, 2025
@martin-georgiev martin-georgiev changed the title (feat) add websearch_to_tsquery feat: add support for websearch_to_tsquery Sep 3, 2025
@martin-georgiev
Copy link
Owner

Thanks @janklan - CI seems to be slightly off though.

@janklan
Copy link
Contributor Author

janklan commented Sep 3, 2025

Thanks @janklan - CI seems to be slightly off though.

Sorry, it should be all good now.

@martin-georgiev martin-georgiev merged commit be90545 into martin-georgiev:main Sep 4, 2025
67 checks passed
@github-actions github-actions bot mentioned this pull request Sep 4, 2025
@coderabbitai coderabbitai bot mentioned this pull request Sep 4, 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