Skip to content

Conversation

@seb-jean
Copy link
Contributor

@seb-jean seb-jean commented Apr 20, 2025

Hi,

I started from the feat/point-type branch, because I need some classes from this branch. This PR should then be merged after #348.

Summary by CodeRabbit

  • New Features

    • Added support for PostgreSQL point and point[] types, enabling storage and retrieval of spatial point data.
    • Introduced a new DQL function DISTANCE for calculating distances using PostgreSQL's <@> operator.
    • Added a new entity example demonstrating usage of point types in ORM mappings.
  • Documentation

    • Updated integration guides for Doctrine, Symfony, and Laravel to include configuration examples for the new point types and DISTANCE function.
    • Expanded available types and operators documentation to reflect new spatial features.
  • Tests

    • Added comprehensive tests for the new point, point[], and DISTANCE features to ensure correct functionality and error handling.

@seb-jean seb-jean closed this Apr 20, 2025
@coderabbitai
Copy link

coderabbitai bot commented Apr 20, 2025

Walkthrough

This update introduces comprehensive support for the PostgreSQL point and point[] spatial types and the <@> (distance) operator within Doctrine-based PHP applications. It adds new DBAL type classes for handling points and arrays of points, corresponding value objects, and custom exceptions for robust error handling. The ORM layer is extended with a new DQL function for distance calculations. Documentation for integration with Doctrine, Symfony, and Laravel is updated to guide users in registering these new types and functions. Thorough test suites are included to validate all new functionality and conversions.

Changes

File(s) Change Summary
docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md Added documentation for the PostgreSQL <@> operator, registered as the DISTANCE DQL function.
docs/AVAILABLE-TYPES.md Documented new types point and point[] with their implementing classes.
docs/INTEGRATING-WITH-DOCTRINE.md, docs/INTEGRATING-WITH-SYMFONY.md, docs/INTEGRATING-WITH-LARAVEL.md Updated integration guides to include registration and usage of point, point[] types and the DISTANCE DQL function.
fixtures/MartinGeorgiev/Doctrine/Entity/ContainsPoints.php Added new entity class with two point properties mapped for ORM testing.
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForDatabaseException.php Introduced exception for invalid point array items during database operations.
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForPHPException.php Introduced exception for invalid point array items in PHP context.
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForDatabaseException.php Introduced exception for invalid point values from the database.
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForPHPException.php Introduced exception for invalid point values in PHP.
src/MartinGeorgiev/Doctrine/DBAL/Types/Point.php Added new DBAL type for PostgreSQL point, handling conversion and validation.
src/MartinGeorgiev/Doctrine/DBAL/Types/PointArray.php Added new DBAL type for PostgreSQL point[], handling conversion and validation.
src/MartinGeorgiev/Doctrine/DBAL/Types/ValueObject/Point.php Introduced Point value object with immutable coordinates and string representation.
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Distance.php Added new DQL function for PostgreSQL <@> distance operator.
tests/MartinGeorgiev/Doctrine/DBAL/Types/PointArrayTest.php, tests/MartinGeorgiev/Doctrine/DBAL/Types/PointTest.php Added PHPUnit test classes for Point and PointArray DBAL types, covering valid and invalid conversions.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.php Added test class for the DISTANCE DQL function, verifying SQL translation.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant Doctrine as Doctrine ORM/DBAL
    participant DB as PostgreSQL

    App->>Doctrine: Register 'point', 'point[]' types and 'DISTANCE' function
    App->>Doctrine: Persist entity with Point or Point[] property
    Doctrine->>Doctrine: Convert Point/Point[] to DB format (validate, serialize)
    Doctrine->>DB: Store/retrieve point data
    App->>Doctrine: Query using DISTANCE DQL function
    Doctrine->>DB: Translate DQL to SQL with <@> operator
    DB-->>Doctrine: Return query results
    Doctrine-->>App: Hydrate entities, convert DB values to Point/Point[] objects
Loading

Suggested labels

enhancement

Poem

In the fields of Doctrine, a new point appears,
With arrays and distance, it now perseveres.
From PHP to Postgres, coordinates align,
With custom exceptions to keep code in line.
Tests hop along, ensuring all’s right—
A spatial leap forward, with features so bright!
🐇✨


📜 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 b042cf3 and f0c0a8f.

📒 Files selected for processing (1)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.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/DistanceTest.php
🧠 Learnings (1)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.php (2)
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.
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.
🧬 Code Graph Analysis (1)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.php (4)
fixtures/MartinGeorgiev/Doctrine/Entity/ContainsPoints.php (1)
  • ORM (10-18)
fixtures/MartinGeorgiev/Doctrine/Entity/Entity.php (1)
  • Entity (10-16)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Distance.php (1)
  • Distance (15-23)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php (1)
  • TestCase (15-120)
✨ 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 generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @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.

@seb-jean seb-jean reopened this Apr 20, 2025
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: 2

🧹 Nitpick comments (6)
docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md (1)

26-26: Fix table formatting inconsistency in documentation.

The table formatting has an inconsistency that was detected by the static analyzer. The line uses trailing pipes when the rest of the table uses only leading pipes.

-| <@> | DISTANCE | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance` |
+| <@> | DISTANCE | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance`
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

26-26: Table pipe style
Expected: leading_only; Actual: leading_and_trailing; Unexpected trailing pipe

(MD055, table-pipe-style)

src/MartinGeorgiev/Doctrine/DBAL/Types/ValueObject/Point.php (1)

19-22: Consider precision control in string representation.

The current implementation uses %f which may result in trailing zeros. Consider using a more precise format specifier to match the database's expected format.

-        return \sprintf('(%f, %f)', $this->x, $this->y);
+        return \sprintf('(%.6f, %.6f)', $this->x, $this->y);

Or even better, for exact control over the string representation:

-        return \sprintf('(%f, %f)', $this->x, $this->y);
+        return '(' . $this->x . ', ' . $this->y . ')';
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.php (1)

25-31: Add documentation comment about the PostgreSQL operator.

To improve clarity, add a comment explaining that the DISTANCE function maps to PostgreSQL's <@> operator, which calculates the distance in miles between two points.

protected function getDqlStatements(): array
{
+   // Tests that the DISTANCE DQL function properly maps to PostgreSQL's '<@>' operator
+   // which calculates the distance between points in miles
    return [
        \sprintf("SELECT DISTANCE(e.point, '(2.320041, 48.858889)') FROM %s e", ContainsPoints::class),
    ];
}
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForPHPException.php (1)

21-34: Add PHPDoc comments to the static factory methods.

While the method names are descriptive, adding PHPDoc comments would improve code documentation and consistency with other parts of the codebase.

/**
 * @since 3.1
 *
 * @author Sébastien Jean <sebastien.jean76@gmail.com>
 */
class InvalidPointArrayItemForPHPException extends ConversionException
{
    private static function create(string $message, mixed $value): self
    {
        return new self(\sprintf($message, \var_export($value, true)));
    }

+   /**
+    * Creates an exception for when an array value is not a string
+    */
    public static function forInvalidType(mixed $value): self
    {
        return self::create('Array values must be strings, %s given', $value);
    }

+   /**
+    * Creates an exception for when a string in the array is not a valid point format
+    */
    public static function forInvalidFormat(mixed $value): self
    {
        return self::create('Invalid point format in array: %s', $value);
    }

+   /**
+    * Creates an exception for when the provided value is not an array
+    */
    public static function forInvalidArrayType(mixed $value): self
    {
        return self::create('Value must be an array, %s given', $value);
    }
}
tests/MartinGeorgiev/Doctrine/DBAL/Types/PointArrayTest.php (1)

97-101: Add a comment explaining the @phpstan-ignore-line annotation

The code includes a PHPStan ignore annotation without explanation. It would be helpful to document why this is necessary.

-        $this->fixture->convertToDatabaseValue($phpValue, $this->platform); // @phpstan-ignore-line
+        // PHPStan knows $phpValue is invalid but we're testing the exception is thrown
+        $this->fixture->convertToDatabaseValue($phpValue, $this->platform); // @phpstan-ignore-line
tests/MartinGeorgiev/Doctrine/DBAL/Types/PointTest.php (1)

101-108: Consider adding more invalid transformation test cases

The current test cases for invalid PHP-to-database transformations are focused on string values, but you might want to add tests for other invalid types like integers, arrays, or objects.

    public static function provideInvalidTransformations(): array
    {
        return [
            'empty string' => [''],
            'whitespace string' => [' '],
            'invalid format' => ['invalid point'],
+           'integer' => [123],
+           'array' => [[1, 2]],
+           'stdClass object' => [(object)['x' => 1, 'y' => 2]],
        ];
    }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9959476 and 36117c6.

📒 Files selected for processing (17)
  • docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md (1 hunks)
  • docs/AVAILABLE-TYPES.md (1 hunks)
  • docs/INTEGRATING-WITH-DOCTRINE.md (3 hunks)
  • docs/INTEGRATING-WITH-LARAVEL.md (4 hunks)
  • docs/INTEGRATING-WITH-SYMFONY.md (3 hunks)
  • fixtures/MartinGeorgiev/Doctrine/Entity/ContainsPoints.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForDatabaseException.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForPHPException.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForDatabaseException.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForPHPException.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Point.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/PointArray.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/ValueObject/Point.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Distance.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/DBAL/Types/PointArrayTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/DBAL/Types/PointTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.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/DistanceTest.php
🧠 Learnings (1)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.php (2)
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.
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.
🧬 Code Graph Analysis (8)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Distance.php (2)
fixtures/MartinGeorgiev/Doctrine/Entity/ContainsPoints.php (1)
  • ORM (10-15)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseFunction.php (3)
  • BaseFunction (20-105)
  • setFunctionPrototype (57-60)
  • addNodeMapping (62-65)
fixtures/MartinGeorgiev/Doctrine/Entity/ContainsPoints.php (1)
fixtures/MartinGeorgiev/Doctrine/Entity/Entity.php (1)
  • Entity (10-16)
src/MartinGeorgiev/Doctrine/DBAL/Types/ValueObject/Point.php (1)
src/MartinGeorgiev/Doctrine/DBAL/Types/Point.php (1)
  • Point (20-53)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForPHPException.php (3)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForDatabaseException.php (1)
  • create (16-19)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForPHPException.php (2)
  • create (16-19)
  • forInvalidType (21-24)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForDatabaseException.php (2)
  • create (16-19)
  • forInvalidType (21-24)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForDatabaseException.php (3)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForPHPException.php (1)
  • create (16-19)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForDatabaseException.php (1)
  • create (16-19)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForPHPException.php (1)
  • create (16-19)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForPHPException.php (3)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForDatabaseException.php (1)
  • create (16-19)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForDatabaseException.php (3)
  • create (16-19)
  • forInvalidType (21-24)
  • forInvalidFormat (26-29)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForPHPException.php (2)
  • create (16-19)
  • forInvalidType (21-24)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForDatabaseException.php (3)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForDatabaseException.php (1)
  • create (16-19)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForPHPException.php (3)
  • create (16-19)
  • forInvalidType (21-24)
  • forInvalidFormat (26-29)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForPHPException.php (2)
  • create (16-19)
  • forInvalidType (21-24)
tests/MartinGeorgiev/Doctrine/DBAL/Types/PointArrayTest.php (3)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForPHPException.php (1)
  • InvalidPointArrayItemForPHPException (14-35)
src/MartinGeorgiev/Doctrine/DBAL/Types/PointArray.php (1)
  • PointArray (19-82)
src/MartinGeorgiev/Doctrine/DBAL/Types/ValueObject/Point.php (1)
  • Point (12-33)
🪛 markdownlint-cli2 (0.17.2)
docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md

26-26: Table pipe style
Expected: leading_only; Actual: leading_and_trailing; Unexpected trailing pipe

(MD055, table-pipe-style)

🔇 Additional comments (43)
src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForPHPException.php (1)

1-25: Clean exception implementation for PHP point type validation.

The exception class is well-structured and follows Doctrine's exception handling patterns with appropriate use of static factory methods for clear, consistent error messages.

src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForDatabaseException.php (1)

1-30: Consistent exception implementation for database point validation.

The class follows the same design pattern as related exception classes, providing specific factory methods for different error scenarios. The implementation is clean and well-structured.

docs/AVAILABLE-TYPES.md (1)

20-21: Documentation correctly updated with new point types.

The point and point array types are properly documented following the established table format.

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

7-14: Well-documented class with clear purpose.

The PHPDoc clearly explains that this is an implementation of PostgreSQL's distance operator and provides a link to the official documentation. The version tag and author information are also properly included.


17-22: Implementation follows the established pattern.

The implementation of customizeFunction() correctly sets up the PostgreSQL distance operator <@> with two string arguments. This follows the pattern used by other functions in the codebase.

fixtures/MartinGeorgiev/Doctrine/Entity/ContainsPoints.php (1)

10-15: Entity class is correctly defined.

The entity class is properly defined with ORM mapping attributes. The point property is correctly typed as Point and mapped with the appropriate column type.

src/MartinGeorgiev/Doctrine/DBAL/Types/ValueObject/Point.php (3)

7-11: Class well-documented with version and author information.

The PHPDoc includes the version tag and author information, which is consistent with other classes in the project.


12-17: Immutable value object with clear responsibility.

The class is correctly defined as final with readonly properties, making it immutable, which is ideal for a value object.


24-32: Appropriate getter methods.

The getter methods provide clean access to the private properties, maintaining encapsulation.

docs/INTEGRATING-WITH-SYMFONY.md (3)

20-21: Type registration is correctly implemented.

The new point and point[] types are properly registered with their respective DBAL type classes.


51-53: PostgreSQL to DBAL type mapping is properly configured.

The mapping for PostgreSQL's point, point[], and _point types to their DBAL equivalents is correctly added.


178-178: Distance function registration is correctly implemented.

The new DISTANCE function is properly registered for use in DQL queries.

src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForDatabaseException.php (3)

9-13: Exception class is well-documented.

The exception includes proper PHPDoc with version tag and author information.


16-19: Consistent error message formatting.

The create method follows the same pattern as other exception classes in the codebase, providing consistency in error reporting.


21-24: Clear exception message for invalid points.

The error message clearly indicates when a value is not a point, which will be helpful for debugging.

docs/INTEGRATING-WITH-LARAVEL.md (4)

33-33: LGTM! Type mapping correctly registered.

The PostgreSQL 'point' type is properly mapped to the Doctrine 'point' type in the type_mappings configuration array.


57-58: LGTM! Custom types registration looks good.

Both 'point' and 'point[]' types are properly registered with their respective DBAL type classes.


182-182: LGTM! DISTANCE function registration is properly implemented.

The DISTANCE function is correctly mapped to the Distance class implementation, which corresponds to the PostgreSQL '<@>' operator for calculating distance between points.


248-253: LGTM! Type registration in DoctrineEventSubscriber is correct.

The implementation follows the same pattern as other type registrations in the postConnect method, ensuring the 'point' and 'point[]' types are registered if they don't already exist.

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

1-9: LGTM! File structure follows project conventions.

The namespace, imports, and class declaration follow the project's conventions. As noted in the retrieved learnings, tests in this namespace extend the custom TestCase class rather than PHPUnit's TestCase.


10-18: LGTM! String function registration is correct.

The test correctly registers the DISTANCE function using the Distance class.

docs/INTEGRATING-WITH-DOCTRINE.md (3)

20-21: LGTM! Point type registration looks good.

The 'point' and 'point[]' types are properly registered with their respective type classes.


147-147: LGTM! DISTANCE function registration is properly implemented.

The DISTANCE function is correctly registered with the Distance class implementation.


174-176: LGTM! Type mappings for PostgreSQL point types are correct.

The type mappings for 'point', 'point[]', and '_point' are properly registered with their respective Doctrine types.

src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForPHPException.php (2)

1-15: LGTM! Exception class structure and inheritance are appropriate.

The class properly extends ConversionException and follows the project's namespace and file structure conventions.


16-19: LGTM! Private helper method for exception creation.

The private static create method follows the pattern used in other exception classes (as seen in the provided relevant code snippets) to format error messages with the problematic value.

src/MartinGeorgiev/Doctrine/DBAL/Types/PointArray.php (5)

56-58: Consider adding anchors to regex pattern for more precise matching

The regex pattern could benefit from explicit start/end anchors to ensure the entire string matches the expected format, not just a portion of it.

-        if (!\preg_match('/^\((-?\d+(?:\.\d{1,6})?),\s*(-?\d+(?:\.\d{1,6})?)\)$/', $item, $matches)) {
+        if (!\preg_match('/^\((-?\d+(?:\.\d{1,6})?),\s*(-?\d+(?:\.\d{1,6})?)\)$/', $item, $matches)) {

Actually, I see the pattern already has proper anchors (^ at start and $ at end). This is correctly implemented!


23-30: LGTM! Properly validates Point objects before conversion

The method correctly ensures that array items are PointValueObject instances before conversion, throwing an appropriate exception otherwise.


32-44: LGTM! Robust array string processing

The method properly handles empty arrays and correctly parses the PostgreSQL array format with proper string boundary checks.


46-61: LGTM! Thorough point string validation and conversion

The method properly validates point strings using a regex pattern that matches the PostgreSQL point format with up to 6 decimal places, converting valid strings to PointValueObject instances.


1-82: LGTM! Well-structured implementation for PostgreSQL POINT[] data type

The class provides a complete implementation for converting between PHP arrays of Point objects and PostgreSQL POINT[] strings, with proper validation and error handling.

tests/MartinGeorgiev/Doctrine/DBAL/Types/PointArrayTest.php (6)

23-27: LGTM! Proper test setup

The setup method correctly mocks the necessary dependencies and instantiates the class under test.


32-35: LGTM! Type name verification

Verifies that the type name is correctly returned as 'point[]'.


42-45: LGTM! Database conversion test

Properly tests the conversion from PHP array of Point objects to PostgreSQL string representation.


52-55: LGTM! PHP conversion test

Properly tests the conversion from PostgreSQL string representation to PHP array of Point objects.


60-90: LGTM! Comprehensive test data for valid transformations

The data provider includes a wide range of test cases covering null values, empty arrays, single points, multiple points, and points with zero values.


106-119: LGTM! Good test coverage for invalid transformations

The data provider includes various invalid inputs including non-arrays, arrays with non-Point items, and mixed arrays.

src/MartinGeorgiev/Doctrine/DBAL/Types/Point.php (2)

24-35: LGTM! Proper database value conversion

The method correctly handles null values and validates that the input is a PointValueObject before conversion.


37-52: LGTM! Well-implemented PHP value conversion

The method properly validates the input string format and creates a new PointValueObject with the parsed coordinates.

tests/MartinGeorgiev/Doctrine/DBAL/Types/PointTest.php (4)

61-85: LGTM! Comprehensive valid transformation test cases

Good test coverage for various point scenarios including null values, positive/negative coordinates, zero values, and decimal precision.


43-46: LGTM! Good PHP-to-database conversion test

The test properly verifies the conversion from PHP PointValueObject to PostgreSQL string representation.


53-56: LGTM! Good database-to-PHP conversion test

The test properly verifies the conversion from PostgreSQL string representation to PHP PointValueObject.


126-135:

✅ Verification successful

Inconsistent maximum precision test cases

There's an inconsistency in the test cases for precision:

  1. In provideValidTransformations(), coordinates with 6 decimal places are considered valid (line 81-82)
  2. In provideInvalidDatabaseValues(), coordinates with more than 6 decimal places are considered invalid (line 134-135)

This is actually correct behavior since your regex in the implementation limits precision to 6 decimal places, but you might want to add a comment explaining this precision limit for clarity.


🏁 Script executed:

#!/bin/bash
# Description: Verify PostgreSQL's default precision for POINT coordinates

# Let's check the regex in the Point class
grep -A 5 "preg_match" src/MartinGeorgiev/Doctrine/DBAL/Types/Point.php

Length of output: 347


Tests correctly enforce 6‑decimal precision – consider clarifying with a comment

The regex in Point::convertToDatabaseValue() (/(…\.\d{1,6}…)/) limits coordinates to at most 6 decimal places. The tests in provideValidTransformations() allow up to 6 decimals and those in provideInvalidDatabaseValues() reject values with more than 6 decimals (e.g. the “maximum float precision” case).

This behavior is intentional and correct; you may add a brief comment above these cases in tests/MartinGeorgiev/Doctrine/DBAL/Types/PointTest.php to explain the 6‑decimal precision limit for future readers.

@seb-jean seb-jean force-pushed the feat/distance-function branch from f85933f to 6d639f8 Compare April 23, 2025 07:19
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: 3

🔭 Outside diff range comments (7)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbInsertTest.php (3)

12-12: ⚠️ Potential issue

Update class to use the new base test case.

The class should extend BaseVariadicFunctionTestCase to be consistent with other refactored test classes like ArrTest.

-class JsonbInsertTest extends TestCase
+class JsonbInsertTest extends BaseVariadicFunctionTestCase

13-13: ⚠️ Potential issue

Add missing required method.

When extending BaseVariadicFunctionTestCase, you need to implement the createFixture() method.

+    protected function createFixture(): BaseVariadicFunction
+    {
+        return new JsonbInsert('JSONB_INSERT');
+    }
+

58-58: 🛠️ Refactor suggestion

Update this error message too.

For consistency, this error message should also be updated to use the lowercase function name.

-        $this->expectExceptionMessage('jsonb_insert() requires between 3 and 4 arguments');
+        $this->expectExceptionMessage('jsonb_insert() requires between 3 and 4 arguments');
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsqueryTest.php (1)

26-41: 💡 Verification agent

🧩 Analysis chain

Consider adding tests for advanced full text search operators.

While the current tests cover basic usage of to_tsquery, they don't test the function's handling of search operators like & (AND), | (OR), ! (NOT), and <-> (phrase distance). These are important aspects of PostgreSQL's text search functionality.


🌐 Web query:

What operators does PostgreSQL to_tsquery support?

💡 Result:

Operators Supported by PostgreSQL to_tsquery

PostgreSQL's to_tsquery function converts text into a tsquery value that can be used for full-text search. The query text passed to to_tsquery can include several operators to combine and structure search conditions.

Supported Operators in to_tsquery

  • & (AND): Requires that both subqueries match; combines terms such that all must be present.
  • | (OR): Requires that at least one of the subqueries matches; combines terms allowing any to be present.
  • ! (NOT): Negates a term or subquery, excluding documents that contain the specified lexeme.
  • <-> (FOLLOWED BY): Specifies that the subqueries must match consecutive lexemes, forming phrase search (matches if the two terms are adjacent in the text).
  • Parentheses ( ): Used to group subqueries and control the order of operations, similar to classic Boolean logic.

Additionally:

  • Weight and prefix-match labels (like :A, :B, :*) can be used within lexemes for more granular control, though these are not operators per se[3].
  • The input must follow the general tsquery syntax rules, and stop words are discarded according to the specified or default configuration[2][3][5].

Example Usage:

SELECT to_tsquery('english', 'cat & rat | dog');
-- Interpreted as: (cat AND rat) OR dog

Web Search Syntax Alternative:
For users preferring a more familiar, search-engine-like syntax, PostgreSQL provides websearch_to_tsquery, which translates common operators (like quoted phrases, OR, and - for NOT) into the strict tsquery syntax automatically[2][5].

Summary Table

Operator Description Example
& AND (must include all terms) cat & dog
| OR (must include at least one term) `cat
! NOT (exclude term) cat & !dog
<-> FOLLOWED BY (phrase search, adjacency) cat <-> dog
() Group terms/control precedence `(cat

These operators allow building complex queries to match a wide variety of full-text search requirements in PostgreSQL[2][3][4][5].

Citations:


Add tests for advanced full‑text search operators

The current tests cover only basic to_tsquery usage. PostgreSQL’s to_tsquery also supports the following operators, so please extend your test cases to include them:

• AND (&): both terms must match
• OR (|): either term may match
• NOT (!): excludes documents containing the term
• FOLLOWED BY (<->): phrase/adjacency search
• Parentheses (()) for grouping and precedence

Locations to update in tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsqueryTest.php:

  • getExpectedSqlStatements():
        return [
            'SELECT to_tsquery(c0_.text1) AS sclr_0 FROM ContainsTexts c0_',
            'SELECT to_tsquery(UPPER(c0_.text1)) AS sclr_0 FROM ContainsTexts c0_',
            "SELECT to_tsquery('english', c0_.text1) AS sclr_0 FROM ContainsTexts c0_",
  •     "SELECT to_tsquery('english', 'cat & dog') AS sclr_0 FROM ContainsTexts c0_",
    
  •     "SELECT to_tsquery('english', 'cat | dog') AS sclr_0 FROM ContainsTexts c0_",
    
  •     "SELECT to_tsquery('english', 'cat & !dog') AS sclr_0 FROM ContainsTexts c0_",
    
  •     "SELECT to_tsquery('english', 'cat <-> dog') AS sclr_0 FROM ContainsTexts c0_",
    
  •     "SELECT to_tsquery('english', '(cat | dog) & rat') AS sclr_0 FROM ContainsTexts c0_",
    ];
    
    
    
  • getDqlStatements():
        return [
            sprintf('SELECT TO_TSQUERY(e.text1) FROM %s e', ContainsTexts::class),
            sprintf('SELECT TO_TSQUERY(UPPER(e.text1)) FROM %s e', ContainsTexts::class),
            sprintf("SELECT TO_TSQUERY('english', e.text1) FROM %s e", ContainsTexts::class),
  •     sprintf("SELECT TO_TSQUERY('english', 'cat & dog') FROM %s e", ContainsTexts::class),
    
  •     sprintf("SELECT TO_TSQUERY('english', 'cat | dog') FROM %s e", ContainsTexts::class),
    
  •     sprintf("SELECT TO_TSQUERY('english', 'cat & !dog') FROM %s e", ContainsTexts::class),
    
  •     sprintf("SELECT TO_TSQUERY('english', 'cat <-> dog') FROM %s e", ContainsTexts::class),
    
  •     sprintf("SELECT TO_TSQUERY('english', '(cat | dog) & rat') FROM %s e", ContainsTexts::class),
    ];
    
    
    

Adding these will ensure coverage of all major full‑text search operators supported by PostgreSQL.

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

26-53: 💡 Verification agent

🧩 Analysis chain

Verify comprehensive test coverage for LEAST function against PostgreSQL documentation.

The test cases cover multiple scenarios for the LEAST function:

  • Multiple column values
  • Column value with expression
  • Multiple expressions
  • Exception when single argument is given

According to PostgreSQL documentation, this covers the basic functionality. However, consider adding a test case with different data types to verify PostgreSQL's type coercion behavior, as LEAST can compare values of different types.


🌐 Web query:

PostgreSQL LEAST function type coercion behavior

💡 Result:

PostgreSQL LEAST Function and Type Coercion Behavior

Overview of LEAST Function

The PostgreSQL LEAST function returns the smallest value from a list of expressions. It is type-flexible, working for numbers, strings (alphabetical order), dates (earliest), and booleans (false is less than true). If any argument is NULL, the function returns NULL[3].

Type Coercion Rules with LEAST

Function Argument Type Resolution

When you use the LEAST function with arguments of different types, PostgreSQL must resolve these arguments to a common type so a single function can process them. Type conversion in PostgreSQL follows general and standardized rules, not ad hoc heuristics[2].

  • The parser first tries to identify an exact match for the function based on argument types.
  • If there is no exact match, PostgreSQL will look for implicit conversions that allow the function to be called.
  • If arguments are of different types, PostgreSQL attempts to find a common type to which all can be implicitly cast, following its type precedence and conversion rules[2][7].

Mixed-Type Expression Handling

  • Arguments to LEAST must be implicitly convertible to a common type. For instance, mixing integers and floats will result in the lower-precedence type being promoted (e.g., integers to floats).
  • If there is ambiguity or the arguments are not implicitly convertible to a common type (for example, mixing dates and numbers), PostgreSQL will raise an error and require explicit casting[2][7].

Example of Type Coercion:

SELECT LEAST(1, 2.5, 3);      -- All arguments are promoted to numeric
SELECT LEAST('abc', 'def');   -- Arguments are text, comparison is lexical
SELECT LEAST('2024-01-01', '2025-03-01'); -- Arguments are dates

If you mix types that PostgreSQL cannot resolve (like a string and a date), you must use explicit casts:

SELECT LEAST('2024-01-01'::date, '2025-03-01'::date);

Unknown and String Literals

  • String literals without explicit type are considered unknown. PostgreSQL prefers to resolve these as text where possible, or as the preferred type within the relevant category[2][7].
  • This is particularly relevant for LEAST when comparing string literals: 'abc' and 'def' are both resolved to text.

Domain Types and Coercion

For domain types created over base types, type coercion can sometimes be problematic if the matching rules do not consider domains equivalent to their base types. This is more of a corner case and not unique to the LEAST function, but may require explicit casting when using custom domain types[6].

Summary Table: LEAST Type Coercion

Data Types Mixed Resulting Type Behavior
All integers integer Returns smallest integer
Integer + float numeric/float All args converted to numeric
All text text Returns alphabetically first string
All dates date Returns earliest date
Mixed incompatible types error unless cast provided Explicit cast required for resolution

Key Takeaways

  • PostgreSQL's LEAST function uses the standard function argument type resolution rules: all arguments are coerced to a common type if possible[2][7].
  • If no common type can be determined, a runtime error is thrown, and explicit casts are needed.
  • String literals without explicit type are treated as unknown and resolved following type precedence[2][7].
  • Mixing very different types (e.g., numeric and date) will not automatically coerce and will require explicit type casting.

This type coercion and resolution behavior is not unique to LEAST but applies to most PostgreSQL functions that accept multiple arguments[2][7].

Citations:


Add mixed‐type and NULL coercion tests for LEAST

Based on PostgreSQL’s type‐coercion rules, LEAST will:

  • Promote integers + floats to a common numeric type
  • Compare text lexically
  • Compare dates chronologically
  • Return NULL if any argument is NULL

Please extend tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/LeastTest.php with scenarios such as:

  • Numeric + float mix (e.g. LEAST(1, 2.5, 3))
  • Text values (e.g. LEAST('abc', 'def'))
  • Date values (e.g. LEAST('2024-01-01'::date, '2025-03-01'::date))
  • NULL handling (any NULL arg yields NULL)

This will ensure full coverage of PostgreSQL’s implicit casting and NULL behavior.

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

27-44: 💡 Verification agent

🧩 Analysis chain

Verify test cases against PostgreSQL documentation

The test cases cover key scenarios for the jsonb_path_query_first function including basic path expression, filtering with conditions, and using optional arguments (vars and silent). However, consider adding tests for returning NULL when no match is found.


🌐 Web query:

PostgreSQL jsonb_path_query_first function examples and NULL handling

💡 Result:

PostgreSQL jsonb_path_query_first() Function

Functionality
The jsonb_path_query_first() function in PostgreSQL is used to extract the first JSON value from a jsonb document that matches a given JSON path expression. If no value matches, the function returns NULL[1][5][7][8].

Syntax

jsonb_path_query_first(
  target jsonb,
  path jsonpath,
  [vars jsonb,]
  [silent boolean]
) → jsonb
  • target: The JSONB value to search
  • path: The JSONPath expression
  • vars (optional): Variables for the path
  • silent (optional): Suppress errors if true[5]

Examples

Extracting First Value from an Array

SELECT jsonb_path_query_first('[1, 2, 3]', '$[*] ? (@ > 1)');

Result:

2

This retrieves the first element greater than 1 in the array[5][6][8].

Using Variables in a Path

SELECT jsonb_path_query_first(
  '[1, 2, 3, 4]',
  '$[*] ? (@ >= $min && @ <= $max)',
  '{"min": 2, "max": 3}'
);

Result:

2

Variables min and max are substituted into the path condition[5].

Querying a JSON Object

SELECT jsonb_path_query_first(
  '{"employees": [{"name": "John", "age": 30}, {"name": "Jane", "age": 25}]}',
  '$.employees[*] ? (@.age > 27)'
);

Result:

{"name": "John", "age": 30}

This fetches the first employee with age greater than 27[4].

No Match Returns NULL

SELECT jsonb_path_query_first('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 5)');

Result:

NULL

If no element matches the path, NULL is returned[6][8].


NULL Handling

  • If there are no matching items for the JSONPath expression, the function returns SQL NULL[1][6][7][8].
  • If any function argument (such as the target or path) is SQL NULL, the function's result is also NULL[5].
  • Distinction: PostgreSQL's SQL NULL is different from a JSON null. A missing key or unmatched path yields SQL NULL, while a key with a value of JSON null yields the JSON null value (as JSON, not as SQL NULL)[9].

Example:

SELECT jsonb_path_query_first('{"a": null}', '$.a');
  • Returns the JSON null value, not SQL NULL, because "a" exists and its value is null[9].
SELECT jsonb_path_query_first('{"b": 1}', '$.a');
  • Returns SQL NULL, because key "a" does not exist[9].

Summary Table

Scenario Result
Path matches a value First match
Path matches JSON null JSON null
Path does not match SQL NULL
Any argument is SQL NULL SQL NULL

In conclusion:
jsonb_path_query_first() is a targeted way to extract a single value from JSONB using JSONPath, returning the actual first match as JSONB (including JSON null if present), and SQL NULL if no matches are found or arguments are SQL NULL[1][5][6][7][8][9].

Citations:


Add a no‐match test case to assert NULL return

To ensure jsonb_path_query_first() returns SQL NULL when there are no matching items, add a test for the “no match” scenario:

• File: tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryFirstTest.php

  • In getExpectedSqlStatements(), append e.g.:
    'no match returns null' => "SELECT jsonb_path_query_first(c0_.object1, '$.items[*] ? (@.price > 1000)') AS sclr_0 FROM ContainsJsons c0_",
  • In getDqlStatements(), append e.g.:
    'no match returns null' => sprintf(
        "SELECT JSONB_PATH_QUERY_FIRST(e.object1, '$.items[*] ? (@.price > 1000)') FROM %s e",
        ContainsJsons::class
    ),

This will validate that the function yields SQL NULL when the path finds no elements.

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

27-44: 💡 Verification agent

🧩 Analysis chain

Verify test cases against PostgreSQL documentation

The test cases cover key scenarios for the jsonb_path_exists function, including path expression with conditions, nested path checking, and using optional arguments. Consider adding tests for edge cases like JSON arrays and empty objects.


🌐 Web query:

PostgreSQL jsonb_path_exists function examples and edge cases

💡 Result:

Overview of jsonb_path_exists in PostgreSQL

The jsonb_path_exists() function in PostgreSQL checks whether a given JSONPath expression matches at least one element in a JSONB document. If any items are matched, it returns true; otherwise, it returns false[1][5][4].

Syntax

jsonb_path_exists(target_jsonb, jsonpath [, vars_jsonb [, silent_boolean]])
  • target_jsonb: The JSONB document to search.
  • jsonpath: The JSON path expression.
  • vars_jsonb (optional): Named variables for the path expression.
  • silent_boolean (optional): If true, suppresses errors and returns null on invalid input.

Practical Examples

Basic existence check:

SELECT jsonb_path_exists('{"a": 1}', '$.a');  -- true
SELECT jsonb_path_exists('{"a": 1}', '$.b');  -- false
  • The first query returns true because the path $.a exists.
  • The second returns false because $.b does not[5].

Using wildcards and filters:

SELECT jsonb_path_exists('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ >= $min && @ <= $max)', '{"min":2, "max":4}');
-- Returns true: values 2, 3, 4 exist in array 'a' and match the condition

Here, @ refers to the current element value, and the JSONB variable object provides parameters for the range[5].

Check for deep matches:

SELECT jsonb_path_exists(content, '$.** ? (@ == "Hyperion")') FROM book_orders;
  • The $.** operator searches all levels of nesting for the value "Hyperion"[5].

Comparative Table: jsonb_path_exists() vs Similar Functions

Function Returns Main Use Case
jsonb_path_exists() true/false Does any item match the path?
jsonb_path_match() true/false Does the path predicate evaluate to true?
jsonb_path_query() Set of jsonb (items matched) Return elements matching the path

Edge Cases and Behavior Insights

  • Null and Boolean Results:
    Any result, including null or false, counts as a match—so the function will return true as long as at least one value is returned by the query[7].
  • No Matches:
    If the path returns zero elements, it returns false.
  • Strict vs Lax Modes:
    In strict mode, errors in the path (like wrong type access) cause exceptions unless silent is set to suppress them[2][7]. Lax mode is more forgiving but can produce unexpected results, especially with recursive operators like .**[2].
  • Deep/Nested Values:
    The recursive descent operator .** will match any occurrence, even deeply nested, but be cautious as it may match more values than intended[5][2].
  • Silent Option:
    If silent is true, errors in the path expression simply cause the function to return null instead of raising an error[8].
  • Empty Arrays:
    If you check for an element inside an empty array, the result is false since there are no matches.

Advanced Usage Scenarios

Variables in Path Expressions:

SELECT jsonb_path_exists('{"a":[1,2,3]}', '$.a[*] ? (@ > $min)', '{"min":2}');
-- Returns true (since 3 > 2)

This flexibility allows parameterized checks within a path[5].

Checking for Nested Key Existence:

SELECT jsonb_path_exists('{"person": {"address": {"city": "NYC"}}}', '$.person.address.city');
-- Returns true

Works on any depth where the path exists.


Summary

  • jsonb_path_exists() is essential for checking if any data matches a given JSONPath in a JSONB column.
  • It is flexible, supporting advanced path expressions, variables, and error handling with the silent mode[1][5][7].
  • Be cautious with recursive paths and strict mode, as they may yield unexpected results or errors[2][7].

For reliable results, always test complex paths, especially when working with varying JSON structures or deeply nested data.

Citations:


Add edge‑case tests for jsonb_path_exists

Core scenarios like conditional filters, nested paths, and use of vars/silent are covered, but we should also verify behavior on empty structures and missing keys:

• tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathExistsTest.php

  • Add a case where the target JSON contains an empty array (e.g. {"a": []}) and the path $.a[*] (or with a filter) returns false.
  • Add a case for an empty object (e.g. {}) using a simple path (e.g. $.a) to confirm it returns false.
  • Optionally, add a case for a missing top‑level key and verify false.
  • (Bonus) Test strict vs. silent mode on invalid paths to ensure null is returned when silent is true.
♻️ Duplicate comments (1)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryArray.php (1)

26-30: Same observation on node‑mapping as for JsonbSet.

If you broaden the pattern there, consider keeping the two JSONB helpers consistent.

🧹 Nitpick comments (13)
docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md (1)

26-26: Fix trailing pipe in the <@> operator row for markdown table consistency

The markdownlint rule (MD055) flags an unexpected trailing pipe on this newly added row. The header and other existing rows use only leading pipes without a trailing one. Removing the trailing | will satisfy the linter and keep the table style consistent.

Apply this diff:

- | <@> | DISTANCE | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance` |
+ | <@> | DISTANCE | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance` |
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

26-26: Table pipe style
Expected: leading_only; Actual: leading_and_trailing; Unexpected trailing pipe

(MD055, table-pipe-style)

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

30-36: SQL test cases look good but could benefit from additional edge cases.

The test provides a good set of SQL test cases for the ROW constructor, including different data types and comparison operations. According to PostgreSQL documentation, the ROW constructor can be used in more scenarios like row subqueries, INSERT INTO statements, and with other row-related operators like IS DISTINCT FROM.

Consider adding test cases for:

  1. Using IS DISTINCT FROM with ROW constructors
  2. Row-wise comparison with IN operator
  3. Using NULL values within a row constructor
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Least.php (1)

17-20: Simplified implementation using base class functionality

The getFunctionName() method replaces previous explicit function prototype customization and validation logic, delegating these responsibilities to the parent class BaseComparisonFunction. This simplification is consistent with the refactoring pattern applied across other function classes.

Consider updating the documentation reference to link to the latest PostgreSQL version rather than 9.4.

- * @see https://www.postgresql.org/docs/9.4/static/functions-conditional.html#FUNCTIONS-GREATEST-LEAST
+ * @see https://www.postgresql.org/docs/current/functions-conditional.html#FUNCTIONS-GREATEST-LEAST
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Greatest.php (1)

17-20: Simplified implementation using base class functionality

The getFunctionName() method replaces previous explicit function prototype customization and validation logic, delegating these responsibilities to the parent class BaseComparisonFunction. This simplification is consistent with the refactoring pattern applied across other function classes.

Consider updating the documentation reference to link to the latest PostgreSQL version rather than 9.4.

- * @see https://www.postgresql.org/docs/9.4/static/functions-conditional.html#FUNCTIONS-GREATEST-LEAST
+ * @see https://www.postgresql.org/docs/current/functions-conditional.html#FUNCTIONS-GREATEST-LEAST
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpSubstr.php (1)

7-19: Complete PHPDoc with all parameter details

The function documentation explains the purpose well, but could be improved by documenting all parameters that the function accepts. This would help users understand what each parameter does without needing to reference the PostgreSQL documentation.

 /**
  * Implementation of PostgreSQL REGEXP_SUBSTR().
  *
  * Returns the substring within string that matches the Nth occurrence of the POSIX regular expression pattern,
  * or NULL if there is no such match.
  *
  * @see https://www.postgresql.org/docs/15/functions-matching.html#FUNCTIONS-POSIX-REGEXP
  * @since 3.1
  *
  * @author Martin Georgiev <martin.georgiev@gmail.com>
  *
+ * @example Using it in DQL: "SELECT REGEXP_SUBSTR(e.text, 'c(.)(..)', 1, 1, 'i', 2) FROM Entity e"
- * @example Using it in DQL: "SELECT REGEXP_SUBSTR(e.text, 'c(.)(..)', 1, 1, 'i', 2) FROM Entity e"
+ * Parameters:
+ * 1. source - string to search in (required)
+ * 2. pattern - POSIX regular expression pattern (required)
+ * 3. start_position - position to begin searching (optional, default 1)
+ * 4. occurrence - which occurrence to return (optional, default 1)
+ * 5. flags - flags modifying regex behavior (optional)
+ * 6. subexpression - which captured subexpression to return (optional, default 0)
  */
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpReplace.php (1)

12-13: Consider adding additional details about parameter order

While the link to PostgreSQL documentation is updated to the latest version (17), it would be helpful to explicitly note the parameter order flexibility mentioned in the retrieved learnings.

 *
 * @see https://www.postgresql.org/docs/17/functions-matching.html#FUNCTIONS-POSIX-REGEXP
+ * Note: In PostgreSQL 16+, the parameter order can be either:
+ * - regexp_replace(source, pattern, replacement [, flags [, start [, N]]])
+ * - regexp_replace(source, pattern, replacement [, start [, N]] [, flags])
 * @since 2.5
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpSubstrTest.php (1)

1-66: Test coverage could be enhanced with more PostgreSQL documentation examples

While the test covers the parameter combinations of regexp_substr, it doesn't demonstrate the different behaviors produced by varying parameter values as shown in PostgreSQL documentation.

Consider adding test cases that demonstrate:

  1. Different start positions (e.g., starting search from middle of string)
  2. Different occurrence values (e.g., finding 2nd or 3rd match)
  3. Effect of different flags (e.g., showing that 'i' actually makes matching case-insensitive)
  4. Effect of different subexpression values (e.g., showing extraction of different capture groups)

Example test cases from PostgreSQL documentation:

 protected function getExpectedSqlStatements(): array
 {
     return [
         'extracts pattern' => "SELECT regexp_substr(c0_.text1, 'c(.)(...)') AS sclr_0 FROM ContainsTexts c0_",
         'extracts digits' => "SELECT regexp_substr(c0_.text1, '\\d+') AS sclr_0 FROM ContainsTexts c0_",
         'extracts digits with start and N parameters' => "SELECT regexp_substr(c0_.text1, '\\d+', 1, 4) AS sclr_0 FROM ContainsTexts c0_",
         'extracts digits with start and N parameters and flags' => "SELECT regexp_substr(c0_.text1, '\\d+', 1, 4, 'i') AS sclr_0 FROM ContainsTexts c0_",
         'extracts digits with start, N parameters, flags and subexpr parameter' => "SELECT regexp_substr(c0_.text1, '\\d+', 1, 4, 'i', 3) AS sclr_0 FROM ContainsTexts c0_",
+        'extracts second occurrence' => "SELECT regexp_substr(c0_.text1, '[0-9]+', 1, 2) AS sclr_0 FROM ContainsTexts c0_",
+        'starts search from position 5' => "SELECT regexp_substr(c0_.text1, '[a-z]+', 5, 1) AS sclr_0 FROM ContainsTexts c0_",
+        'extracts first subexpression' => "SELECT regexp_substr(c0_.text1, '([0-9]+)([a-z]+)', 1, 1, NULL, 1) AS sclr_0 FROM ContainsTexts c0_",
     ];
 }
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsquery.php (1)

17-35: Well-structured modular function configuration

The refactoring to small, focused protected methods follows good OOP principles and improves maintainability. The code now clearly separates configuration concerns.

Consider updating the PostgreSQL documentation reference

The documentation URL points to PostgreSQL 9.4, while other files in this codebase reference PostgreSQL 16. Consider updating this reference for consistency.

- * @see https://www.postgresql.org/docs/9.4/static/textsearch-controls.html
+ * @see https://www.postgresql.org/docs/16/textsearch-controls.html
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbSet.php (2)

32-35: Consider expanding the node‑mapping pattern.

JSONB_SET() accepts not only string literals but also column references and parameters for its first & third arguments (target jsonb / new value). Restricting the pattern to only StringPrimary could reject otherwise valid DQL such as
JSONB_SET(e.data, '{a}', :payload).
If StringPrimary is intentionally sufficient because BaseVariadicFunction applies the pattern per argument, please add a short inline comment; otherwise, you may want to return the more permissive pattern used in other JSONB helpers, e.g.

-return ['StringPrimary'];
+// Accept any primary expression (string literal, parameter, path, etc.)
+return ['ArithmeticPrimary'];

37-40: Deduplicate the function name with a class constant.

The literal 'jsonb_set' is duplicated here and also appears in exception messages constructed elsewhere. A private constant improves maintainability and avoids typos:

+private const FUNCTION_NAME = 'jsonb_set';
+
 protected function getFunctionName(): string
 {
-    return 'jsonb_set';
+    return self::FUNCTION_NAME;
 }
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryArray.php (1)

31-34: Promote function name to constant for consistency.

See earlier suggestion; the same applies here.

+private const FUNCTION_NAME = 'jsonb_path_query_array';
+
 protected function getFunctionName(): string
 {
-    return 'jsonb_path_query_array';
+    return self::FUNCTION_NAME;
 }
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpInstrTest.php (1)

52-68: Minor: factor repetitive DQL/SQL cases into data providers.

Converting the hard‑coded arrays to PHPUnit data providers will:

  1. reduce duplication between getExpectedSqlStatements() and getDqlStatements(),
  2. give each permutation its own explicit test case ID in PHPUnit’s output.

No functional change, but it improves readability of test failures.

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

16-34: Clarity of mapping pattern could be improved

Returning a single–element pattern leverages the “simple pattern repeats” logic in BaseVariadicFunction, which works fine here.
However, explicitly documenting that the second argument (optional dictionary) is also a StringPrimary would make intent clearer to future maintainers who might not be aware of this convention.

No code change required—adding a short inline comment is enough.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f85933f and 6d639f8.

📒 Files selected for processing (72)
  • .github/workflows/ci.yml (1 hunks)
  • composer.json (1 hunks)
  • docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md (1 hunks)
  • docs/AVAILABLE-TYPES.md (1 hunks)
  • docs/INTEGRATING-WITH-DOCTRINE.md (3 hunks)
  • docs/INTEGRATING-WITH-LARAVEL.md (4 hunks)
  • docs/INTEGRATING-WITH-SYMFONY.md (3 hunks)
  • fixtures/MartinGeorgiev/Doctrine/Entity/ContainsPoints.php (1 hunks)
  • fixtures/MartinGeorgiev/Doctrine/Function/TestVariadicFunction.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForDatabaseException.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForPHPException.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForDatabaseException.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForPHPException.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Point.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/PointArray.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/DBAL/Types/ValueObject/Point.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Arr.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayToJson.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseComparisonFunction.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateAdd.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateSubtract.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Distance.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Greatest.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObject.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObject.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbInsert.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathExists.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathMatch.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQuery.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryArray.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryFirst.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbSet.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Least.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpCount.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpInstr.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpReplace.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpSubstr.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Row.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowToJson.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsquery.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvector.php (1 hunks)
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Unaccent.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/DBAL/Types/PointArrayTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/DBAL/Types/PointTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayToJsonTest.php (2 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (2 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateAddTest.php (3 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateSubtractTest.php (3 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/GreatestTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObjectTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObjectTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbInsertTest.php (2 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathExistsTest.php (3 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathMatchTest.php (3 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryArrayTest.php (3 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryFirstTest.php (3 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryTest.php (3 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbSetTest.php (3 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/LeastTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpCountTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpInstrTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpReplaceTest.php (2 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpSubstrTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowToJsonTest.php (2 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsqueryTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvectorTest.php (1 hunks)
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/UnaccentTest.php (1 hunks)
✅ Files skipped from review due to trivial changes (8)
  • composer.json
  • .github/workflows/ci.yml
  • fixtures/MartinGeorgiev/Doctrine/Function/TestVariadicFunction.php
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpCount.php
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpInstr.php
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForPHPException.php
  • tests/MartinGeorgiev/Doctrine/DBAL/Types/PointArrayTest.php
🚧 Files skipped from review as they are similar to previous changes (14)
  • docs/AVAILABLE-TYPES.md
  • docs/INTEGRATING-WITH-SYMFONY.md
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForPHPException.php
  • src/MartinGeorgiev/Doctrine/DBAL/Types/ValueObject/Point.php
  • fixtures/MartinGeorgiev/Doctrine/Entity/ContainsPoints.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DistanceTest.php
  • docs/INTEGRATING-WITH-DOCTRINE.md
  • src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Distance.php
  • docs/INTEGRATING-WITH-LARAVEL.md
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointForDatabaseException.php
  • src/MartinGeorgiev/Doctrine/DBAL/Types/PointArray.php
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Point.php
  • src/MartinGeorgiev/Doctrine/DBAL/Types/Exceptions/InvalidPointArrayItemForDatabaseException.php
  • tests/MartinGeorgiev/Doctrine/DBAL/Types/PointTest.php
🧰 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/UnaccentTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbInsertTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateAddTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateSubtractTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsqueryTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathMatchTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryArrayTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathExistsTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/LeastTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayToJsonTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObjectTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvectorTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbSetTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/GreatestTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObjectTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpInstrTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowToJsonTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryFirstTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpReplaceTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpSubstrTest.php
  • tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpCountTest.php
🧠 Learnings (21)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/UnaccentTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateAddTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateSubtractTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsqueryTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathMatchTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryArrayTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathExistsTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/LeastTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayToJsonTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObjectTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvectorTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbSetTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/GreatestTest.php (2)
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.
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.
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpReplace.php (2)
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#0
File: :0-0
Timestamp: 2025-04-20T22:41:09.046Z
Learning: PostgreSQL's REGEXP_REPLACE function accepts between 3 and 6 arguments: REGEXP_REPLACE(source, pattern, replacement [, flags [, start [, N]]]). The first 3 parameters are required, and the rest are optional. The start and N parameters are available in PostgreSQL 16 and later.
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#0
File: :0-0
Timestamp: 2025-04-20T22:41:39.223Z
Learning: PostgreSQL's regexp_replace function has the full syntax: regexp_replace(source, pattern, replacement [, start [, N]] [, flags]). In newer PostgreSQL versions, it supports between 3 and 6 parameters, with the additional parameters allowing for specifying the start position and which occurrence to replace.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObjectTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryFirstTest.php (2)
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.
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.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpReplaceTest.php (2)
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.
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.
🧬 Code Graph Analysis (21)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/UnaccentTest.php (5)
fixtures/MartinGeorgiev/Doctrine/Entity/ContainsTexts.php (1)
  • ORM (10-18)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-135)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php (1)
  • InvalidArgumentForVariadicFunctionException (7-56)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Unaccent.php (1)
  • Unaccent (14-35)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (2)
  • BaseVariadicFunctionTestCase (14-42)
  • createFixture (16-16)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrTest.php (3)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-135)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (2)
  • BaseVariadicFunctionTestCase (14-42)
  • createFixture (16-16)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Arr.php (1)
  • Arr (15-41)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsqueryTest.php (5)
fixtures/MartinGeorgiev/Doctrine/Entity/ContainsTexts.php (1)
  • ORM (10-18)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-135)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php (1)
  • InvalidArgumentForVariadicFunctionException (7-56)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsquery.php (1)
  • ToTsquery (15-36)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (2)
  • BaseVariadicFunctionTestCase (14-42)
  • createFixture (16-16)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryArrayTest.php (6)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-135)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php (1)
  • InvalidArgumentForVariadicFunctionException (7-56)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidBooleanException.php (1)
  • InvalidBooleanException (14-33)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryArray.php (1)
  • JsonbPathQueryArray (22-55)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (2)
  • BaseVariadicFunctionTestCase (14-42)
  • createFixture (16-16)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowTest.php (1)
  • createFixture (16-19)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Greatest.php (6)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateAdd.php (1)
  • getFunctionName (32-35)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Arr.php (1)
  • getFunctionName (22-25)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • getFunctionName (27-27)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Least.php (1)
  • getFunctionName (17-20)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Row.php (1)
  • getFunctionName (19-22)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Unaccent.php (1)
  • getFunctionName (21-24)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvectorTest.php (5)
fixtures/MartinGeorgiev/Doctrine/Entity/ContainsTexts.php (1)
  • ORM (10-18)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-135)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php (1)
  • InvalidArgumentForVariadicFunctionException (7-56)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvector.php (1)
  • ToTsvector (15-36)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (2)
  • BaseVariadicFunctionTestCase (14-42)
  • createFixture (16-16)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpSubstr.php (1)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-135)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpReplace.php (1)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (5)
  • BaseVariadicFunction (20-135)
  • getNodeMappingPattern (32-32)
  • getFunctionName (27-27)
  • getMinArgumentCount (34-34)
  • getMaxArgumentCount (36-36)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (6)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-135)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/ParserException.php (1)
  • ParserException (7-18)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php (1)
  • TestCase (15-120)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrTest.php (1)
  • createFixture (13-16)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/LeastTest.php (1)
  • createFixture (14-17)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowTest.php (1)
  • createFixture (16-19)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Least.php (16)
fixtures/MartinGeorgiev/Doctrine/Function/TestVariadicFunction.php (1)
  • getFunctionName (25-28)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateAdd.php (1)
  • getFunctionName (32-35)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayToJson.php (1)
  • getFunctionName (33-36)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateSubtract.php (1)
  • getFunctionName (32-35)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Greatest.php (1)
  • getFunctionName (17-20)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Arr.php (1)
  • getFunctionName (22-25)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • getFunctionName (27-27)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObject.php (1)
  • getFunctionName (25-28)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbInsert.php (1)
  • getFunctionName (33-36)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObject.php (1)
  • getFunctionName (25-28)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbSet.php (1)
  • getFunctionName (37-40)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Row.php (1)
  • getFunctionName (19-22)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowToJson.php (1)
  • getFunctionName (32-35)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Unaccent.php (1)
  • getFunctionName (21-24)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvector.php (1)
  • getFunctionName (22-25)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsquery.php (1)
  • getFunctionName (22-25)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbSet.php (2)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (5)
  • getNodeMappingPattern (32-32)
  • getFunctionName (27-27)
  • getMinArgumentCount (34-34)
  • getMaxArgumentCount (36-36)
  • validateArguments (111-124)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Traits/BooleanValidationTrait.php (1)
  • validateBoolean (25-37)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Row.php (5)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Arr.php (4)
  • getNodeMappingPattern (17-20)
  • getFunctionName (22-25)
  • getMinArgumentCount (32-35)
  • getMaxArgumentCount (37-40)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (4)
  • getNodeMappingPattern (32-32)
  • getFunctionName (27-27)
  • getMinArgumentCount (34-34)
  • getMaxArgumentCount (36-36)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathExists.php (3)
  • getNodeMappingPattern (26-29)
  • getMinArgumentCount (36-39)
  • getMaxArgumentCount (41-44)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Greatest.php (1)
  • getFunctionName (17-20)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Least.php (1)
  • getFunctionName (17-20)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryArray.php (3)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (5)
  • getNodeMappingPattern (32-32)
  • getFunctionName (27-27)
  • getMinArgumentCount (34-34)
  • getMaxArgumentCount (36-36)
  • validateArguments (111-124)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQuery.php (5)
  • getNodeMappingPattern (27-30)
  • getFunctionName (32-35)
  • getMinArgumentCount (37-40)
  • getMaxArgumentCount (42-45)
  • validateArguments (47-55)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Traits/BooleanValidationTrait.php (1)
  • validateBoolean (25-37)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryFirstTest.php (20)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-135)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php (1)
  • InvalidArgumentForVariadicFunctionException (7-56)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidBooleanException.php (1)
  • InvalidBooleanException (14-33)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryFirst.php (1)
  • JsonbPathQueryFirst (23-56)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (2)
  • BaseVariadicFunctionTestCase (14-42)
  • createFixture (16-16)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrTest.php (1)
  • createFixture (13-16)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayToJsonTest.php (1)
  • createFixture (15-18)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateAddTest.php (1)
  • createFixture (15-18)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/GreatestTest.php (1)
  • createFixture (14-17)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObjectTest.php (1)
  • createFixture (14-17)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateSubtractTest.php (1)
  • createFixture (15-18)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObjectTest.php (1)
  • createFixture (14-17)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathMatchTest.php (1)
  • createFixture (15-18)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathExistsTest.php (1)
  • createFixture (15-18)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryArrayTest.php (1)
  • createFixture (15-18)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryTest.php (1)
  • createFixture (15-18)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowToJsonTest.php (1)
  • createFixture (15-18)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbSetTest.php (1)
  • createFixture (15-18)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/LeastTest.php (1)
  • createFixture (14-17)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowTest.php (1)
  • createFixture (16-19)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObject.php (3)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (5)
  • getNodeMappingPattern (32-32)
  • getFunctionName (27-27)
  • getMinArgumentCount (34-34)
  • getMaxArgumentCount (36-36)
  • validateArguments (111-124)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonBuildObject.php (5)
  • getNodeMappingPattern (20-23)
  • getFunctionName (25-28)
  • getMinArgumentCount (30-33)
  • getMaxArgumentCount (35-38)
  • validateArguments (40-47)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php (2)
  • InvalidArgumentForVariadicFunctionException (7-56)
  • evenNumber (39-45)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RowToJson.php (3)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ArrayToJson.php (5)
  • getNodeMappingPattern (28-31)
  • getFunctionName (33-36)
  • getMinArgumentCount (38-41)
  • getMaxArgumentCount (43-46)
  • validateArguments (48-56)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (5)
  • getNodeMappingPattern (32-32)
  • getFunctionName (27-27)
  • getMinArgumentCount (34-34)
  • getMaxArgumentCount (36-36)
  • validateArguments (111-124)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Traits/BooleanValidationTrait.php (1)
  • validateBoolean (25-37)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpReplaceTest.php (6)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-135)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php (1)
  • InvalidArgumentForVariadicFunctionException (7-56)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpReplace.php (1)
  • RegexpReplace (19-47)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (1)
  • BaseVariadicFunctionTestCase (14-42)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpCountTest.php (3)
  • createFixture (14-17)
  • test_too_few_arguments_throws_exception (46-53)
  • test_too_many_arguments_throws_exception (55-62)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php (1)
  • buildEntityManager (116-119)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryFirst.php (2)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (5)
  • getNodeMappingPattern (32-32)
  • getFunctionName (27-27)
  • getMinArgumentCount (34-34)
  • getMaxArgumentCount (36-36)
  • validateArguments (111-124)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Traits/BooleanValidationTrait.php (1)
  • validateBoolean (25-37)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpSubstrTest.php (4)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php (1)
  • InvalidArgumentForVariadicFunctionException (7-56)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpSubstr.php (1)
  • RegexpSubstr (20-47)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (1)
  • BaseVariadicFunctionTestCase (14-42)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php (1)
  • buildEntityManager (116-119)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathMatch.php (2)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (5)
  • getNodeMappingPattern (32-32)
  • getFunctionName (27-27)
  • getMinArgumentCount (34-34)
  • getMaxArgumentCount (36-36)
  • validateArguments (111-124)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Traits/BooleanValidationTrait.php (1)
  • validateBoolean (25-37)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpCountTest.php (9)
fixtures/MartinGeorgiev/Doctrine/Entity/Entity.php (1)
  • Entity (10-16)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunction.php (1)
  • BaseVariadicFunction (20-135)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Exception/InvalidArgumentForVariadicFunctionException.php (1)
  • InvalidArgumentForVariadicFunctionException (7-56)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpCount.php (1)
  • RegexpCount (19-44)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (1)
  • BaseVariadicFunctionTestCase (14-42)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpInstrTest.php (1)
  • createFixture (14-17)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpReplaceTest.php (1)
  • createFixture (14-17)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpSubstrTest.php (1)
  • createFixture (14-17)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/TestCase.php (1)
  • buildEntityManager (116-119)
🪛 markdownlint-cli2 (0.17.2)
docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md

26-26: Table pipe style
Expected: leading_only; Actual: leading_and_trailing; Unexpected trailing pipe

(MD055, table-pipe-style)

🔇 Additional comments (115)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateSubtract.php (2)

27-45: Implementation aligns well with the base class architecture.

The refactoring of the DateSubtract class properly implements the abstract methods from BaseVariadicFunction with clear, descriptive method implementations that define function behavior.


49-54: Good use of parent validation logic.

The implementation correctly delegates to parent validation first and then only performs the timezone-specific validation when needed, avoiding duplicate code.

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

27-45: Implementation aligns well with the base class architecture.

The refactoring of the RowToJson class properly implements the abstract methods from BaseVariadicFunction with clear, descriptive method implementations that define function behavior.


49-54: Good use of parent validation logic.

The implementation correctly delegates to parent validation first and then only performs the boolean-specific validation when needed, avoiding duplicate code.

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

9-16: Implementation follows the test base class pattern.

The test now properly extends BaseVariadicFunctionTestCase and implements the required createFixture() method. This approach standardizes test initialization across function tests.

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

40-40: Error message update looks good.

The error message now reflects the lowercase function name style used throughout the codebase.


49-49: Error message update looks good.

The error message now uses the "at least" phrasing which matches the parent class validation message style.

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

11-19: Test refactoring aligns with new inheritance hierarchy.

The test class has been updated to use the new BaseVariadicFunctionTestCase as its parent, and a new createFixture() method has been implemented to provide the test instance. This change is consistent with the broader refactoring in the codebase that standardizes testing of variadic functions.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/UnaccentTest.php (3)

8-17: Test refactoring aligns with new inheritance hierarchy.

The test has been properly updated to extend BaseVariadicFunctionTestCase and implement the abstract createFixture() method, which returns an instance of the Unaccent function. This change is consistent with the broader standardization of variadic function testing in this codebase.


28-31: Test coverage matches documented usage patterns for UNACCENT.

The SQL test statements correctly test the two main forms of the unaccent function:

  1. Single argument: unaccent(text)
  2. Two arguments: unaccent(regdictionary, text)

According to PostgreSQL documentation, these are the valid forms for this function, so the test coverage is appropriate.


42-51: Test correctly validates argument validation.

The test includes a specific test case for validating that providing too many arguments to the function throws an appropriate exception, which is important for ensuring the function behaves correctly in error scenarios.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsvectorTest.php (3)

8-17: Test refactoring aligns with new inheritance hierarchy.

The test has been correctly updated to extend BaseVariadicFunctionTestCase and implement the required createFixture() method, returning an instance of ToTsvector. This change is part of the standardization of variadic function testing in the codebase.


28-32: Test cases cover the main usage patterns for to_tsvector.

These test cases correctly cover the primary forms of to_tsvector:

  1. to_tsvector(text) - Direct conversion
  2. to_tsvector(text) with a function as input - Text manipulation before conversion
  3. to_tsvector(regconfig, text) - Using a specific text search configuration

According to PostgreSQL documentation, these are the main usage patterns for this function.


44-53: Exception testing for argument validation is correctly implemented.

The test includes a specific test case for validating that providing too many arguments throws the appropriate exception. This is important for ensuring the function behaves correctly in error cases.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/ToTsqueryTest.php (3)

8-17: Test refactoring aligns with new inheritance hierarchy.

The test has been properly updated to extend BaseVariadicFunctionTestCase and implement the required createFixture() method, returning an instance of ToTsquery. This follows the broader refactoring pattern in the codebase for standardizing variadic function tests.


28-32: Test cases cover the main usage patterns for to_tsquery.

The SQL test statements correctly cover the primary forms of to_tsquery:

  1. to_tsquery(text) - Direct conversion
  2. to_tsquery(text) with function as input - Text manipulation before conversion
  3. to_tsquery(regconfig, text) - Using a specific text search configuration

These match the usage patterns documented in PostgreSQL for this function.


44-53: Exception testing for argument validation is properly implemented.

The test includes a test case for validating that providing too many arguments throws the appropriate exception. This is important for ensuring correct behavior in error scenarios.

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

9-18: Updates look good, follows the refactored pattern for variadic function testing.

The changes correctly implement the new base class pattern by extending BaseVariadicFunctionTestCase and adding the required createFixture() method. This aligns with the project's standardized approach for testing variadic functions.


46-46: Function name in error message correctly updated for consistency.

The lowercase function name in the error message is now consistent with other similar function tests in the codebase, improving readability and maintaining the project's error message standards.

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

8-17: Updates correctly implement the standardized testing pattern.

The changes properly implement the project's standardized approach by:

  1. Importing the required BaseVariadicFunction class
  2. Extending BaseVariadicFunctionTestCase instead of the previous base class
  3. Adding the createFixture() method that returns an appropriately configured JsonBuildObject instance

This aligns with other test refactoring in this PR and improves consistency across the codebase.

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

8-18: Changes correctly follow the standardized testing pattern.

The refactoring properly implements the new base class pattern for variadic function tests by:

  1. Importing the required BaseVariadicFunction class
  2. Extending BaseVariadicFunctionTestCase
  3. Implementing the required createFixture() method

This brings consistency with other test classes in the codebase.


48-48: Error message correctly updated for consistency.

The function name in the error message is now lowercase, which matches the convention used in other similar function tests throughout the codebase.

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

8-17: Correctly migrated from comparison to variadic function base class.

The changes properly update this test to use the variadic function pattern instead of the comparison function pattern:

  1. Importing BaseVariadicFunction instead of what was likely BaseComparisonFunction
  2. Extending BaseVariadicFunctionTestCase instead of what was likely BaseComparisonFunctionTestCase
  3. Updating the return type of createFixture()
  4. Using uppercase 'LEAST' as the function name for consistency

These changes align with the standardization of variadic function testing in the codebase.

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

8-8: Import added for the base class.

The import for BaseVariadicFunction has been added as required by the new createFixture() method's return type.


13-18: Class now properly extends the base test case for variadic functions.

The class has been updated to:

  1. Extend BaseVariadicFunctionTestCase instead of TestCase
  2. Implement the required createFixture() method

This change aligns with the standardized approach for testing variadic functions in the codebase.


50-50: Exception message updated to use lowercase function name.

The expected exception message now uses the lowercase function name jsonb_path_match instead of uppercase, which matches the actual PostgreSQL function name. This is consistent with other exception messages in the codebase.


59-59: Updated error message for argument count validation.

The error message now states "requires at least 2 arguments" instead of specifying an upper bound in this particular error case. This aligns with the new approach of validating arguments in the BaseVariadicFunction class.


68-72:

✅ Verification successful

Test case for too many arguments needs PostgreSQL documentation verification.

The error message for too many arguments still states "requires between 2 and 4 arguments". Please verify that this aligns with the PostgreSQL documentation for the jsonb_path_match function, which should accept a maximum of 4 arguments.


🌐 Web query:

PostgreSQL jsonb_path_match function arguments count

💡 Result:

PostgreSQL jsonb_path_match Function: Arguments Count

Arguments Overview

The jsonb_path_match function in PostgreSQL is used to evaluate a JSON path predicate on a jsonb value and return the result as a boolean. According to the documentation and cross-platform similarities, the function signature is:

jsonb_path_match(target jsonb, path text [, vars jsonb [, silent boolean]])

This means the function accepts:

  • 2 required arguments:
    • The target jsonb value.
    • The JSON path expression (as a string).
  • 2 optional arguments:
    • A jsonb object for path variables.
    • A boolean flag for silent error handling.

So, the function can take a minimum of 2 and a maximum of 4 arguments[2][5].

Example Usage

  • Basic use with 2 arguments:
    SELECT jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= 3))');
    
  • With variables and silent flag:
    SELECT jsonb_path_match('{"a":[1,2,3,4,5]}', 'exists($.a[*] ? (@ >= $min))', '{"min": 3}', true);
    

Summary Table

Argument Position Type Required Description
1 jsonb Yes Target JSONB value
2 text Yes JSON path predicate
3 jsonb No JSON path variables (default: null)
4 boolean No Silent error flag (default: false)

Conclusion

The jsonb_path_match function accepts between two and four arguments: the target JSONB, the JSON path, and optionally, path variables and a silent flag[2][5].

Citations:


jsonb_path_match argument count verified
The PostgreSQL jsonb_path_match function accepts between 2 and 4 arguments, so asserting an error when passing 5 is correct. No changes needed.

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

8-8: Import added for the base class.

The import for BaseVariadicFunction has been added as required by the new createFixture() method's return type.


13-18: Class now properly extends the base test case for variadic functions.

The class has been updated to:

  1. Extend BaseVariadicFunctionTestCase instead of TestCase
  2. Implement the required createFixture() method

This change aligns with the standardized approach for testing variadic functions in the codebase.


50-50: Exception message updated to use lowercase function name.

The expected exception message now uses the lowercase function name jsonb_path_query instead of uppercase, which matches the actual PostgreSQL function name. This is consistent with other exception messages in the codebase.


59-59: Updated error message for argument count validation.

The error message now states "requires at least 2 arguments" instead of specifying an upper bound in this particular error case. This aligns with the new approach of validating arguments in the BaseVariadicFunction class.


68-72:

✅ Verification successful

Test case for too many arguments needs PostgreSQL documentation verification.

The error message for too many arguments still states "requires between 2 and 4 arguments". Please verify that this aligns with the PostgreSQL documentation for the jsonb_path_query function, which should accept a maximum of 4 arguments.


🌐 Web query:

PostgreSQL jsonb_path_query function arguments count

💡 Result:

PostgreSQL jsonb_path_query Function: Argument Count and Usage

Function Signature

The PostgreSQL jsonb_path_query function extracts items from a jsonb value that match a specified JSON path expression. According to the official documentation and various technical resources, the function can accept between two and four arguments, as shown below[1][3][5]:

jsonb_path_query(target jsonb, path text [, vars jsonb [, silent boolean]]) → setof jsonb

Arguments

  1. target (jsonb, required)
    The JSONB value to search in.

  2. path (text, required)
    The JSON path expression to evaluate against the target jsonb value.

  3. vars (jsonb, optional)
    A JSON object defining named variables that can be used within the path expression.

  4. silent (boolean, optional)
    A flag indicating whether errors (such as invalid path expressions) should be suppressed (if true) or reported (if false). The default is false.

Example Usages

  • Two Arguments (basic usage):
    SELECT jsonb_path_query('{"users":[{"name":"Alice"},{"name":"Bob"}]}', '$.users[*].name');
  • Three Arguments (with variables):
    SELECT jsonb_path_query(
        '{"employees":[{"name":"John","age":30},{"name":"Jane","age":25}]}',
        '$.employees[*] ? (@.age >= $min_age)',
        '{"min_age": 28}'
    );
  • Four Arguments (with variables and silent mode):
    SELECT jsonb_path_query(
        '{"employees":[{"name":"John"}]}',
        '$.employees[*] ? (@.salary > 0)',
        '{}',
        true
    );

Summary Table

Argument Position Name Type Required Description
1 target jsonb Yes The JSONB data to query.
2 path text Yes The JSON path expression.
3 vars jsonb No Path variables in JSONB format.
4 silent boolean No Suppress errors (default: false).

References:

  • Official documentation and function signature[1][3][5].

In summary:
The jsonb_path_query function in PostgreSQL can take 2, 3, or 4 arguments: (target jsonb, path text [, vars jsonb [, silent boolean]])[3][5].

Citations:


Exception message matches PostgreSQL’s argument requirements

The PostgreSQL jsonb_path_query function indeed accepts between 2 and 4 arguments (target JSONB, path text, optional vars JSONB, and optional silent boolean), so the test’s expected error message is correct. No changes required.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryArrayTest.php (6)

8-8: Import added for the base class.

The import for BaseVariadicFunction has been added as required by the new createFixture() method's return type.


13-18: Class now properly extends the base test case for variadic functions.

The class has been updated to:

  1. Extend BaseVariadicFunctionTestCase instead of TestCase
  2. Implement the required createFixture() method

This change aligns with the standardized approach for testing variadic functions in the codebase.


50-50: Exception message updated to use lowercase function name.

The expected exception message now uses the lowercase function name jsonb_path_query_array instead of uppercase, which matches the actual PostgreSQL function name. This is consistent with other exception messages in the codebase.


59-59: Updated error message for argument count validation.

The error message now states "requires at least 2 arguments" instead of specifying an upper bound in this particular error case. This aligns with the new approach of validating arguments in the BaseVariadicFunction class.


29-34: Comprehensive test cases for jsonb_path_query_array function.

The test suite includes various usage patterns for the jsonb_path_query_array function:

  1. Extracting arrays with conditions
  2. Extracting arrays of items
  3. Using the vars argument
  4. Using both vars and silent arguments

This covers the full range of functionality and aligns with the coding guideline to include comprehensive test cases based on PostgreSQL documentation.


68-72:

✅ Verification successful

Test case for too many arguments needs PostgreSQL documentation verification.

The error message for too many arguments still states "requires between 2 and 4 arguments". Please verify that this aligns with the PostgreSQL documentation for the jsonb_path_query_array function, which should accept a maximum of 4 arguments.


🌐 Web query:

PostgreSQL jsonb_path_query_array function arguments count

💡 Result:

PostgreSQL jsonb_path_query_array Function: Argument Count

The jsonb_path_query_array() function in PostgreSQL is used to extract elements from a JSONB value that match a specified JSONPath expression and return them as a JSON array.

Argument Details

The function accepts 2 to 4 arguments:

  1. target (required): The JSONB value to query.
  2. path (required): The JSONPath expression (as type jsonpath) to use for matching elements.
  3. vars (optional): A JSONB object containing variables for use in the path expression.
  4. silent (optional): A boolean flag. If true, errors are suppressed for certain path issues.

Function Signature

jsonb_path_query_array(
    target JSONB,
    path JSONPATH
    [, vars JSONB
    [, silent BOOLEAN]]
) → JSONB
  • You must provide at least target and path.
  • The vars and silent arguments are optional and can be omitted[4][5][6][8].

Examples

  • Two arguments:
    SELECT jsonb_path_query_array('{"a": [1,2,3,4,5]}', '$.a[*] ? (@ > 2)');
    -- returns [3, 4, 5]
  • Three arguments:
    SELECT jsonb_path_query_array(
        '{"employees":[{"name":"John","age":30},{"name":"Bob","age":25}]}',
        '$.employees[*] ? (@.age >= $min && @.age <= $max)',
        '{"min":24,"max":32}'
    );
    -- returns [{"age":30,"name":"John"}, {"age":25,"name":"Bob"}]
  • Four arguments:
    SELECT jsonb_path_query_array(
        '{"x": 1}', '$.x', NULL, TRUE
    );

Summary Table

Argument Position Name Type Required Description
1 target JSONB Yes JSONB value to search
2 path JSONPATH Yes Path expression to use
3 vars JSONB No Variables for use in path (as JSONB object)
4 silent BOOLEAN No Suppress errors if TRUE

In total, jsonb_path_query_array() accepts between 2 and 4 arguments, depending on your needs[4][5][6][8].

Citations:


Error message is correct per PostgreSQL docs

The PostgreSQL documentation confirms that jsonb_path_query_array() accepts 2 to 4 arguments, matching the exception message in this test. No changes are needed.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateAddTest.php (6)

8-8: Import added for the base class.

The import for BaseVariadicFunction has been added as required by the new createFixture() method's return type.


13-18: Class now properly extends the base test case for variadic functions.

The class has been updated to:

  1. Extend BaseVariadicFunctionTestCase instead of TestCase
  2. Implement the required createFixture() method

This change aligns with the standardized approach for testing variadic functions in the codebase.


50-50: Exception message updated to use lowercase function name.

The expected exception message now uses the lowercase function name date_add instead of uppercase, which matches the actual PostgreSQL function name. This is consistent with other exception messages in the codebase.


59-59: Updated error message for argument count validation.

The error message now states "requires at least 2 arguments" instead of specifying an upper bound in this particular error case. This aligns with the new approach of validating arguments in the BaseVariadicFunction class.


29-34: Comprehensive test cases for date_add function.

The test suite includes various usage patterns for the date_add function:

  1. Adding days with timezone
  2. Adding hours with timezone
  3. Adding days without timezone
  4. Using in a WHERE clause

This covers the full range of functionality and aligns with the coding guideline to include comprehensive test cases based on PostgreSQL documentation.


68-72:

❌ Incorrect review comment

Test case for too many arguments needs PostgreSQL documentation verification.

The error message for too many arguments still states "requires between 2 and 3 arguments". Please verify that this aligns with the PostgreSQL documentation for the date_add function, which should accept a maximum of 3 arguments.


🌐 Web query:

PostgreSQL date_add function arguments count

💡 Result:

Arguments Count for PostgreSQL date_add Function

PostgreSQL does not have a built-in date_add() function like MySQL or SQL Server. Instead, PostgreSQL handles date and time arithmetic using the addition (+) operator with intervals, or by using explicit interval addition functions. However, some guides and tools informally reference a date_add() function for demonstration purposes or as a user-defined wrapper[2][4].

Common Usage and Arguments

When referenced, the date_add() function in PostgreSQL typically takes two arguments:

  • date_expression: The date, timestamp, or column to which you want to add the interval.
  • interval_expression: The interval you want to add, like '1 day', '2 months', etc.

Syntax:

date_add(date_expression, interval_expression)

Example:

SELECT event_date, date_add(event_date, '1 day') AS updated_date FROM events;

Here, event_date is the first argument, and the string '1 day' representing the interval is the second argument[2].

PostgreSQL Standard Approach

PostgreSQL's standard method for adding intervals is:

date_value + INTERVAL '1 day'

This does not use the date_add() function but achieves the same result[1][4].

Summary Table

Argument Position Name Description
1 date_expression The date or timestamp to modify
2 interval_expression Interval to add (as a string, e.g., '1 day')

Total arguments required: 2 for the typical date_add() reference in PostgreSQL contexts[2].

Key Point

  • If you are porting from other SQL dialects (MySQL, SQL Server), be aware that PostgreSQL does not natively support a date_add() function and instead uses date arithmetic with intervals[4].
  • When used as a wrapper or alias, date_add() always expects two arguments: the date/timestamp and the interval[2].

Citations:


Ignore PostgreSQL docs for Doctrine’s DQL DateAdd signature

The DateAddTest is validating Doctrine’s DQL AST function—which by design accepts 2 or 3 arguments (date + interval, with an optional timezone or unit). The error message “requires between 2 and 3 arguments” correctly matches Doctrine’s own signature, not a native PostgreSQL function. No changes are needed here.

Likely an incorrect or invalid review comment.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbBuildObjectTest.php (3)

8-8: LGTM: Properly updated to use the new BaseVariadicFunctionTestCase.

The changes appropriately align this test with the broader refactoring of variadic function tests. The class now extends BaseVariadicFunctionTestCase and implements the required createFixture() method that returns an instance of JsonbBuildObject.

Also applies to: 12-17


26-42: Test cases look comprehensive and well-structured.

The test includes multiple SQL use cases for the jsonb_build_object function, testing different scenarios:

  1. Simple key-value with a column reference
  2. Multiple key-values with string literals and functions
  3. Multiple key-values with column references

These examples align well with PostgreSQL's official documentation for this function.


44-53: Validation test for argument count is properly implemented.

The test appropriately verifies that the function throws an exception when given an odd number of arguments, which is a requirement for the jsonb_build_object function.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateSubtractTest.php (4)

8-8: LGTM: Properly updated to use the new BaseVariadicFunctionTestCase.

The changes correctly align this test with the broader refactoring of variadic function tests. The class now extends BaseVariadicFunctionTestCase and implements the required createFixture() method.

Also applies to: 13-18


48-48: Exception messages appropriately updated to match new conventions.

The exception messages have been updated to use lowercase function names and revised argument count phrasing, which is consistent with the conventions used across other function tests in this refactoring.

Also applies to: 57-57


27-43: Test cases cover comprehensive use cases for date subtraction.

The test includes various SQL examples for the date_subtract function with:

  1. Subtracting days with timezone
  2. Subtracting hours with different timezone
  3. Subtracting days without timezone

These test cases provide good coverage of the function's capabilities.


54-70: Complete error handling tests for argument validation.

The test suite properly checks for error cases:

  1. Invalid timezone handling
  2. Too few arguments
  3. Too many arguments

This ensures robust validation of function inputs.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbSetTest.php (4)

8-8: LGTM: Properly updated to use the new BaseVariadicFunctionTestCase.

The changes correctly align this test with the broader refactoring of variadic function tests. The class now extends BaseVariadicFunctionTestCase and implements the required createFixture() method.

Also applies to: 13-18


46-46: Exception messages appropriately updated to match new conventions.

The exception messages have been updated to use lowercase function names and revised argument count phrasing, which is consistent with the conventions used across other function tests in this refactoring.

Also applies to: 55-55


27-41: Test cases cover key use cases for jsonb_set function.

The test includes different scenarios for the jsonb_set function:

  1. Basic usage with object path and value
  2. Usage with create-if-missing parameter

These tests align with the PostgreSQL documentation for this function.


43-68: Thorough error handling tests for Boolean validation and argument counts.

The test suite comprehensively checks error cases:

  1. Invalid boolean parameter validation
  2. Too few arguments
  3. Too many arguments

This ensures the function properly validates its inputs.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/GreatestTest.php (4)

8-8: LGTM: Properly updated to use the new BaseVariadicFunctionTestCase.

The changes correctly align this test with the broader refactoring of variadic function tests. The class now extends BaseVariadicFunctionTestCase (changed from BaseComparisonFunctionTestCase) and updates the return type of the createFixture() method.

Also applies to: 12-17


26-42: Test cases provide good coverage of the GREATEST function.

The test includes multiple SQL examples for the greatest function:

  1. Comparing multiple column values
  2. Comparing column values with expressions
  3. Comparing multiple expressions

These test cases align with PostgreSQL's documentation and show the function's versatility.


44-53: Argument validation test is properly implemented.

The test correctly verifies that the function throws an exception when given a single argument, as the greatest function requires at least two values to compare.


1-55: Where are the tests for the new distance operator <@>?

While the refactoring changes look good, I don't see any tests for the new distance operator <@> mentioned in the PR title. According to the coding guidelines, tests should include comprehensive use cases and example SQL queries for tested SQL functions and operators.

Is there another file that contains the tests for the distance operator? Please ensure that adequate test coverage is provided for this new feature.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathQueryFirstTest.php (3)

8-18: Implementation follows refactoring pattern

The changes to extend BaseVariadicFunctionTestCase instead of TestCase and implement the createFixture() method follow the project's standardization pattern for testing variadic function implementations. This is consistent with other similar test classes in the codebase.


50-50: Improved error message consistency

Update to use lowercase function name in the error message (jsonb_path_query_first instead of uppercase) is consistent with PostgreSQL naming conventions and aligns with other error messages in the codebase.


59-59: Corrected error message for argument validation

The updated error message now correctly specifies that the function requires at least 2 arguments, which matches the implementation in the JsonbPathQueryFirst class that sets a minimum argument count of 2.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonbPathExistsTest.php (3)

8-18: Implementation follows refactoring pattern

The changes to extend BaseVariadicFunctionTestCase instead of TestCase and implement the createFixture() method follow the project's standardization pattern for testing variadic function implementations. This is consistent with other similar test classes in the codebase.


50-50: Improved error message consistency

Update to use lowercase function name in the error message (jsonb_path_exists instead of uppercase) is consistent with PostgreSQL naming conventions and aligns with other error messages in the codebase.


59-59: Corrected error message for argument validation

The updated error message now correctly specifies that the function requires at least 2 arguments, which matches the implementation in the JsonbPathExists class that sets a minimum argument count of 2.

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

22-31: Comprehensive node mapping for all PostgreSQL parameter combinations

The implementation correctly handles all valid parameter combinations for the PostgreSQL REGEXP_SUBSTR function, in line with the documentation.


33-46: Well-defined function constraints match PostgreSQL documentation

The implementation correctly defines the function name and the required parameter constraints (min: 2, max: 6) which match PostgreSQL's specifications for REGEXP_SUBSTR.

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

10-12: Documentation updates reflect function behavior accurately

The improved description better explains the purpose of the REGEXP_REPLACE function.


17-18: Example usage shows all parameters in correct order

The example has been updated to show all six possible parameters, making it clearer how to use the function in DQL.


21-31: Comprehensive node mapping patterns for all parameter combinations

The implementation correctly supports all valid parameter combinations for REGEXP_REPLACE, including the flexibility in parameter ordering as mentioned in the retrieved learnings.


38-46: Parameter constraints match PostgreSQL specifications

The implementation correctly defines the minimum (3) and maximum (6) argument counts for REGEXP_REPLACE, matching PostgreSQL's specifications as noted in the retrieved learnings.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/BaseVariadicFunctionTestCase.php (3)

11-14: Appropriate class name change reflecting architecture refactoring

The class name change from (implied) BaseComparisonFunctionTestCase to BaseVariadicFunctionTestCase properly reflects the architectural shift to using BaseVariadicFunction as the parent class for variadic SQL functions.


16-16: Updated method signature to use new base class

The return type of createFixture() has been correctly updated to BaseVariadicFunction, aligning with the broader refactoring effort.


36-40: Test correctly adapted to new architecture

The test method has been updated to use the new class name and parameter requirements for feedParserWithNodesForNodeMappingPattern, which now expects a node mapping pattern as a second parameter.

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

14-27: Well-structured implementation of required abstract methods

The implementation correctly provides the required abstract methods from BaseVariadicFunction:

  • getNodeMappingPattern() returns a simplified pattern for comparison functions
  • getMinArgumentCount() correctly requires at least 2 arguments for comparison
  • getMaxArgumentCount() allows unlimited arguments, which is appropriate for comparison functions

This change aligns with the architecture refactoring to standardize implementation of variadic SQL functions across the codebase.

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

20-38: Implementation looks good!

The refactored code properly implements the abstract methods from BaseVariadicFunction, providing clear definitions for node mapping pattern, function name, and argument count constraints.


42-46: Consistent validation implementation.

The argument validation correctly delegates to the parent class first, then implements the specific requirement for an even number of arguments (required for key-value pairs in JSON build objects).

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

26-44: Implementation looks good!

The refactored code properly implements the abstract methods from BaseVariadicFunction with appropriate values for this specific function.


48-53: Validation implementation is correct.

The argument validation correctly delegates to the parent class first, then implements specific validation for the boolean parameter when 4 arguments are provided.

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

20-38: Implementation looks good!

The refactored code properly implements the abstract methods from BaseVariadicFunction with appropriate values that match the PostgreSQL jsonb_build_object function requirements.


42-46: Validation implementation is correct.

The argument validation correctly delegates to the parent class first, then implements the specific requirement for an even number of arguments (required for key-value pairs in JSONB build objects).

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

27-45: Well-structured modular function configuration

The refactoring to small, focused protected methods follows good OOP principles and improves maintainability. The code now clearly separates configuration concerns (node mapping pattern, function name, argument counts) instead of having them embedded in a single method.


49-54: Good validation approach with parent delegation

This implementation properly delegates to the parent's validateArguments method first, then performs specialized timezone validation. Using getFunctionName() instead of hardcoding the function name in the error message is a nice touch for maintainability.

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

28-46: Well-structured modular function configuration

The refactoring to small, focused protected methods follows good OOP principles and improves maintainability. The code now clearly separates configuration concerns (node mapping pattern, function name, argument counts) instead of having them embedded in a single method.


50-55: Good validation approach with parent delegation

This implementation properly delegates to the parent's validateArguments method first, then performs specialized boolean validation. Using getFunctionName() instead of hardcoding the function name in the error message is a nice touch for maintainability.

tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/RegexpReplaceTest.php (4)

7-17: Good test structure with appropriate base class

Extending BaseVariadicFunctionTestCase and implementing createFixture() properly aligns this test with the refactored function implementation pattern.


28-36: Comprehensive test cases for SQL generation

The test cases cover all argument combinations for the regexp_replace function, which is excellent.


40-47: Well-structured test cases with descriptive names

Using named array keys significantly improves readability by clearly describing each test case's purpose.


50-66: Good validation testing

These tests properly verify that the function throws appropriate exceptions with correct messages when provided with invalid argument counts.

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

52-60: Boolean validation guard looks good – minor micro‑optimisation available.

Because parent::validateArguments() has already guaranteed that $arguments contains either 3 or 4 elements, the explicit \count($arguments) === 4 check could be replaced with isset($arguments[3]) which is marginally faster and reads intent more clearly.

No action required if you prefer the current style.

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

46-54: Good reuse of parent validation.

Delegating to parent::validateArguments() keeps the logic DRY and in line with the new architecture.

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

26-37: Excellent breadth of test coverage.

The fixture exercises all argument‑count permutations (2 → 7) and checks both SQL generation and validation errors—nicely aligning with the PostgreSQL documentation examples.

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

28-31: Implementation aligns with abstract method requirement

The getNodeMappingPattern() method correctly implements the abstract method from the base class, returning the StringPrimary pattern which is appropriate for this function.


33-36: Function name correctly defined

The getFunctionName() method properly returns the PostgreSQL function name 'jsonb_insert', which matches the function's purpose as described in the class documentation.


38-46: Argument count constraints properly defined

The min and max argument count methods correctly define the constraints for the jsonb_insert function (3-4 arguments), which aligns with PostgreSQL's function signature.


48-56: Improved argument validation

The refactored validation logic properly leverages the parent class's validation for argument count checking and adds specific validation for the optional boolean parameter. Using getFunctionName() for error messages ensures consistency if the function name changes.

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

17-20: Implementation aligns with abstract method requirement

The getNodeMappingPattern() method correctly implements the abstract method from the base class, returning the StringPrimary pattern.


22-25: Function name correctly defined

The getFunctionName() method properly returns 'ARRAY', which corresponds to PostgreSQL's array constructor syntax.


27-30: Function prototype correctly customized

The customizeFunction() implementation now dynamically uses the function name from getFunctionName(), improving maintainability if the function name ever changes.


32-40: Argument count constraints properly defined

The implementation correctly defines the constraints for the ARRAY constructor (minimum 1 argument, no maximum), which aligns with PostgreSQL's syntax requirements.

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

27-30: Implementation aligns with abstract method requirement

The getNodeMappingPattern() method correctly implements the abstract method from the base class, returning the StringPrimary pattern.


32-35: Function name correctly defined

The getFunctionName() method properly returns 'jsonb_path_query', which matches the PostgreSQL function.


37-45: Argument count constraints properly defined

The min and max argument count methods correctly define the constraints for the jsonb_path_query function (2-4 arguments), which aligns with PostgreSQL's function signature.


47-55: Improved argument validation

The refactored validation logic properly leverages the parent class's validation for argument count checking and adds specific validation for the optional boolean parameter. Using getFunctionName() for error messages ensures consistency if the function name changes.

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

27-30: Implementation aligns with abstract method requirement

The getNodeMappingPattern() method correctly implements the abstract method from the base class, returning the StringPrimary pattern.


32-35: Function name correctly defined

The getFunctionName() method properly returns 'jsonb_path_query_first', which matches the PostgreSQL function.


37-45: Argument count constraints properly defined

The min and max argument count methods correctly define the constraints for the jsonb_path_query_first function (2-4 arguments), which aligns with PostgreSQL's function signature.


47-55: Improved argument validation

The validation logic properly leverages the parent class's validation for argument count checking and adds specific validation for the optional boolean parameter. Using getFunctionName() ensures consistency if the function name changes.

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

26-34: Test cases correctly model PostgreSQL's regexp_count function behavior.

The test cases cover the essential use cases for PostgreSQL's regexp_count function:

  • Basic pattern matching for digits and words
  • Using the start position parameter
  • Using the flags parameter

The SQL generation looks correct against PostgreSQL's regexp_count documentation.


46-53: Validation for too few arguments aligns with function requirements.

The test correctly verifies that the function throws an appropriate exception when called with fewer than the required minimum of 2 arguments.

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

28-46: Implementation correctly configures function properties.

The refactoring properly defines the function metadata through dedicated methods:

  • Node mapping pattern is correctly set to 'StringPrimary'
  • Function name matches PostgreSQL's jsonb_path_match
  • Argument count constraints (2-4) match PostgreSQL's function signature

This implementation aligns with the consistent pattern applied across other function classes.


48-55: Boolean validation aligns with PostgreSQL's jsonb_path_match requirements.

The method correctly validates that the fourth parameter (when present) is a valid boolean, which matches PostgreSQL's jsonb_path_match function signature where the fourth parameter is a boolean flag. The implementation now uses the dynamically retrieved function name rather than a hardcoded string.

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

17-35: Refactoring aligns with project-wide standardization.

The implementation correctly defines:

  • Node mapping pattern as 'StringExpression'
  • Function name as 'to_tsvector'
  • Argument constraints (min: 1, max: 2) matching PostgreSQL's function signature

This refactoring follows the consistent pattern applied across all function classes in the project, improving maintainability.

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

14-32: Implementation correctly supports PostgreSQL's ROW constructor syntax.

The refactoring properly defines:

  • Node mapping pattern as 'InParameter'
  • Function name as 'ROW'
  • Minimum argument count of 1
  • Maximum argument count as PHP_INT_MAX (unlimited)

This implementation correctly reflects that PostgreSQL's ROW constructor can accept any number of arguments (at least one), and uses the appropriate mapping for parameter handling.

coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 23, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 23, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 23, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes Apr 23, 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.

2 participants