Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX Don't generate table alias for "from" statement that are not column names #11312

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of those would have pass previously, but addFrom didn't have explicit test coverage.

'string' => [
'MyTable', ['MyTable' => 'MyTable'],
'Plain table name get alias automatic alias'
],
'string padded with spaces' => [
GuySartorelli marked this conversation as resolved.
Show resolved Hide resolved
' 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'
);
}
}
Loading