-
-
Notifications
You must be signed in to change notification settings - Fork 56
feat: add (limited) support for json_exists, json_query, json_scalar, json_serialize and json_value
#277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…on_serialize` and `json_value`
…on_serialize` and `json_value`
WalkthroughThis update adds several new JSON functions to the Doctrine ORM. The changes update documentation for available functions and integration guides for Doctrine, Laravel, and Symfony. New classes for JSON operations—such as JSON_EXISTS, JSON_QUERY, JSON_SCALAR, JSON_SERIALIZE, and JSON_VALUE—are introduced along with their custom implementations. Corresponding test cases have been added to verify their functionality, and one outdated function (JSONB_BUILD_OBJECT) has been removed from the configuration. These modifications collectively enhance support for JSON data manipulation within DQL queries. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant DoctrineORM
participant CustomFunction
participant SQLEngine
User->>DoctrineORM: Submit DQL query with JSON function call
DoctrineORM->>CustomFunction: Map call to corresponding JSON function (e.g., JSON_EXISTS)
CustomFunction-->>DoctrineORM: Generate SQL fragment
DoctrineORM->>SQLEngine: Execute generated SQL query
SQLEngine-->>DoctrineORM: Return query results
DoctrineORM-->>User: Deliver final results
Possibly related PRs
Poem
Tip ⚡🧪 Multi-step agentic review comment chat (experimental)
📜 Recent review detailsConfiguration used: .coderabbit.yaml 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (3)
🔇 Additional comments (7)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this 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
🧹 Nitpick comments (2)
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonQueryTest.php (1)
10-42:❓ Verification inconclusive
Expand test cases for JSON_QUERY to cover more PostgreSQL features.
The test covers several important scenarios including array access, nested objects, filters, and ranges. However, based on PostgreSQL's JSON path query features, consider adding tests for:
- Testing with the
returningclause parameter to specify the return type- Testing with
with uniqueoption to eliminate duplicate values- Testing with wildcard descent (
**) for deeper recursive searchesprotected function getExpectedSqlStatements(): array { return [ "SELECT json_query(c0_.object1, '$.items[*]') AS sclr_0 FROM ContainsJsons c0_", "SELECT json_query(c0_.object1, '$.address') AS sclr_0 FROM ContainsJsons c0_", // Additional test cases for important scenarios "SELECT json_query(c0_.object1, '$.store.book[*].author') AS sclr_0 FROM ContainsJsons c0_", "SELECT json_query(c0_.object1, '$.store.book[0 to 2]') AS sclr_0 FROM ContainsJsons c0_", "SELECT json_query(c0_.object1, '$.store.book[*]?(@.price > 10)') AS sclr_0 FROM ContainsJsons c0_", + // Testing with returning clause + "SELECT json_query(c0_.object1, '$.store.book[*].price' RETURNING VARCHAR) AS sclr_0 FROM ContainsJsons c0_", + // Testing with 'with unique' option + "SELECT json_query(c0_.object1, '$.store.book[*].category' WITH UNIQUE) AS sclr_0 FROM ContainsJsons c0_", + // Testing with wildcard recursive descent + "SELECT json_query(c0_.object1, '$.**?(@.type == \"fiction\")') AS sclr_0 FROM ContainsJsons c0_", ]; } protected function getDqlStatements(): array { return [ \sprintf("SELECT JSON_QUERY(e.object1, '$.items[*]') FROM %s e", ContainsJsons::class), \sprintf("SELECT JSON_QUERY(e.object1, '$.address') FROM %s e", ContainsJsons::class), // Additional test cases matching the SQL statements above \sprintf("SELECT JSON_QUERY(e.object1, '$.store.book[*].author') FROM %s e", ContainsJsons::class), \sprintf("SELECT JSON_QUERY(e.object1, '$.store.book[0 to 2]') FROM %s e", ContainsJsons::class), \sprintf("SELECT JSON_QUERY(e.object1, '$.store.book[*]?(@.price > 10)') FROM %s e", ContainsJsons::class), + \sprintf("SELECT JSON_QUERY(e.object1, '$.store.book[*].price' RETURNING VARCHAR) FROM %s e", ContainsJsons::class), + \sprintf("SELECT JSON_QUERY(e.object1, '$.store.book[*].category' WITH UNIQUE) FROM %s e", ContainsJsons::class), + \sprintf("SELECT JSON_QUERY(e.object1, '$.**?(@.type == \"fiction\")') FROM %s e", ContainsJsons::class), ]; }
🌐 Web query:
PostgreSQL json_query function latest documentation and examples💡 Result:
The
JSON_QUERY()function in PostgreSQL 17 enables advanced extraction and transformation of JSON data using SQL/JSON path expressions. It provides granular control over result formatting, error handling, and output structure, making it ideal for querying nested or complex JSON structures. Below is a detailed breakdown:
Key Features and Syntax
Function Signature
JSON_QUERY( json_input JSONB, json_path TEXT [ PASSING variables ] [ RETURNING type ] [ WITHOUT WRAPPER | WITH WRAPPER | WITH CONDITIONAL WRAPPER ] [ KEEP QUOTES | OMIT QUOTES ] [ ON EMPTY action ] [ ON ERROR action ] )
json_path: Defines the path to the target JSON element using SQL/JSON syntax (e.g.,$.users.name) [1][15].- Wrapper Modes:
WITHOUT WRAPPER(default): Returns unwrapped values, errors if multiple results exist.WITH UNCONDITIONAL WRAPPER: Always wraps results in an array.WITH CONDITIONAL WRAPPER: Wraps results only when multiple values exist [1][15].- Quote Handling:
KEEP QUOTES(default): Preserves quotes for scalar strings.OMIT QUOTES: Removes quotes (only applicable to scalar strings without wrappers) [1][4].
Common Use Cases
1. Extracting Nested Objects
-- Extract the first employee's address object SELECT JSON_QUERY( '{"employees": [{"name": "Alice", "address": {"city": "Paris"}}]}', '$.employees[0].address' ); -- Returns: {"city": "Paris"} [1][5]2. Handling Arrays with Wrappers
-- Extract all tags, wrapping results conditionally SELECT JSON_QUERY( '{"user": {"tags": ["admin", "editor"]}}', '$.user.tags[*]' WITH CONDITIONAL WRAPPER ); -- Returns: ["admin", "editor"] [1][4]3. Error Handling
-- Return NULL if the path doesn’t exist SELECT JSON_QUERY( '{"user": {"name": "Bob"}}', '$.user.age' ON EMPTY RETURN NULL ); -- Returns: NULL [1][15]
Comparison with
JSON_VALUE()
Feature JSON_QUERY()JSON_VALUE()Return Type JSON objects/arrays Scalar values (text, numbers, booleans) Path Errors Returns NULLor error (configurable)Returns NULLor error (configurable)Usage Extracting fragments Extracting single values Example:
-- JSON_QUERY returns a JSON object SELECT JSON_QUERY('{"user": {"name": "Alice"}}', '$.user'); -- Result: {"name": "Alice"} -- JSON_VALUE returns a scalar SELECT JSON_VALUE('{"user": {"name": "Alice"}}', '$.user.name'); -- Result: Alice [1][10]
Performance Tips
- Indexing: Create indexes on frequently queried JSON paths (e.g.,
CREATE INDEX idx ON table USING GIN (json_column jsonb_path_ops)) [1][17].- Path Specificity: Avoid wildcards (
[*]) where possible to optimize query speed [1][9].- Error Recovery: Use
DEFAULTclauses to handle missing paths instead of raising errors [1][15].
Advanced Examples
Dynamic Data Transformation
-- Build a JSON object from table data SELECT JSON_QUERY( jsonb_build_object('age', profile->'age', 'theme', preferences->'theme'), '$' ) AS user_settings FROM users; -- Returns: {"age": 30, "theme": "dark"} [3][8]Filtering with Path Expressions
-- Find users with "beta" preferences enabled SELECT JSON_QUERY(preferences, '$.beta') FROM users WHERE JSON_VALUE(preferences, '$.beta')::boolean = true; -- Returns: true for matching users [2][7]
JSON_QUERY()streamlines complex JSON operations by combining SQL’s relational strengths with JSON’s flexibility. For scalar extraction, useJSON_VALUE(), but for objects/arrays or advanced formatting needs,JSON_QUERY()is indispensable [1][3][15].Citations:
- 1: https://neon.tech/docs/functions/json_query
- 2: https://hevodata.com/learn/postgres-json-query/
- 3: https://www.dbi-services.com/blog/postgresql-17-enhancing-json-support-for-web-developers/
- 4: https://trino.io/docs/current/functions/json.html
- 5: https://www.sqlshack.com/the-json_query-function-to-extract-objects-from-json-data/
- 6: https://hevodata.com/learn/postgresql-json-functions/
- 7: https://popsql.com/learn-sql/postgresql/how-to-query-a-json-column-in-postgresql
- 8: https://risingwave.com/blog/mastering-json-functions-in-postgresql-the-ultimate-guide/
- 9: https://neon.tech/postgresql/postgresql-json-functions/postgresql-json-path
- 10: https://learn.microsoft.com/en-us/sql/t-sql/functions/json-query-transact-sql?view=sql-server-ver16
- 11: https://www.commandprompt.com/education/postgresql-json_agg-function-by-practical-examples/
- 12: https://docs.oracle.com/en/database/oracle/oracle-database/19/adjsn/function-JSON_QUERY.html
- 13: https://neon.tech/postgresql/postgresql-json-functions
- 14: https://docs.aws.amazon.com/dms/latest/oracle-to-aurora-postgresql-migration-playbook/chap-oracle-aurora-pg.special.json.html
- 15: https://www.postgresql.org/docs/current/functions-json.html
- 16: https://www.dbvis.com/thetable/postgresql-jsonpath/
- 17: https://www.postgresql.org/docs/current/datatype-json.html
- 18: https://www.postgresql.org/message-id/CA+HiwqGZ+X9Po05aEUOck4hW6mGx2SGtE8ddTa-76eZoyr1gFA@mail.gmail.com
- 19: https://postgrespro.com/docs/postgresql/12/functions-json
- 20: https://learn.microsoft.com/en-us/sql/relational-databases/json/validate-query-and-change-json-data-with-built-in-functions-sql-server?view=sql-server-ver16
Action Required: Expand JSON_QUERY Test Coverage for Advanced PostgreSQL Features
The current tests cover several core scenarios (array access, nested objects, filters, and ranges). However, based on PostgreSQL 17’s JSON_QUERY documentation—which introduces advanced parameters like the RETURNING clause—and to potentially support custom extensions (e.g. a unique filter and recursive descent), please expand the tests as follows:
- Add a test using the
RETURNINGclause: This verifies that specifying a return type (e.g. VARCHAR) correctly transforms the extracted JSON.- Introduce a test with a "with unique" option: Although not part of the official PostgreSQL JSON_QUERY syntax, if this clause is a custom extension in your implementation to eliminate duplicates, ensure its behavior is validated.
- Include a test for wildcard recursive descent: Use cases like searching deeply nested elements (e.g. using
$.**?(@.type == "fiction")) will help catch potential issues in recursive JSON path handling.Below is the updated diff snippet demonstrating the adjustments for both SQL and DQL statements:
protected function getExpectedSqlStatements(): array { return [ "SELECT json_query(c0_.object1, '$.items[*]') AS sclr_0 FROM ContainsJsons c0_", "SELECT json_query(c0_.object1, '$.address') AS sclr_0 FROM ContainsJsons c0_", // Additional test cases for important scenarios "SELECT json_query(c0_.object1, '$.store.book[*].author') AS sclr_0 FROM ContainsJsons c0_", "SELECT json_query(c0_.object1, '$.store.book[0 to 2]') AS sclr_0 FROM ContainsJsons c0_", "SELECT json_query(c0_.object1, '$.store.book[*]?(@.price > 10)') AS sclr_0 FROM ContainsJsons c0_", + // Testing with returning clause + "SELECT json_query(c0_.object1, '$.store.book[*].price' RETURNING VARCHAR) AS sclr_0 FROM ContainsJsons c0_", + // Testing with 'with unique' option (verify if this is a custom extension) + "SELECT json_query(c0_.object1, '$.store.book[*].category' WITH UNIQUE) AS sclr_0 FROM ContainsJsons c0_", + // Testing with wildcard recursive descent + "SELECT json_query(c0_.object1, '$.**?(@.type == \"fiction\")') AS sclr_0 FROM ContainsJsons c0_", ]; } protected function getDqlStatements(): array { return [ \sprintf("SELECT JSON_QUERY(e.object1, '$.items[*]') FROM %s e", ContainsJsons::class), \sprintf("SELECT JSON_QUERY(e.object1, '$.address') FROM %s e", ContainsJsons::class), // Additional test cases matching the SQL statements above \sprintf("SELECT JSON_QUERY(e.object1, '$.store.book[*].author') FROM %s e", ContainsJsons::class), \sprintf("SELECT JSON_QUERY(e.object1, '$.store.book[0 to 2]') FROM %s e", ContainsJsons::class), \sprintf("SELECT JSON_QUERY(e.object1, '$.store.book[*]?(@.price > 10)') FROM %s e", ContainsJsons::class), + \sprintf("SELECT JSON_QUERY(e.object1, '$.store.book[*].price' RETURNING VARCHAR) FROM %s e", ContainsJsons::class), + \sprintf("SELECT JSON_QUERY(e.object1, '$.store.book[*].category' WITH UNIQUE) FROM %s e", ContainsJsons::class), + \sprintf("SELECT JSON_QUERY(e.object1, '$.**?(@.type == \"fiction\")') FROM %s e", ContainsJsons::class), ]; }Please review these additions carefully—including verifying that the "WITH UNIQUE" option is intentionally supported—and adjust the implementation if needed.
docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md (1)
1-104: Overall Documentation Consistency and Enhancement Note
The updates integrating new JSON functions are well-incorporated into the available functions table. For further clarity, consider adding short usage examples or cross-references to integration guides where these functions are demonstrated in DQL queries.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md(1 hunks)docs/INTEGRATING-WITH-DOCTRINE.md(1 hunks)docs/INTEGRATING-WITH-LARAVEL.md(1 hunks)docs/INTEGRATING-WITH-SYMFONY.md(1 hunks)src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonExists.php(1 hunks)src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonQuery.php(1 hunks)src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonScalar.php(1 hunks)src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonSerialize.php(1 hunks)src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonValue.php(1 hunks)tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonExistsTest.php(1 hunks)tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonQueryTest.php(1 hunks)tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonScalarTest.php(1 hunks)tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonSerializeTest.php(1 hunks)tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonValueTest.php(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/**/*....
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/JsonSerializeTest.phptests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonScalarTest.phptests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonValueTest.phptests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonQueryTest.phptests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonExistsTest.php
🧠 Learnings (1)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonExists.php (1)
Learnt from: martin-georgiev
PR: martin-georgiev/postgresql-for-doctrine#0
File: :0-0
Timestamp: 2025-03-12T13:01:51.371Z
Learning: The PostgreSQL-for-doctrine library implements the JSON array element existence check using the `RIGHT_EXISTS_ON_LEFT` DQL function, which maps to PostgreSQL's `?` operator. This is used for checking if a specific value exists in a JSONB array column.
🔇 Additional comments (13)
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonScalar.php (1)
1-22: Implementation looks correct and well-documentedThe
JsonScalarclass properly implements the PostgreSQL JSON_SCALAR function. The code follows the same pattern as other function implementations in this library with appropriate documentation including PostgreSQL reference link.The implementation sets the function prototype correctly to match PostgreSQL's syntax and maps a single
StringPrimaryparameter which is appropriate for this function.src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonSerialize.php (1)
1-25: Implementation looks correct with clear documentationThe
JsonSerializeclass correctly implements the PostgreSQL JSON_SERIALIZE function. The class follows the consistent pattern of other function implementations in this library.The documentation is thorough, including:
- Basic function form example
- Link to PostgreSQL documentation
- Version number
- Author information
The implementation sets the correct function prototype and parameter mapping.
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonExists.php (1)
1-23: Implementation matches PostgreSQL's JSON_EXISTS functionThe
JsonExistsimplementation looks correct, mapping to PostgreSQL'sjson_exists(%s, %s)function with two string parameters. The class follows the same pattern as other function implementations in this library.I note that this new function complements the existing JSON array element existence check functionality mentioned in the retrieved learning (which uses the
?operator).src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonQuery.php (1)
1-23: Implementation correctly matches PostgreSQL's JSON_QUERY functionThe
JsonQueryclass properly implements the PostgreSQL JSON_QUERY function. The implementation follows the consistent pattern used throughout the library and sets the correct function prototype with two string parameters.Documentation is complete with appropriate PostgreSQL reference link.
src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonValue.php (1)
1-23: Implementation matches PostgreSQL's JSON_VALUE function.The class implementation correctly defines the JSON_VALUE function with appropriate parameter mapping. The function prototype and node mappings match PostgreSQL's JSON_VALUE signature, which takes a JSON expression and a path expression as parameters.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonScalarTest.php (1)
19-30:❓ Verification inconclusive
Test coverage should be expanded for JSON_SCALAR function.
The current test case only covers the basic scenario of using JSON_SCALAR on a JSON object. Based on PostgreSQL documentation, this test should be expanded to include:
- Tests with different types of JSON scalars (numbers, strings, booleans, null)
- Tests with non-scalar values (arrays, objects) to verify error handling
- Tests with NULL JSON inputs
For example:
protected function getExpectedSqlStatements(): array { return [ 'SELECT json_scalar(c0_.object1) AS sclr_0 FROM ContainsJsons c0_', + // Test with JSON literal containing different scalar types + "SELECT json_scalar('\"string value\"') AS sclr_0 FROM ContainsJsons c0_", + "SELECT json_scalar('42') AS sclr_0 FROM ContainsJsons c0_", + "SELECT json_scalar('true') AS sclr_0 FROM ContainsJsons c0_", + "SELECT json_scalar('null') AS sclr_0 FROM ContainsJsons c0_", ]; }With corresponding additions to the getDqlStatements method.
🌐 Web query:
PostgreSQL json_scalar function examples and usage💡 Result:
PostgreSQL doesn't have a dedicated
json_scalarfunction, but provides equivalent functionality through operators and specialized functions for JSON value extraction. Here are the key methods for working with scalar values in JSON/JSONB data:1. Scalar Extraction Operators
These operators retrieve values as basic PostgreSQL types:
->>(Get Text Value)
Extracts values asTEXTfrom JSON objects/arrays:SELECT info->>'age' AS age_text FROM users; -- Returns "25" (text) for {"age": 25}
->(Get JSON Value)
Returns values as JSON type for nested operations:SELECT info->'address'->>'city' AS city FROM users; -- Returns "Paris" (text) from {"address": {"city": "Paris"}}2. Specialized Scalar Functions
For complex path navigation:
jsonb_extract_path_text()
Extracts nested values via path components:SELECT jsonb_extract_path_text( '{"a":{"b":{"c":42}}}'::jsonb, 'a', 'b', 'c' ); -- Returns "42" (text)
jsonb_path_query_first()
Uses JSONPath expressions for precise extraction:SELECT jsonb_path_query_first( '{"scores": [85,92,78]}', '$.scores[0]' ); -- Returns 85 (JSONB number)3. Type Conversion Patterns
Cast extracted values directly to SQL types:
SELECT (info->'price')::numeric * 1.1 AS taxed_price FROM products; -- Converts JSON number to PostgreSQL numericCommon Use Cases
Filtering with Scalar Values
SELECT * FROM orders WHERE (metadata->>'priority')::int > 5;Aggregate Calculations
SELECT AVG((stats->>'visits')::int) FROM website_analytics;Nested Value Updates
UPDATE user_profiles SET preferences = jsonb_set( preferences, '{notification_frequency}', '"daily"' ) WHERE id = 123;For JSON arrays, use
jsonb_array_elements_text()to unpack scalar values:SELECT value::date FROM jsonb_array_elements_text( '["2024-01-01", "2024-02-01"]' );Key differences in JSON handling:
Operation JSON Type JSONB Type Storage Exact input copy Binary decomposition Indexing Limited GIN/GIST indexes Duplicate Keys Preserved Last-write wins Scalar Extraction Requires casting Automatic type inference These methods provide comprehensive scalar value handling without needing a dedicated
json_scalarfunction[2][4][5]. For JSONPath syntax and advanced queries, refer to PostgreSQL'sjsonpathdocumentation[2][6].Citations:
- 1: https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions
- 2: https://www.postgresql.org/docs/current/datatype-json.html
- 3: https://www.postgresql.org/docs/9.5/functions-json.html
- 4: https://neon.tech/postgresql/postgresql-tutorial/postgresql-json
- 5: https://neon.tech/postgresql/postgresql-json-functions
- 6: https://risingwave.com/blog/mastering-json-functions-in-postgresql-the-ultimate-guide/
- 7: https://tembo.io/docs/getting-started/postgres_guides/working-with-json-data-in-postgres/
Expand JSON_SCALAR test cases for comprehensive input coverage.
The current test in
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonScalarTest.phponly covers the basic scenario of applyingJSON_SCALARto a JSON object property. However, even though PostgreSQL doesn’t include a dedicatedjson_scalarfunction (it achieves similar functionality using operators and other functions), the custom Doctrine implementation should be thoroughly validated.Please consider adding tests that cover:
- Different JSON scalar types (e.g., strings, numbers, booleans, and null values)
- Non-scalar inputs (arrays or objects) to verify that errors or unexpected behaviors are handled appropriately
- NULL JSON inputs
- Additional expressions, such as using literal values
For example, you might update the expected SQL statements as follows:
protected function getExpectedSqlStatements(): array { return [ 'SELECT json_scalar(c0_.object1) AS sclr_0 FROM ContainsJsons c0_', + // Test cases for varying inputs: + "SELECT json_scalar('\"string value\"') AS sclr_0 FROM ContainsJsons c0_", + "SELECT json_scalar('42') AS sclr_0 FROM ContainsJsons c0_", + "SELECT json_scalar('true') AS sclr_0 FROM ContainsJsons c0_", + "SELECT json_scalar('null') AS sclr_0 FROM ContainsJsons c0_", ]; }Make sure to add corresponding enhancements to the DQL statements in the
getDqlStatements()method. This will ensure the Doctrine implementation handles various JSON scalar scenarios as expected.docs/INTEGRATING-WITH-SYMFONY.md (1)
107-107: LGTM: JSON function integration looks good.The added JSON functions (
JSON_EXISTS,JSON_QUERY,JSON_SCALAR,JSON_SERIALIZE,JSON_TYPEOF, andJSON_VALUE) are properly integrated into the Symfony configuration file in the "json specific functions" section. This matches the PR objective of adding support for these functions.Also applies to: 115-117, 119-120
docs/INTEGRATING-WITH-LARAVEL.md (1)
114-114: LGTM: JSON function registration is properly configured.The added JSON functions (
JSON_EXISTS,JSON_QUERY,JSON_SCALAR,JSON_SERIALIZE, andJSON_VALUE) are correctly integrated into the Laravel configuration file. The formatting and organization match the existing pattern in the file.Also applies to: 122-124, 126-126
docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md (3)
56-56: Confirm New Entry: JSON_EXISTS
The addition of thejson_existsrow—with its DQL registration asJSON_EXISTSand implementation classMartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonExists—is consistent with the naming and formatting conventions used in the table.
59-61: Add New JSON Functions: JSON_QUERY, JSON_SCALAR, and JSON_SERIALIZE
These three new entries are added in a contiguous block and follow the established pattern. Ensure that the implementations in their respective classes (JsonQuery,JsonScalar,JsonSerialize) match the expected behavior when queried through DQL.
64-64: Verify New Function: JSON_VALUE
Thejson_valuefunction appears with its corresponding DQL aliasJSON_VALUEand implementation class. Confirm that its functionality is in line with the other JSON operations and that any usage examples in your test suite/documentation cover its intended semantics.docs/INTEGRATING-WITH-DOCTRINE.md (2)
36-55: Registering New JSON Functions in Doctrine Configuration
The JSON functions—includingJSON_EXISTS,JSON_QUERY,JSON_SCALAR,JSON_SERIALIZE, andJSON_VALUE—are now registered along with the other JSON functions in the Doctrine configuration. This registration is clear and follows the established pattern. Please ensure that each corresponding implementation class has adequate tests to cover edge cases.
28-77: Overall Integration Configuration Check
The integration setup displayed in this PHP code block is well-organized. The registration of custom string functions (both existing and new) is consistent with the documented pattern. Just verify that similar JSON function registrations are updated in the integration guides for Laravel and Symfony to maintain consistency across the board.
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonSerializeTest.php
Show resolved
Hide resolved
tests/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/JsonExistsTest.php
Show resolved
Hide resolved
json_exists, json_query, json_scalar, json_serialize and json_valuejson_exists, json_query, json_scalar, json_serialize and json_value
json_exists, json_query, json_scalar, json_serialize and json_valuejson_exists, json_query, json_scalar, json_serialize and json_value
Summary by CodeRabbit
JSON_EXISTS,JSON_QUERY,JSON_SCALAR,JSON_SERIALIZE, andJSON_VALUE.JsonExists,JsonQuery,JsonScalar,JsonSerialize, andJsonValue.