Patch #2634

Kohana_ORM::with() does not work well when Database uses prefixes

Added by Vladimir Kolesnikov almost 2 years ago. Updated almost 2 years ago.

Status:Closed Start date:02/20/2010
Priority:Normal Due date:
Assignee:John Heathco % Done:

0%

Category:Modules:ORM
Target version:v3.0.4
Resolution:fixed Points:

Description

Say, we have two tables: users and subscriptions:

CREATE TABLE prefix_users (
    id INTEGER NOT NULL PRIMARY KEY,
    name VARCHAR(255) NOT NULL
);

CREATE TABLE prefix_subscriptions (
    id INTEGER NOT NULL PRIMARY KEY,
    user_id INTEGER UNSIGNED NOT NULL,
    some_data TEXT NOT NULL
);

A user has_many subscriptions, a subscription belongs_to one user.

We have two models describing the tables above:

class Model_User extends ORM {
    protected $_has_many = array(
        'subscriptions' => array(
            'foreign_key' => 'user_id',
            'model'       => 'Subscription',
        ),
    );
}

class Model_Subscription extends ORM {
    protected $_belongs_to = array(
        'user' => array(
            'foreign_key' => 'user_id',
            'model'       => 'User',
        ),
    );
}

Database connection configuration is as follows:

return array(
    'default' => array(
        'type'       => 'mysql',
        'connection' => array( /* Omitted for the sake of brevity */),
        'table_prefix' => 'prefix_',  // <<< This is the crucial part
    ),
);

Now, if we call something like ORM::factory('Subscription')->with('user')->find_all(); we will get an exception (I have reformatted the message for the sake of readability):

Database_Exception [ 1054 ]: Unknown column 'prefix_user.id' in 'field list' [ 
SELECT `prefix_user`.`id` AS `user:id`, `prefix_user`.`name` AS `user:name`, `prefix_subscriptions`.*
FROM `prefix_subscriptions`
LEFT JOIN `prefix_users` AS `user` ON (`prefix_user`.`id` = `prefix_subscriptions`.`user_id`)
ORDER BY `prefix_subscriptions`.`id` ASC
] ~ MODPATH/database/classes/kohana/database/mysql.php [ 183 ]

The problem is that the Database module is unaware of table aliases (thus replacing all user. with prefix_user.) and ORM module is unaware of table prefixes.

The patch that fixes the issue is attached.

orm.php.diff - Patch (1.2 kB) Vladimir Kolesnikov, 02/20/2010 04:14 am


Related issues

related to Kohana v3.x - Bug Report #2780: Database Table Prefixes aren't correctly handled when joi... v3.0.8 Closed 04/05/2010

Associated revisions

History

Updated by John Heathco almost 2 years ago

  • Target version changed from v3.0.3 to v3.0.4

Updated by Woody Gilk almost 2 years ago

  • Status changed from New to Assigned
  • Assignee set to John Heathco

Updated by John Heathco almost 2 years ago

Is this an issue with the DB or ORM? It looks like your patch involves quoting the columns - something that should be done in the DB layer...

Updated by Vladimir Kolesnikov almost 2 years ago

I am not sure this is possible at the DB layer. Quoting is necessary to stop the DB layer from adding the prefixes to table aliases.

Database layer is not aware of table aliases, ORM is not aware of table prefixes.

You get something like

DB::instance()
    ->select(/* skipped */)
    ->join(array('users', 'user'), 'LEFT')
    ->on('user.id', '=', 'subscriptions.user_id')
    ->order_by('subscriptions.id', 'ASC)

Database layer does not know if "user" in the ON clause is a table (should be prefixed) or alias (should not be prefixed).

Updated by Vladimir Kolesnikov almost 2 years ago

Quoting the tables is the only way (at least that I am aware of) to force the DB layer not to add prefixes. But if we pass something like "alias".column to the DB layer, it won't quote column part (will have `alias`.column) which can break the query if a column name matches the reserved word.

Updated by Woody Gilk almost 2 years ago

  • Target version changed from v3.0.4 to v3.0.5

Updated by John Heathco almost 2 years ago

The best solution is simply to attach the prefix to the join statement in ORM..

Updated by John Heathco almost 2 years ago

  • Status changed from Assigned to Closed
  • Target version changed from v3.0.5 to 175
  • Resolution set to fixed

Updated by Woody Gilk almost 2 years ago

  • Target version changed from 175 to v3.0.4

Also available in: Atom PDF