Ticket #950 (closed defect: fixed)

Opened 15 months ago

Last modified 10 months ago

Auto Create INDEX on FOREIGN KEY REFERENCE on MySQL (exportClasses)

Reported by: cferry Owned by: jwage
Priority: minor Milestone:
Component: Attributes Version: 0.11.0
Severity: Keywords:
Cc: Has Test: no
Status: Pending Core Response Has Patch: no

Description

Hi!
I found a little bug in exportClasses method.
In fact, when i create a FOREIGN KEY using :

$this->hasOne('CountryRecord as Country', array('local' => 'pays', 'foreign' => 'iso'));

I get the following message :

SQLSTATE[HY000]: General error: 1005 Can't create table './mydatabase/#sql-c5f_b0.frm' (errno: 150). 

because MySQL need an INDEX on FOREIGN KEY REFERENCE (iso field)
if I add $this->index('iso', array('fields' => 'iso')); in CountryRecord.

The problem is solved.
I think the best way is exportClasses auto add an index on foreign key reference to prevent this error.

Thank you in advance
regards

Cédric FERRY
www.emisfr.com

Change History

Changed 15 months ago by jwage

  • status changed from new to closed
  • resolution set to invalid

Doctrine already export indexes on foreign keys, I think something else is going on here. Are the columns pays and iso of the same type and length? You would get that error too if they are not of the same type and length.

Changed 15 months ago by cferry

  • status changed from closed to reopened
  • resolution invalid deleted

Hi,
iso and pays have same type : string length 2.
Maybe, string is the problem ? I know a better way is using integer. but in this case, I need string.

I reopen the ticket because, iso and pays have the same type.

Regards

Cédric

Changed 15 months ago by jwage

I am unable to produce the issue you are describing, and this is scenario is common and covered by tests. Can you provide some more information or create a failing test case in Doctrine.

Changed 15 months ago by cferry

There is the classes declarations :

class AdresseRecord extends Doctrine_Record
{

	public function setTableDefinition()
	{
		$this->setTableName('adresse_record');
		$this->hasColumn('id', 'integer', 20, array('notnull' => true,
                                              'primary' => true,
                                              'autoincrement' => true));

		$this->hasColumn('adresse', 'string', 255);
		$this->hasColumn('cp', 'string', 60);
		$this->hasColumn('ville', 'string', 255);
		$this->hasColumn('pays', 'string', 2 ); // <----------------------------
		//$this->index('pays', array('fields' => 'pays'));
	}

	public function setUp()
	{
		parent::setUp();
		$this->hasOne('CountryRecord as Country', array('local' => 'pays', 'foreign' => 'iso'));
	}

}


class CountryRecord extends Doctrine_Record
{

	public function setTableDefinition()
	{
		$this->setTableName('country_record');
		$this->hasColumn('id', 'integer', 11, array('notnull' => true,
                                              'primary' => true,
                                              'autoincrement' => true));

		$this->hasColumn('iso', 'string', 2, array('notnull' => true)); // <--------------------------

		$this->hasColumn('name', 'string', 80);
		$this->hasColumn('printable_name', 'string', 80);
		$this->hasColumn('iso3', 'string', 3);
		$this->hasColumn('numcode', 'integer', 10);
		$this->index('iso', array('fields' => 'iso')); // <- need this else I get the error.
	}

	public function setUp()
	{
		parent::setUp();
	}
}


// Use the classes to build table in database


$manager = Doctrine_Manager::getInstance();
$conn    = $manager->openConnection('mysql://user:pass@localhost/test');


$conn->export->exportClasses(array('AdresseRecord','CountryRecord'));



I'm sorry I've no time to write test case, maybe later. Hope that will help you.

Regards

Cédric

Changed 15 months ago by jwage

  • status changed from reopened to closed
  • resolution set to invalid

Added coverage in r4291

You will see everything is passing. The correct sql is produced, and I tested executing it against mysql 5.0.45 and it executes correctly. I am not sure what is going on :( Can you check what mysql version you have?

Changed 15 months ago by cferry

My MySQL version : 5.0.51a
Your text case seems to be not correct.
Please delete the line 88 ($this->index('iso', array('fields' => 'iso'));) and test it again.
Without this line I got an error. I think this index must be create automatically. It was my request.
(I leave it closed, but reopen it if test fail).

Thanks & Regards

Cédric

Changed 15 months ago by jwage

I see now. Why is iso not a primary key of the country record? Your database design is flawed as it is currently, which is why it does not fit in to Doctrine very easily. Your address record has one country record, but the iso column on country record is not primary or unique or anything, which is a big flaw. Is this an existing database?

Changed 15 months ago by cferry

I know is not the better way. But i need use it like this for the moment.
For sure the better way is to use id (primary key). The database works very well.
I think you will keep the ticket closed and don't resolve this problem due to the flaw.

Changed 15 months ago by jwage

  • status changed from closed to reopened
  • resolution invalid deleted

Right now it will automatically create the index for the local key, but not the foreign, because it assumes the foreign will be a primary key on the relation model. I will re-open this and see if we can change it to auto create the index if the foreign key is not primary.

Changed 14 months ago by jwage

  • status changed from reopened to closed
  • resolution set to wontfix

Changed 12 months ago by jwage

  • status changed from closed to reopened
  • has_test unset
  • version changed from 0.10 to 0.11
  • mystatus set to Pending Core Response
  • milestone changed from 0.11.0 to 0.11.1
  • has_patch unset
  • resolution wontfix deleted

This issue is that you're relationship is not

Changed 12 months ago by jwage

  • status changed from reopened to closed
  • resolution set to fixed

(In [4586]) fixes #950

Changed 10 months ago by anonymous

  • milestone New deleted

Milestone New deleted

Note: See TracTickets for help on using tickets.