Skip to content
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

[5.6] Fix JSON queries with table names on SQL Server #24542

Merged
merged 1 commit into from
Jun 12, 2018
Merged

[5.6] Fix JSON queries with table names on SQL Server #24542

merged 1 commit into from
Jun 12, 2018

Conversation

staudenmeir
Copy link
Contributor

@staudenmeir staudenmeir commented Jun 10, 2018

JSON queries on SQL Server don't yet support columns with table names:

DB::table('users')->where('users.options->language', 'en')->get();
DB::table('users')->whereJsonContains('users.options->languages', 'en')->get();

Table names have been broken because JSON queries work differently on SQL Server: While MySQL and PostgreSQL use the arrow operator (column->path), SQL Server uses JSON functions.
This led to incorrect SQL: where [users].json_value([options], '$."language"') = ?.

Unfortunately, the fix requires some refactoring. We have to move the use of wrapJsonSelector() from wrapValue() up to wrap(). We could integrate it into Database\Grammar::wrap(), but I think that it rather belongs into Database\Query\Grammars\Grammar since it doesn't concern Schema grammars.

I also used the opportunity to improve the SQL Server grammar by extracting wrapJsonPath(). It's a better solution than replacing the names of JSON functions in SQL strings.

I added table name tests for all databases.

The PR is also a preparation for supporting JSON queries on MariaDB (laravel/ideas#811):
When replacing MySQL's arrow operator with the equivalent JSON_EXTRACT(), we would have run into the same wrapping problems.

@taylorotwell
Copy link
Member

taylorotwell commented Jun 10, 2018

Do you use SQL Server professionally on a daily basis?

@staudenmeir
Copy link
Contributor Author

staudenmeir commented Jun 10, 2018

I use SQL Server for one project, the rest is MySQL. So rather weekly than daily.

@taylorotwell
Copy link
Member

It looks like this changes the behavior of MySQL wrapping as well?

@staudenmeir
Copy link
Contributor Author

Do you mean the code changes in MySqlGrammar? Or that the generated SQL changes?

@taylorotwell
Copy link
Member

Well you change existing MySQL tests here:

image

@staudenmeir
Copy link
Contributor Author

I added table name tests for the other databases to catch bugs like this in the future.

@taylorotwell taylorotwell merged commit 8dd376c into laravel:5.6 Jun 12, 2018
@staudenmeir staudenmeir deleted the sql-server-json-table branch June 12, 2018 23:21
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