Skip to content

Commit

Permalink
Alternate fix to delete queries with aliases.
Browse files Browse the repository at this point in the history
I goofed on the last set of changes and mainlined a MySQLism. Since we
don't support joins in delete queries, and database vendors either don't
support aliases in delete queries (sqlite) or support them in different
ways (mysql, postgres, sqlserver) it is simpler to manipulate queries
before they are rendered removing table and condition aliases.
  • Loading branch information
markstory committed Aug 11, 2014
1 parent 4413c8d commit d1ec92f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 25 deletions.
25 changes: 1 addition & 24 deletions src/Database/QueryCompiler.php
Expand Up @@ -32,6 +32,7 @@ class QueryCompiler {
* @var array
*/
protected $_templates = [
'delete' => 'DELETE',
'update' => 'UPDATE %s',
'where' => ' WHERE %s',
'group' => ' GROUP BY %s ',
Expand Down Expand Up @@ -158,30 +159,6 @@ protected function _buildSelectPart($parts, $query, $generator) {
return sprintf($select, $modifiers, $distinct, implode(', ', $normalized));
}

/**
* Helper function used to build the string representation of a DELETE clause.
*
* If the table is aliased, a `DELETE x` fragment will be returned
*
* @param array $parts list of tables to be transformed to string
* @param \Cake\Database\Query $query The query that is being compiled
* @param \Cake\Database\ValueBinder $generator the placeholder generator to be used in expressions
* @return string
*/
protected function _buildDeletePart($parts, $query, $generator) {
$delete = 'DELETE';
$aliases = [];
foreach ($query->clause('from') as $k => $v) {
if (is_string($k)) {
$aliases[] = $k;
}
}
if (!empty($aliases)) {
$delete = trim($delete . ' ' . implode(',', $aliases));
}
return $delete;
}

/**
* Helper function used to build the string representation of a FROM clause,
* it constructs the tables list taking care of aliasing and
Expand Down
40 changes: 39 additions & 1 deletion src/Database/SqlDialectTrait.php
Expand Up @@ -14,6 +14,8 @@
*/
namespace Cake\Database;

use Cake\Database\Expression\Comparison;

/**
* Sql dialect trait
*/
Expand Down Expand Up @@ -129,14 +131,50 @@ protected function _transformDistinct($query) {
}
return $query;
}

/**
*
* Apply translation steps to delete queries.
*
* Chops out aliases on delete query conditions as most database dialects do not
* support aliases in delete queries. This also removes aliases
* in table names as they frequently don't work either.
*
* We are intentionally not supporting deletes with joins as they have even poorer support.
*
* @param Query $query The query to translate
* @return Query The modified query
*/
protected function _deleteQueryTranslator($query) {
$hadAlias = false;
$tables = [];
foreach ($query->clause('from') as $alias => $table) {
if (is_string($alias)) {
$hadAlias = true;
}
$tables[] = $table;
}
if ($hadAlias) {
$query->from($tables, true);
}

if (!$hadAlias) {
return $query;
}
$conditions = $query->clause('where');
if ($conditions) {
$conditions->iterateParts(function($condition, $key) {
if (!($condition instanceof Comparison)) {
return $condition;
}
$field = $condition->getField();
if (strpos($field, '.') !== false) {
list(, $field) = explode('.', $field);
$condition->field($field);
}
return $condition;
});
}

return $query;
}

Expand Down

0 comments on commit d1ec92f

Please sign in to comment.