Skip to content

Commit

Permalink
FIX Don't generate table alias for "from" statement that are not colu…
Browse files Browse the repository at this point in the history
…mn names.
  • Loading branch information
maxime-rainville committed Jul 29, 2024
1 parent d9bccaf commit f91b279
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/ORM/Queries/SQLConditionalExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,18 @@ public function addFrom($from)
if (is_array($from)) {
$this->from = array_merge($this->from, $from);
} elseif (!empty($from)) {
$this->from[str_replace(['"','`'], '', $from)] = $from;
// Check if the from clause looks like a regular table name
// Table name most be an uninterrupted string, with no spaces.
// It may be padded with spaces. e.g. ` TableName ` will be
// treated as Table Name, but not ` Table Name `.
if (preg_match('/^\s*[^\s]+\s*$/', $from)) {
// Add an alias for the table name, stripping any quotes
$this->from[str_replace(['"','`'], '', $from)] = $from;
} else {
// Add from clause without an alias - this is probably a full
// sub-select with its own explicit alias.
$this->from[] = $from;
}
}

return $this;
Expand Down
97 changes: 97 additions & 0 deletions tests/php/ORM/SQLSelectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1327,4 +1327,101 @@ public function testMultipleWithDuplicateName()

$select->addWith('cte', new SQLSelect());
}

public function subqueryProvider()
{
return [
'no-explicit-alias-string' => ['( SELECT DISTINCT "SQLSelectTest_DO"."ClassName" FROM "SQLSelectTest_DO") AS "FINAL"'],
'no-alias-array' => [['( SELECT DISTINCT "SQLSelectTest_DO"."ClassName" FROM "SQLSelectTest_DO") AS "FINAL"']],
'no-alias-array-numeric-key' => [[0 => '( SELECT DISTINCT "SQLSelectTest_DO"."ClassName" FROM "SQLSelectTest_DO") AS "FINAL"']],
'explicit-alias-string' => [['FINAL' => '( SELECT DISTINCT "SQLSelectTest_DO"."ClassName" FROM "SQLSelectTest_DO")']],
];
}

/**
* @dataProvider subqueryProvider
*/
public function testSubqueries($subquery)
{
$query = new SQLSelect('*', $subquery);

$actualSQL = $query->sql();

$this->assertSQLEquals(
'SELECT * FROM ( SELECT DISTINCT "SQLSelectTest_DO"."ClassName" FROM "SQLSelectTest_DO") AS "FINAL"',
$actualSQL
);
}

public function addFromProvider()
{
return [
'string' => [
'MyTable', ['MyTable' => 'MyTable'],
'Plain table name get alias automatic alias'
],
'string padded with spaces' => [
' MyTable ', [' MyTable ' => ' MyTable '],
'Plain table name get alias automatic alias'
],
'quoted string' => [
'"MyTable"', ['MyTable' => '"MyTable"'],
'Quoted table name get alias without the quotes'
],
'underscore in table name string' => [
'"My_Table_123"', ['My_Table_123' => '"My_Table_123"'],
'Numbers and underscores are allowed in table names'
],
'backtick string' => [
'`MyTable`', ['MyTable' => '`MyTable`'],
'Backtick quoted table name get alias without the quotes'
],
'subquery string' => [
' (SELECT * from "FooBar") as FooBar ', [' (SELECT * from "FooBar") as FooBar '],
'String that don\'t look like table name don\'t get alias'
],
'array' => [
['MyTable'], ['MyTable'],
'Arrays are passed through as is'
],
'array-associative-key' => [
['MyTableAlias' => 'MyTable'], ['MyTableAlias' => 'MyTable'],
'Associative arrays are passed through as is and aliases are preserved'
],
];
}

/**
* @dataProvider addFromProvider
*/
public function testAddFrom($input, $out, $message = ""): void
{
$query = new SQLSelect();
$query->addFrom($input);
$this->assertEquals($out, $query->getFrom(), $message);
}

public function testAddFromRetainPreviousData()
{
// Initial setup
$query = new SQLSelect();
$query->addFrom('MyTable');
$query->addFrom('"MyOtherTable"');

// This will override some value and add a new one
$query->addFrom([
'MyTable' => '(SELECT * FROM "MyTable" where "Foo" = "Bar")',
'ThirdTable',
]);

$this->assertEquals(
[
'MyTable' => '(SELECT * FROM "MyTable" where "Foo" = "Bar")',
'MyOtherTable' => '"MyOtherTable"',
'ThirdTable',
],
$query->getFrom(),
'MyTable entry got merge over, MyOtherTable was retained, ThirdTable was added'
);
}
}

0 comments on commit f91b279

Please sign in to comment.