public function testQuoteIdentifier() { if ($this->_platform->getName() == "mssql") { $this->markTestSkipped('Not working this way on mssql.'); } $c = $this->_platform->getIdentifierQuoteCharacter(); $this->assertEquals(str_repeat($c, 4), $this->_platform->quoteIdentifier($c)); }
/** * Walks down a SelectStatement AST node, wrapping it in a COUNT (SELECT DISTINCT) * * Note that the ORDER BY clause is not removed. Many SQL implementations (e.g. MySQL) * are able to cache subqueries. By keeping the ORDER BY clause intact, the limitSubQuery * that will most likely be executed next can be read from the native SQL cache. * * @param SelectStatement $AST * @return string */ public function walkSelectStatement(SelectStatement $AST) { if ($this->platform->getName() === "mssql") { $AST->orderByClause = null; } $sql = parent::walkSelectStatement($AST); // Find out the SQL alias of the identifier column of the root entity // It may be possible to make this work with multiple root entities but that // would probably require issuing multiple queries or doing a UNION SELECT // so for now, It's not supported. // Get the root entity and alias from the AST fromClause $from = $AST->fromClause->identificationVariableDeclarations; if (count($from) > 1) { throw new \RuntimeException("Cannot count query which selects two FROM components, cannot make distinction"); } $rootAlias = $from[0]->rangeVariableDeclaration->aliasIdentificationVariable; $rootClass = $this->queryComponents[$rootAlias]['metadata']; $rootIdentifier = $rootClass->identifier; // For every identifier, find out the SQL alias by combing through the ResultSetMapping $sqlIdentifier = array(); foreach ($rootIdentifier as $property) { if (isset($rootClass->fieldMappings[$property])) { foreach (array_keys($this->rsm->fieldMappings, $property) as $alias) { if ($this->rsm->columnOwnerMap[$alias] == $rootAlias) { $sqlIdentifier[$property] = $alias; } } } if (isset($rootClass->associationMappings[$property])) { $joinColumn = $rootClass->associationMappings[$property]['joinColumns'][0]['name']; foreach (array_keys($this->rsm->metaMappings, $joinColumn) as $alias) { if ($this->rsm->columnOwnerMap[$alias] == $rootAlias) { $sqlIdentifier[$property] = $alias; } } } } if (count($rootIdentifier) != count($sqlIdentifier)) { throw new \RuntimeException(sprintf('Not all identifier properties can be found in the ResultSetMapping: %s', implode(', ', array_diff($rootIdentifier, array_keys($sqlIdentifier))))); } // Build the counter query return sprintf('SELECT %s AS dctrn_count FROM (SELECT DISTINCT %s FROM (%s) dctrn_result) dctrn_table', $this->platform->getCountExpression('*'), implode(', ', $sqlIdentifier), $sql); }