-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
[GH-4243] more sqlite schema manager fixes #4256
[GH-4243] more sqlite schema manager fixes #4256
Conversation
9a324e1
to
f47f593
Compare
The blueprint code for the documents table is here: https://github.com/uuf6429/doc-sqlite-poc/blob/b9b5bd688342ca7d0b75addf8d54579e50a8c4d7/database/migrations/2030_09_02_3_create_documents_table.php That repo also comes with an SQLite database versioned in it. Using sqliteman to describe the documents table, I obtain the following piece of SQL: CREATE TABLE "documents" (
"hash" varchar not null,
"id" integer not null primary key autoincrement,
"created_at" datetime null,
"updated_at" datetime null,
"title" varchar not null,
"ek" varchar not null,
"iv" varchar not null,
"deleted_at" datetime null,
"type_id" integer not null,
"group_id" integer null,
foreign key("type_id") references "types"("id") on delete cascade,
foreign key("group_id") references "groups"("id") on delete cascade
) cc @uuf6429 |
11e36f0
to
010f69b
Compare
$changes++; | ||
unset($fromFkeys[$key1], $toFkeys[$key2]); | ||
} | ||
continue 2; |
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.
The continue 2;
are new, but i believe they were missing in the previous code. If the "fromKey" from the outer loop was matched to a "toKey", then we can skip to the next "fromKey", and don't need to match the current fromKey to another "toKey".
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.
This change in the code that is used by all platforms is only covered by an SQLite test. Would it be possible to rework the new test to use the DBAL APIs and run across platforms?
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.
Wouldn't applying https://github.com/doctrine/dbal/pull/4256/files#r484110298 be enough to do this? Or does "use the DBAL APIs" mean something else?
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.
@greg0ire, yes, it's exactly the same. I just reiterated because the previous comment wasn't taken into account.
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.
I tried it in #4262 , and it works only for SQLite although I used a high level API.
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.
It is fine if it only works with SQLite right now, we can mark the test incomplete for other platforms. But this way, we at least identified the inconsistency in the API (which is a bug) which will be documented in the form of an incomplete test.
AppVeyor fail is unrelated |
Not entirely, but it's definitely a step forward 👍 After that we still have to figure out the issue of implicit indexes, that fails even with this patch:
With this PR + greg0ire@68fe000 , that test passes, but that's probably not the best fix we can come up with 😅 . |
tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php
Outdated
Show resolved
Hide resolved
tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php
Outdated
Show resolved
Hide resolved
The change from greg0ire@68fe000 is a BC break. I wouldn't consider it for |
Offtopic: it fails regularly on AppVeyor due to not being able to submit code coverage to CodeCov. The question is, does it only happen on AppVeyor due to connectivity issues between AppVeyor and CodeCov (but not between GitHub and CodeCov or Travis and CodeCov) or because it's the only place where we fail the build that cannot submit code coverage. This all instability results in fluctuation of the code coverage and misleading coverage diffs. |
Me neither to be clear: it's just here to demonstrate that the issue that will be left after this is merged has to do with implicit indexes. |
0748561
to
16eab09
Compare
017ebfc
to
f5ccf9c
Compare
tests/Doctrine/Tests/DBAL/Functional/Schema/SqliteSchemaManagerTest.php
Outdated
Show resolved
Hide resolved
8f8a24a
to
0c384b4
Compare
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.
It looks like both new tests pass on 2.10.x
without the changes in lib/
.
@morozov thats bad, for the compare foreign key that is expected, because I added it as a guard for the new |
@morozov it has to be an sqlite specific test, because the schema that breaks it cannot be created with the Schema abstraction, it will always generate a constraint name. |
@beberlei I think I understand what you're saying. To make it documented, could you post the SQL that needs to be generated to fail the test (it should exist in the earlier versions of this PR) and the closest possible SQL that could be produced by the Schema API. This way, it will be clear why it's an SQLite-only scenario. |
@morozov i would rather revert to the old test with the SQL and document it, wouldn't it be better to have a working regression test for this? The test is only relevant on SQLite in anyways, because the other databases did not have this bug, because they don't have supportsCreateDropForeignKey returning false. So its not problematic that we don't cover the abstraction here, as its more a regression test for Sqlite. It seems i deprecated the necessary method on Table $referencingTable->addNamedForeignKeyConstraint(null, ...); |
@greg0ire shouldn't the SQL in https://github.com/doctrine/dbal/pull/4256/files#diff-ffff5b2690b3aab7bb35b745b6ca89b9R261 already lead to the DROP INDEX problem as well? wondering how to expand the test to get that failure as well. |
Absolutely. I just wanted it to be clarified in the discussion of this PR. So, as I understand, it can't be tested via the abstraction because it doesn't allow to create an anonymous FK for SQLite? If that's the case, then it's a clear enough explanation. Let's have it clearly stated in the PR header and possibly in the comment to the test. |
The next question (not blocking the work on the fix) is, why does DBAL force naming the object (e.g. an FK) if the underlying platform allows it to be anonymous? Even if it's to simplify the schema management, there's still a wrong assumption that such objects should be identified by name. They should be identified by value (which is implemented to some extent for indices). |
When introducing SQLite foreign key support a case was not considered where not Doctrine DBAL is creating the schema, but some other code that is not naming foreign key constraints. This leads to triggr a bug that the code already had but was never before executed.
308247d
to
523cdc0
Compare
@morozov are the Postgresql failures unrelated? https://travis-ci.org/github/doctrine/dbal/jobs/725648695 they suddenly started to pop up, 2.10.x last commit is green. |
@beberlei I've never seen these specific failures on Postgres. I restarted the job to see if they persist. UPD: the restarted job failed in the same way. It looks like the server-side errors are expected but they are not handled properly. |
Is it expected that |
Having any FK should be enough I think, the way this bug happens is DBAL wrongly supposes the index is supposed to exist because who says FK in SQLite says DBAL-implicit index, but if the table is created with Laravel blueprint that will not be the case. Maybe there should be a separate test case where we attempt the same thing that is attempted in https://github.com/uuf6429/doc-sqlite-poc/blob/master/database/migrations/2030_09_02_4_alter_documents_table.php |
Irrelevant as of #4255. |
Summary
The previous fix #4246 did not fully fix the bug, because it missed handling of
constraint_name
== NULL in a downstream function. This lead to foreign keys without name grouped together.Patch includes one regression example copied from Taylor in the original Laravel issue, but could use another one from @greg0ire example with the documents table, pending the original SQL to create it from Laravel blueprint.