Add JsonPathExpression to support json path clauses#19463
Conversation
| * @param array $types Associative array of types for the expressions. | ||
| * @return $this | ||
| */ | ||
| public function passing(array $passing, array $types = []): static |
There was a problem hiding this comment.
We should silence this rule for 5.4 so that we can at least add static for new methods.
| /** | ||
| * Sets the ON EMPTY clause. | ||
| * | ||
| * @param string $behavior The behavior on empty (NULL, ERROR, or DEFAULT). |
There was a problem hiding this comment.
| * @param string $behavior The behavior on empty (NULL, ERROR, or DEFAULT). | |
| * @param self::BEHAVIOR_* $behavior The behavior on empty (NULL, ERROR, or DEFAULT). |
phpstan supports this, most likely other tools too
https://phpstan.org/writing-php-code/phpdoc-types#literals-and-constants
|
@ADmad I should extend the query tests with the full format. The jsonValue() test is in UpateQueryTest, but it's not specific to update. Should I move it to QueryTest or somewhere else? |
QueryTest would work I guess. |
| } | ||
|
|
||
| /** | ||
| * Returns a FunctionExpression representing the Json Exists |
There was a problem hiding this comment.
Should these methods include any hints about the limitations in database support?
There was a problem hiding this comment.
Sure. Most clauses are supported by engines that support the sql standard function.
I'm not sure if we should translate this to non-standard similar functions in other db engines -- maybe yes, but we'd have to deal with ignoring clauses that have a value set.
There was a problem hiding this comment.
Most clauses are supported by engines that support the sql standard function.
Ok, I took a quick look at MySQL and Postgres docs, and I was surprised to see so much alignment in the implementations.
|
There are a few CS & Stan issues, other than that this looks good to merge. |
I have an update that cleans up some types, but waiting until I have time to add a couple tests to ensure the engines parse ok. |
699618e to
e155348
Compare
| if: matrix.db-type == 'pgsql' | ||
| - name: Setup PostgreSQL 12 with PostGIS | ||
| if: matrix.db-type == 'pgsql' && matrix.php-version = '8.2' | ||
| run: docker run --rm --name=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=cakephp -p 5432:5432 -d postgis/postgis:12-3.5 |
There was a problem hiding this comment.
Why specifically postgres 12 here? According to https://endoflife.date/postgresql 12 is EOL'd since over a year.
There was a problem hiding this comment.
12.0 adds the JSONB_PATH_EXISTS() function. Since we were already transforming JSON_VALUE to JSONB_PATH_QUERY, thought it would be expected.
17.0 adds the sql standard functions we should be using.
|
| [null, 'literal'], | ||
| '', | ||
| parentheses: false, | ||
| ); |
There was a problem hiding this comment.
cake makes modifying function expressions into something else a nightmare. I'm not sure if this is worth it or not, but it's one way to support it.
There was a problem hiding this comment.
I think it is worth the effort. SQLite is a fantastic database when it is a suitable choice.
5f464fd to
71d2bbc
Compare
|
I don't know what to do about the rector failure. It wants to change the code layout while there's only one switch case. |
Well because its the A switch-case with only 1 case is basically just a if. |
I understand - it just sets a lousy code example that's different from the other drivers. |
|
I appreciate trying to keep it as consistent as possible. Alternatively we can also ignore that rector rule in our config, but I don't think that this is a big difference. |
| * @param \Cake\Database\Expression\FunctionExpression $expression The function expression to transform. | ||
| * @return void | ||
| */ | ||
| protected function _transformFunctionExpression(FunctionExpression $expression): void |
There was a problem hiding this comment.
Unless this is an overridden function we don't need the underscore prefix.
|
@ADmad How much do you dislike the |
| protected function _expressionTranslators(): array | ||
| { | ||
| return [ | ||
| FunctionExpression::class => '_transformFunctionExpression', |
There was a problem hiding this comment.
| FunctionExpression::class => '_transformFunctionExpression', | |
| FunctionExpression::class => 'transformFunctionExpression', |
| * @param \Cake\Database\Expression\FunctionExpression $expression The function expression to transform. | ||
| * @return void | ||
| */ | ||
| protected function _transformFunctionExpression(FunctionExpression $expression): void |
There was a problem hiding this comment.
| protected function _transformFunctionExpression(FunctionExpression $expression): void | |
| protected function transformFunctionExpression(FunctionExpression $expression): void |
| ->setName('JSON_CONTAINS_PATH') | ||
| ->iterateParts(function ($p, $key) { | ||
| if ($key === 1) { | ||
| return new QueryExpression(["'all'", $p], ['literal'], ',', parentheses: false); |
There was a problem hiding this comment.
Should we have a separate class for a ExpressionList style container that doesn't emit parentheses? I could see this being useful in other parts of the database drivers as well.
There was a problem hiding this comment.
It would be helpful. Hoping one of you makes the call.
There was a problem hiding this comment.
@LordSimal @ADmad Do you have any opinions on this so I can work on final update?
There was a problem hiding this comment.
I have no strong opinion about this.
There was a problem hiding this comment.
@othercorey Adding a new class as markstory suggested would be cleaner instead of adding more switches to QueryExpression.
| [null, 'literal'], | ||
| '', | ||
| parentheses: false, | ||
| ); |
There was a problem hiding this comment.
I think it is worth the effort. SQLite is a fantastic database when it is a suitable choice.
Add support for the full json path expression clauses for JSON_VALUE() and JSON_EXISTS() functions. These can be extended to support JSON_QUERY and possibly JSON_TABLE in the future.
https://www.postgresql.org/docs/current/functions-json.html#SQLJSON-QUERY-FUNCTIONS