Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Using TableGateway::insert() fails when table has an alias #7311

Merged
merged 1 commit into from
Mar 23, 2015

Conversation

weierophinney
Copy link
Member

I want to use a single table Users via TableGateway. I need to put an alias on a table to be able to use it in select query. I'm using a PDO driver with MySQL platform.

When you create a new TableGateway:

new \Zend\Db\TableGateway\TableGateway(array('U' => 'Users'), $adapter);

you can use this instance to select whatever you like. However, when you try to insert anything using that instance, Zend\Db\Sql\Insert tries to quote table identifier (using adapter's platform) and it fails on

Zend\Db\Adapter\Platform\Mysql:
public function quoteIdentifier($identifier)
    {
        return '`' . str_replace('`', '``', $identifier) . '`';
    }

as $identifier is an array of array('U' => 'Users') in that case.

I understand there are no table aliases in SQL insert of any flavour, still, I believe this is a bug as Zend\Db\Sql\Insert is missing something similar to what Zend\Db\Sql\Select does:

if (is_array($table)) {
   $alias = key($this->table);
   $table = current($this->table);
} 

Also, it happens with TableIdentifier as well if you add table with alias to it. As TableGateway honours table notation with alias, I'd expect to still be able to do any CRUD actions on it.

@mirfilip mirfilip changed the title Using TableGateway::insert() when table has alias fails Using TableGateway::insert() fails when table has an alias Mar 14, 2015
@weierophinney
Copy link
Member

The root cause of the issue is in Zend\Db\Sql\Insert::processInsert(), as it passes the $table property verbatim to resolveTable() instead of checking to see if the value is an array. The correct approach would be to check if the value is an array, and, if so, pass the value. I'll prepare a PR shortly.

@weierophinney weierophinney added this to the 2.4.0 milestone Mar 23, 2015
@weierophinney
Copy link
Member

I was slightly off with my analysis; processInsert() is dead code. AbstractTableGateway calls on getRawState() instead, and validates that the table received is identical to its own. Once it has, it passes the various values to Zend\Db\Sql\Sql::prepareStatementForSqlObject(). As such, the "fix" will be to reset the table value to the unaliased table after validating it.

@weierophinney
Copy link
Member

Build on my own branch passes: https://travis-ci.org/weierophinney/zf2/builds/55558431

mwillbanks added a commit that referenced this pull request Mar 23, 2015
@mwillbanks mwillbanks merged commit d54d157 into zendframework:master Mar 23, 2015
mwillbanks added a commit that referenced this pull request Mar 23, 2015
@weierophinney weierophinney deleted the hotfix/7311 branch March 24, 2015 13:27
@mirfilip
Copy link
Author

mirfilip commented Apr 7, 2015

Related issue #7430.

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

Successfully merging this pull request may close these issues.

3 participants