<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 4.0.3
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Database;
use Cake\Database\Expression\FunctionExpression;
/**
* Responsible for compiling a Query object into its SQL representation
* for Postgres
*
* @internal
*/
class PostgresCompiler extends QueryCompiler
{
/**
* Always quote aliases in SELECT clause.
*
* Postgres auto converts unquoted identifiers to lower case.
*
* @var bool
*/
protected $_quotedSelectAliases = true;
/**
* @inheritDoc
*/
protected $_templates = [
'delete' => 'DELETE',
'where' => ' WHERE %s',
'group' => ' GROUP BY %s',
'order' => ' %s',
'limit' => ' LIMIT %s',
'offset' => ' OFFSET %s',
'epilog' => ' %s',
];
/**
* Helper function used to build the string representation of a HAVING clause,
* it constructs the field list taking care of aliasing and
* converting expression objects to string.
*
* @param array $parts list of fields to be transformed to string
* @param \Cake\Database\Query $query The query that is being compiled
* @param \Cake\Database\ValueBinder $binder Value binder used to generate parameter placeholder
* @return string
*/
protected function _buildHavingPart($parts, $query, $binder)
{
$selectParts = $query->clause('select');
foreach ($selectParts as $selectKey => $selectPart) {
if (!$selectPart instanceof FunctionExpression) {
continue;
}
foreach ($parts as $k => $p) {
if (!is_string($p)) {
continue;
}
preg_match_all(
'/\b' . trim($selectKey, '"') . '\b/i',
$p,
$matches
);
if (empty($matches[0])) {
continue;
}
$parts[$k] = preg_replace(
['/"/', '/\b' . trim($selectKey, '"') . '\b/i'],
['', $selectPart->sql($binder)],
$p
);
}
}
return sprintf(' HAVING %s', implode(', ', $parts));
}
}