I'm trying to put that query:
SELECT
*
FROM (
(SELECT * FROM table1)
UNION
(SELECT * FROM table2)
) AS t;
into \Laminas\Db\Sql\Select object. Something like this:
$select1 = new \Laminas\Db\Sql\Select($table1); // this is select for table1
$select2 = new \Laminas\Db\Sql\Select($table2); // this is select for table2
$select1->combine($select2);
So far everything looks good, and query is fine, but while I'm trying to use that query as a table, like this:
$selectUnion = new \Laminas\Db\Sql\Select();
$selectUnion->from($select1->getSqlString());
I'm getting very strange, and wrong query, result of
echo $selectUnion->getSqlString();
is:
SELECT "((SELECT * FROM table1) UNION (SELECT * FROM table2))";
which is wrong, because FROM part is missing and also " are unnecessary.
I've fixed the issue by editing \Laminas\Db\Sql\Select class from line 199:
if (! is_string($table) && ! is_array($table) && ! $table instanceof TableIdentifier) {
throw new Exception\InvalidArgumentException(
'$table must be a string, array, or an instance of TableIdentifier'
);
}
by adding possibility to object of $from can be of type Select, which is natively supported by Laminas:
if (! is_string($table) && ! is_array($table) && ! ($table instanceof TableIdentifier || $table instanceof Select)) {
throw new Exception\InvalidArgumentException(
'$table must be a string, array, or an instance of TableIdentifier or Select'
);
}
Now to build SELECT from another SELECT we have two possibilities:
$selectUnion = new \Laminas\Db\Sql\Select();
$selectUnion->from(['t' => $select1->getSqlString()]);
or
$selectUnion = new \Laminas\Db\Sql\Select();
$selectUnion->columns(['*'], false);
$selectUnion->from($select1->getSqlString());
Because our Select needs to have either alias name for subselect or disabled auto prefixation of table columns.