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

DDC-3671 prevent duplicate unique index #1375

Merged
merged 1 commit into from
Nov 7, 2015
Merged

DDC-3671 prevent duplicate unique index #1375

merged 1 commit into from
Nov 7, 2015

Conversation

michalbundyra
Copy link
Member

No description provided.

@doctrinebot
Copy link

Hello,

thank you for creating this pull request. I have automatically opened an issue
on our Jira Bug Tracker for you. See the issue link:

http://www.doctrine-project.org/jira/browse/DDC-3677

We use Jira to track the state of pull requests and the versions they got
included in.

foreach ($table->getIndexes() as $tableIndexName => $tableIndex) {
if ($tableIndex->isFullfilledBy($uniqIndex)) {
$table->dropIndex($tableIndexName);
break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the break; needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed if one fulfilled index will be found it has no sense to look for another one. Can be removed, but is it possible to have more than one fulfilled index in table before? Can you provide an example?

I was thinking to add condition to check if found index is primary, than we shouldn't add unique index, but it will be only possible when annotation is invalid - so when we have uniqueConstraint at primary column.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@webimpress nothing denies adding more than one unique constraint for the same column, so the break is probably not needed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Ocramius, yes, nothing denies adding more than one unique constraint for the same column in (DBAL) Table class (actually the commit that made it possible caused that issue), but that method creates table from metadata and adding a unique index for a table is possible when one of the conditions is met i.e.:

  1. column has annotation unique=true;
  2. column has relation OneToOne;
  3. entity has annotation uniqueConstraint.

Therefore in modified method getSchemaFromMetadata table can have at most one fulfilled index in this loop, then I can't see any reason to continue search for another one.

I can remove it, but I'm worried that it could partially cover another bug, which should be resolved in another part. If you can provide an example to write one more unit test to prove that this break causes an issue I'll be glad and all will be clear when we have one more unit test for that case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO the preference should be uniqueConstraint (explicit) > unique=true (implicit) if and only if uniqueConstraint spans ONLY the unique=true column (same behaviour as for uniqueConstraint (explicit) > foreignKey index (implicit).
Not sure about OneToOne but it should be similar I guess.

So what about simply leaving this block as it was and move it to the top of the classes loop to line 162. Then it will first add explicit unique constraints before adding implicit unique indexes from the columns gathering. gatherColumn() should then ask the table if a fullfilling unique index is already available and skip addition eventually.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@deeky666 It makes sense, but gatherColumn()1 is not the only one place where unique index can be added.
It could be also added in method gatherRelationJoinColumns()2 (for relation OneToOne).

About foreign key... It creates index key (not unique index) implicit ONLY when is needed, so when another fulfilling index doesn't exist3. Therefore when relation is OneToOne unique index is created2 and then on creating foreign key normal index is not added3.

My solution fits better, because indexes from uniqueConstraint are the most important (explicit) so always replace other (fulfilled) implicit indexes. (Even we have relation ManyToOne for a column and uniqueConstraint is defined on the column, index key created with foreign key will be replaced by unique index from uniqueConstraint - of course, in that case relation should be OneToOne and can be defined uniqueConstraint to set name for the unique index).

Finally, your proposition will be also good, but IMO more complicated, because calls 1 or 2 should be replaced by new method which will decide if unique index should be added or not.

After all, break; can be taken out but, in my loop table can have at most one fulfilled index (implicit) (added due column annotation 1 or 2).


1 Add unique index for column with annotation unique=true (method gatherColumn())
2 Add unique index for relation OneToOne (method gatherRelationJoinColumns())
3 Add index key with foreign key only when needed

@Ocramius
Copy link
Member

Ocramius commented Nov 6, 2015

@deeky666 could you give me your opinion for this? I don't see anything else required :)

@Ocramius Ocramius removed the Delayed label Nov 6, 2015
guilhermeblanco added a commit that referenced this pull request Nov 7, 2015
DDC-3671 prevent duplicate unique index
@guilhermeblanco guilhermeblanco merged commit ada97d5 into doctrine:master Nov 7, 2015
guilhermeblanco added a commit that referenced this pull request Nov 7, 2015
@Ocramius
Copy link
Member

Ocramius commented Nov 7, 2015

Backported by @guilhermeblanco into 2.5.x via 3a058f8

@guilhermeblanco
Copy link
Member

Thanks for the PR! =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants