- Updated copyright headers in 3,055 core application files - Changed 'Copyright (C) 2014-2025' to 'Copyright (C) 2014-2026' - Added 123 new files from EspoCRM core updates - Removed 4 deprecated files - Total changes: 61,637 insertions, 54,283 deletions This is a routine maintenance update for the new year 2026.
821 lines
24 KiB
PHP
821 lines
24 KiB
PHP
<?php
|
||
/************************************************************************
|
||
* This file is part of EspoCRM.
|
||
*
|
||
* EspoCRM – Open Source CRM application.
|
||
* Copyright (C) 2014-2026 EspoCRM, Inc.
|
||
* Website: https://www.espocrm.com
|
||
*
|
||
* This program is free software: you can redistribute it and/or modify
|
||
* it under the terms of the GNU Affero General Public License as published by
|
||
* the Free Software Foundation, either version 3 of the License, or
|
||
* (at your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful,
|
||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
* GNU Affero General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU Affero General Public License
|
||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
*
|
||
* The interactive user interfaces in modified source and object code versions
|
||
* of this program must display Appropriate Legal Notices, as required under
|
||
* Section 5 of the GNU Affero General Public License version 3.
|
||
*
|
||
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
|
||
************************************************************************/
|
||
|
||
namespace Espo\ORM\Query\Part;
|
||
|
||
use Espo\ORM\Query\Part\Expression\Util;
|
||
|
||
use RuntimeException;
|
||
|
||
/**
|
||
* A complex expression. Can be a function or a simple column reference. Immutable.
|
||
*/
|
||
class Expression implements WhereItem
|
||
{
|
||
private string $expression;
|
||
|
||
public function __construct(string $expression)
|
||
{
|
||
if ($expression === '') {
|
||
throw new RuntimeException("Expression can't be empty.");
|
||
}
|
||
|
||
if (str_ends_with($expression, ':')) {
|
||
throw new RuntimeException("Expression should not end with `:`.");
|
||
}
|
||
|
||
$this->expression = $expression;
|
||
}
|
||
|
||
public function getRaw(): array
|
||
{
|
||
return [$this->getRawKey() => null];
|
||
}
|
||
|
||
public function getRawKey(): string
|
||
{
|
||
return $this->expression . ':';
|
||
}
|
||
|
||
public function getRawValue(): mixed
|
||
{
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* Get a string expression.
|
||
*/
|
||
public function getValue(): string
|
||
{
|
||
return $this->expression;
|
||
}
|
||
|
||
/**
|
||
* Create an expression from a string.
|
||
*/
|
||
public static function create(string $expression): self
|
||
{
|
||
return new self($expression);
|
||
}
|
||
|
||
/**
|
||
* Create an expression from a scalar value or NULL.
|
||
*
|
||
* @param string|float|int|bool|null $value A scalar or NULL.
|
||
*/
|
||
public static function value(string|float|int|bool|null $value): self
|
||
{
|
||
return self::create(self::stringifyArgument($value));
|
||
}
|
||
|
||
/**
|
||
* Create a column reference expression.
|
||
*
|
||
* @param string $expression Examples: `columnName`, `alias.columnName`.
|
||
*/
|
||
public static function column(string $expression): self
|
||
{
|
||
$string = $expression;
|
||
|
||
if (strlen($string) && $string[0] === '@') {
|
||
$string = substr($string, 1);
|
||
}
|
||
|
||
if ($string === '') {
|
||
throw new RuntimeException("Empty column.");
|
||
}
|
||
|
||
if (!preg_match('/^[a-zA-Z\d.]+$/', $string)) {
|
||
throw new RuntimeException("Bad column. Must be of letters, digits. Can have a dot.");
|
||
}
|
||
|
||
return self::create($expression);
|
||
}
|
||
|
||
/**
|
||
* Create an alias reference expression.
|
||
*
|
||
* @param string $expression Examples: `someAlias`, `subQueryAlias.someAlias`.
|
||
* @since 8.1.0
|
||
*/
|
||
public static function alias(string $expression): self
|
||
{
|
||
if ($expression === '') {
|
||
throw new RuntimeException("Empty alias.");
|
||
}
|
||
|
||
if (!preg_match('/^[a-zA-Z\d.]+$/', $expression)) {
|
||
throw new RuntimeException("Bad alias expression. Must be of letters, digits. Can have a dot.");
|
||
}
|
||
|
||
if (str_contains($expression, '.')) {
|
||
[$left, $right] = explode('.', $expression, 2);
|
||
|
||
return self::create($left . '.#' . $right);
|
||
}
|
||
|
||
return self::create('#' . $expression);
|
||
}
|
||
|
||
/**
|
||
* 'COUNT' function.
|
||
*
|
||
* @param Expression $expression
|
||
*/
|
||
public static function count(Expression $expression): self
|
||
{
|
||
return self::composeFunction('COUNT', $expression);
|
||
}
|
||
|
||
/**
|
||
* 'MIN' function.
|
||
*
|
||
* @param Expression $expression
|
||
*/
|
||
public static function min(Expression $expression): self
|
||
{
|
||
return self::composeFunction('MIN', $expression);
|
||
}
|
||
|
||
/**
|
||
* 'MAX' function.
|
||
*
|
||
* @param Expression $expression
|
||
*/
|
||
public static function max(Expression $expression): self
|
||
{
|
||
return self::composeFunction('MAX', $expression);
|
||
}
|
||
|
||
/**
|
||
* 'SUM' function.
|
||
*
|
||
* @param Expression $expression
|
||
*/
|
||
public static function sum(Expression $expression): self
|
||
{
|
||
return self::composeFunction('SUM', $expression);
|
||
}
|
||
|
||
/**
|
||
* 'AVG' function.
|
||
*
|
||
* @param Expression $expression
|
||
*/
|
||
public static function average(Expression $expression): self
|
||
{
|
||
return self::composeFunction('AVG', $expression);
|
||
}
|
||
|
||
/**
|
||
* 'IF' function. Return $then if a condition is true, $else otherwise.
|
||
*
|
||
* @param Expression $condition A condition.
|
||
* @param Expression|string|int|float|bool|null $then Then.
|
||
* @param Expression|string|int|float|bool|null $else Else.
|
||
*/
|
||
public static function if(
|
||
Expression $condition,
|
||
Expression|string|int|float|bool|null $then,
|
||
Expression|string|int|float|bool|null $else
|
||
): self {
|
||
|
||
return self::composeFunction('IF', $condition, $then, $else);
|
||
}
|
||
|
||
/**
|
||
* 'CASE' expression. Even arguments define 'WHEN' conditions, following odd arguments
|
||
* define 'THEN' values. The last unmatched argument defines the 'ELSE' value.
|
||
*
|
||
* @param Expression|scalar|null ...$arguments Arguments.
|
||
*/
|
||
public static function switch(Expression|string|int|float|bool|null ...$arguments): self
|
||
{
|
||
if (count($arguments) < 2) {
|
||
throw new RuntimeException("Too few arguments.");
|
||
}
|
||
|
||
return self::composeFunction('SWITCH', ...$arguments);
|
||
}
|
||
|
||
/**
|
||
* 'CASE' expression that maps keys to values. The first argument is the value to map.
|
||
* Odd arguments define keys, the following even arguments define mapped values.
|
||
* The last unmatched argument defines the 'ELSE' value.
|
||
*
|
||
* @param Expression|scalar|null ...$arguments Arguments.
|
||
*/
|
||
public static function map(Expression|string|int|float|bool|null ...$arguments): self
|
||
{
|
||
if (count($arguments) < 3) {
|
||
throw new RuntimeException("Too few arguments.");
|
||
}
|
||
|
||
return self::composeFunction('MAP', ...$arguments);
|
||
}
|
||
|
||
/**
|
||
* 'IFNULL' function. If the first argument is not NULL, returns it,
|
||
* otherwise returns the second argument.
|
||
*
|
||
* @param Expression $value A value.
|
||
* @param Expression|string|int|float|bool $fallbackValue A fallback value.
|
||
*/
|
||
public static function ifNull(Expression $value, Expression|string|int|float|bool $fallbackValue): self
|
||
{
|
||
return self::composeFunction('IFNULL', $value, $fallbackValue);
|
||
}
|
||
|
||
/**
|
||
* 'NULLIF' function. If $arg1 = $arg2, returns NULL,
|
||
* otherwise returns the first argument.
|
||
*
|
||
* @param Expression|string|int|float|bool $argument1
|
||
* @param Expression|string|int|float|bool $argument2
|
||
*/
|
||
public static function nullIf(
|
||
Expression|string|int|float|bool $argument1,
|
||
Expression|string|int|float|bool $argument2
|
||
): self {
|
||
|
||
return self::composeFunction('NULLIF', $argument1, $argument2);
|
||
}
|
||
|
||
/**
|
||
* 'LIKE' operator.
|
||
*
|
||
* Example: `like(Expression:column('test'), 'test%'`.
|
||
*
|
||
* @param Expression $subject A subject.
|
||
* @param Expression|string $pattern A pattern.
|
||
*/
|
||
public static function like(Expression $subject, Expression|string $pattern): self
|
||
{
|
||
return self::composeFunction('LIKE', $subject, $pattern);
|
||
}
|
||
|
||
/**
|
||
* '=' operator.
|
||
*
|
||
* @param Expression|string|int|float|bool $argument1
|
||
* @param Expression|string|int|float|bool $argument2
|
||
*/
|
||
public static function equal(
|
||
Expression|string|int|float|bool $argument1,
|
||
Expression|string|int|float|bool $argument2
|
||
): self {
|
||
|
||
return self::composeFunction('EQUAL', $argument1, $argument2);
|
||
}
|
||
|
||
/**
|
||
* '<>' operator.
|
||
*
|
||
* @param Expression|string|int|float|bool $argument1
|
||
* @param Expression|string|int|float|bool $argument2
|
||
*/
|
||
public static function notEqual(
|
||
Expression|string|int|float|bool $argument1,
|
||
Expression|string|int|float|bool $argument2
|
||
): self {
|
||
|
||
return self::composeFunction('NOT_EQUAL', $argument1, $argument2);
|
||
}
|
||
|
||
/**
|
||
* '>' operator.
|
||
*
|
||
* @param Expression|string|int|float|bool $argument1
|
||
* @param Expression|string|int|float|bool $argument2
|
||
*/
|
||
public static function greater(
|
||
Expression|string|int|float|bool $argument1,
|
||
Expression|string|int|float|bool $argument2
|
||
): self {
|
||
|
||
return self::composeFunction('GREATER_THAN', $argument1, $argument2);
|
||
}
|
||
|
||
/**
|
||
* '<' operator.
|
||
*
|
||
* @param Expression|string|int|float|bool $argument1
|
||
* @param Expression|string|int|float|bool $argument2
|
||
*/
|
||
public static function less(
|
||
Expression|string|int|float|bool $argument1,
|
||
Expression|string|int|float|bool $argument2
|
||
): self {
|
||
|
||
return self::composeFunction('LESS_THAN', $argument1, $argument2);
|
||
}
|
||
|
||
/**
|
||
* '>=' operator.
|
||
*
|
||
* @param Expression|string|int|float|bool $argument1
|
||
* @param Expression|string|int|float|bool $argument2
|
||
*/
|
||
public static function greaterOrEqual(
|
||
Expression|string|int|float|bool $argument1,
|
||
Expression|string|int|float|bool $argument2
|
||
): self {
|
||
|
||
return self::composeFunction('GREATER_THAN_OR_EQUAL', $argument1, $argument2);
|
||
}
|
||
|
||
/**
|
||
* '<=' operator.
|
||
*
|
||
* @param Expression|string|int|float|bool $argument1
|
||
* @param Expression|string|int|float|bool $argument2
|
||
*/
|
||
public static function lessOrEqual(
|
||
Expression|string|int|float|bool $argument1,
|
||
Expression|string|int|float|bool $argument2
|
||
): self {
|
||
|
||
return self::composeFunction('LESS_THAN_OR_EQUAL', $argument1, $argument2);
|
||
}
|
||
|
||
/**
|
||
* 'IS NULL' operator.
|
||
*
|
||
* @param Expression $expression
|
||
*/
|
||
public static function isNull(Expression $expression): self
|
||
{
|
||
return self::composeFunction('IS_NULL', $expression);
|
||
}
|
||
|
||
/**
|
||
* 'IS NOT NULL' operator.
|
||
*
|
||
* @param Expression $expression
|
||
*/
|
||
public static function isNotNull(Expression $expression): self
|
||
{
|
||
return self::composeFunction('IS_NOT_NULL', $expression);
|
||
}
|
||
|
||
/**
|
||
* 'IN' operator. Check whether a value is within a set of values.
|
||
*
|
||
* @param Expression $expression
|
||
* @param Expression[]|string[]|int[]|float[]|bool[] $values
|
||
*/
|
||
public static function in(Expression $expression, array $values): self
|
||
{
|
||
return self::composeFunction('IN', $expression, ...$values);
|
||
}
|
||
|
||
/**
|
||
* 'NOT IN' operator. Check whether a value is not within a set of values.
|
||
*
|
||
* @param Expression $expression
|
||
* @param Expression[]|string[]|int[]|float[]|bool[] $values
|
||
*/
|
||
public static function notIn(Expression $expression, array $values): self
|
||
{
|
||
return self::composeFunction('NOT_IN', $expression, ...$values);
|
||
}
|
||
|
||
/**
|
||
* 'COALESCE' function. Returns the first non-NULL value in the list.
|
||
*/
|
||
public static function coalesce(Expression ...$expressions): self
|
||
{
|
||
return self::composeFunction('COALESCE', ...$expressions);
|
||
}
|
||
|
||
/**
|
||
* 'MONTH' function. Returns a month number of a passed date or date-time.
|
||
*
|
||
* @param Expression $date
|
||
*/
|
||
public static function month(Expression $date): self
|
||
{
|
||
return self::composeFunction('MONTH_NUMBER', $date);
|
||
}
|
||
|
||
/**
|
||
* 'WEEK' function. Returns a week number of a passed date or date-time.
|
||
*
|
||
* @param Expression $date
|
||
* @param int $weekStart A week start. `0` for Sunday, `1` for Monday.
|
||
*/
|
||
public static function week(Expression $date, int $weekStart = 0): self
|
||
{
|
||
if ($weekStart !== 0 && $weekStart !== 1) {
|
||
throw new RuntimeException("Week start can be only 0 or 1.");
|
||
}
|
||
|
||
if ($weekStart === 1) {
|
||
return self::composeFunction('WEEK_NUMBER_1', $date);
|
||
}
|
||
|
||
return self::composeFunction('WEEK_NUMBER', $date);
|
||
}
|
||
|
||
/**
|
||
* 'DAYOFWEEK' function. A day of week of a passed date or date-time. 1..7.
|
||
*
|
||
* @param Expression $date
|
||
*/
|
||
public static function dayOfWeek(Expression $date): self
|
||
{
|
||
return self::composeFunction('DAYOFWEEK', $date);
|
||
}
|
||
|
||
/**
|
||
* 'DAYOFMONTH' function. A day of month of a passed date or date-time. 1..31.
|
||
*
|
||
* @param Expression $date
|
||
*/
|
||
public static function dayOfMonth(Expression $date): self
|
||
{
|
||
return self::composeFunction('DAYOFMONTH', $date);
|
||
}
|
||
|
||
/**
|
||
* 'YEAR' function. A year number of a passed date or date-time.
|
||
*
|
||
* @param Expression $date
|
||
*/
|
||
public static function year(Expression $date): self
|
||
{
|
||
return self::composeFunction('YEAR', $date);
|
||
}
|
||
|
||
/**
|
||
* 'YEAR' function taking into account a fiscal year start.
|
||
*
|
||
* @param Expression $date
|
||
* @param int $fiscalYearStart A month number of a fiscal year start. 1..12.
|
||
*/
|
||
public static function yearFiscal(Expression $date, int $fiscalYearStart = 1): self
|
||
{
|
||
if ($fiscalYearStart < 1 || $fiscalYearStart > 12) {
|
||
throw new RuntimeException("Bad fiscal year start.");
|
||
}
|
||
|
||
return self::composeFunction('YEAR_' . strval($fiscalYearStart), $date);
|
||
}
|
||
|
||
/**
|
||
* 'QUARTER' function. A quarter number of a passed date or date-time. 1..4.
|
||
*
|
||
* @param Expression $date
|
||
*/
|
||
public static function quarter(Expression $date): self
|
||
{
|
||
return self::composeFunction('QUARTER_NUMBER', $date);
|
||
}
|
||
|
||
/**
|
||
* 'HOUR' function. A hour number of a passed date-time. 0..23.
|
||
*
|
||
* @param Expression $dateTime
|
||
*/
|
||
public static function hour(Expression $dateTime): self
|
||
{
|
||
return self::composeFunction('HOUR', $dateTime);
|
||
}
|
||
|
||
/**
|
||
* 'MINUTE' function. A minute number of a passed date-time. 0..59.
|
||
*
|
||
* @param Expression $dateTime
|
||
*/
|
||
public static function minute(Expression $dateTime): self
|
||
{
|
||
return self::composeFunction('MINUTE', $dateTime);
|
||
}
|
||
|
||
/**
|
||
* 'SECOND' function. A second number of a passed date-time. 0..59.
|
||
*
|
||
* @param Expression $dateTime
|
||
*/
|
||
public static function second(Expression $dateTime): self
|
||
{
|
||
return self::composeFunction('SECOND', $dateTime);
|
||
}
|
||
|
||
/**
|
||
* 'UNIX_TIMESTAMP' function. Seconds.
|
||
*
|
||
* @param Expression $dateTime
|
||
* @since 9.0.0
|
||
*/
|
||
public static function unixTimestamp(Expression $dateTime): self
|
||
{
|
||
return self::composeFunction('UNIX_TIMESTAMP', $dateTime);
|
||
}
|
||
|
||
/**
|
||
* 'NOW' function. A current date and time.
|
||
*/
|
||
public static function now(): self
|
||
{
|
||
return self::composeFunction('NOW');
|
||
}
|
||
|
||
/**
|
||
* 'DATE' function. Returns a date part of a date-time.
|
||
*
|
||
* @param Expression $dateTime
|
||
*/
|
||
public static function date(Expression $dateTime): self
|
||
{
|
||
return self::composeFunction('DATE', $dateTime);
|
||
}
|
||
|
||
/**
|
||
* Time zone conversion function. Converts a passed data-time applying a hour offset.
|
||
*
|
||
* @param Expression $date
|
||
*/
|
||
public static function convertTimezone(Expression $date, float $offset): self
|
||
{
|
||
return self::composeFunction('TZ', $date, $offset);
|
||
}
|
||
|
||
/**
|
||
* 'CONCAT' function. Concatenates multiple strings.
|
||
*
|
||
* @param Expression|string ...$strings Strings.
|
||
*/
|
||
public static function concat(Expression|string ...$strings): self
|
||
{
|
||
return self::composeFunction('CONCAT', ...$strings);
|
||
}
|
||
|
||
/**
|
||
* 'LEFT' function. Returns a specified number of characters from the left of a string.
|
||
*/
|
||
public static function left(Expression $string, int $offset): self
|
||
{
|
||
return self::composeFunction('LEFT', $string, $offset);
|
||
}
|
||
|
||
/**
|
||
* 'LOWER' function. Converts a string to a lower case.
|
||
*/
|
||
public static function lowerCase(Expression $string): self
|
||
{
|
||
return self::composeFunction('LOWER', $string);
|
||
}
|
||
|
||
/**
|
||
* 'UPPER' function. Converts a string to an upper case.
|
||
*/
|
||
public static function upperCase(Expression $string): self
|
||
{
|
||
return self::composeFunction('UPPER', $string);
|
||
}
|
||
|
||
/**
|
||
* 'TRIM' function. Removes leading and trailing spaces.
|
||
*/
|
||
public static function trim(Expression $string): self
|
||
{
|
||
return self::composeFunction('TRIM', $string);
|
||
}
|
||
|
||
/**
|
||
* 'BINARY' function. Converts a string value to a binary string.
|
||
*/
|
||
public static function binary(Expression $string): self
|
||
{
|
||
return self::composeFunction('BINARY', $string);
|
||
}
|
||
|
||
/**
|
||
* 'CHAR_LENGTH' function. A number of characters in a string.
|
||
*/
|
||
public static function charLength(Expression $string): self
|
||
{
|
||
return self::composeFunction('CHAR_LENGTH', $string);
|
||
}
|
||
|
||
/**
|
||
* 'REPLACE' function. Replaces all the occurrences of a sub-string within a string.
|
||
*
|
||
* @param Expression $haystack A subject.
|
||
* @param Expression|string $needle A string to be replaced.
|
||
* @param Expression|string $replaceWith A string to replace with.
|
||
*/
|
||
public static function replace(
|
||
Expression $haystack,
|
||
Expression|string $needle,
|
||
Expression|string $replaceWith
|
||
): self {
|
||
|
||
return self::composeFunction('REPLACE', $haystack, $needle, $replaceWith);
|
||
}
|
||
|
||
/**
|
||
* 'FIELD' operator (in MySQL). Returns an index (position) of an expression
|
||
* in a list. Returns `0` if not found. The first index is `1`.
|
||
*
|
||
* @param Expression $expression
|
||
* @param Expression[]|string[]|int[]|float[] $list
|
||
*/
|
||
public static function positionInList(Expression $expression, array $list): self
|
||
{
|
||
return self::composeFunction('POSITION_IN_LIST', $expression, ...$list);
|
||
}
|
||
|
||
/**
|
||
* 'ADD' function. Adds two or more numbers.
|
||
*
|
||
* @param Expression|int|float ...$arguments
|
||
*/
|
||
public static function add(Expression|int|float ...$arguments): self
|
||
{
|
||
if (count($arguments) < 2) {
|
||
throw new RuntimeException("Too few arguments.");
|
||
}
|
||
|
||
return self::composeFunction('ADD', ...$arguments);
|
||
}
|
||
|
||
/**
|
||
* 'SUB' function. Subtraction.
|
||
*
|
||
* @param Expression|int|float ...$arguments
|
||
*/
|
||
public static function subtract(Expression|int|float ...$arguments): self
|
||
{
|
||
if (count($arguments) < 2) {
|
||
throw new RuntimeException("Too few arguments.");
|
||
}
|
||
|
||
return self::composeFunction('SUB', ...$arguments);
|
||
}
|
||
|
||
/**
|
||
* 'MUL' function. Multiplication.
|
||
*
|
||
* @param Expression|int|float ...$arguments
|
||
*/
|
||
public static function multiply(Expression|int|float ...$arguments): self
|
||
{
|
||
if (count($arguments) < 2) {
|
||
throw new RuntimeException("Too few arguments.");
|
||
}
|
||
|
||
return self::composeFunction('MUL', ...$arguments);
|
||
}
|
||
|
||
/**
|
||
* 'DIV' function. Division.
|
||
*
|
||
* @param Expression|int|float ...$arguments
|
||
*/
|
||
public static function divide(Expression|int|float ...$arguments): self
|
||
{
|
||
if (count($arguments) < 2) {
|
||
throw new RuntimeException("Too few arguments.");
|
||
}
|
||
|
||
return self::composeFunction('DIV', ...$arguments);
|
||
}
|
||
|
||
/**
|
||
* 'MOD' function. Returns a remainder of a number divided by another number.
|
||
*
|
||
* @param Expression|int|float ...$arguments
|
||
*/
|
||
public static function modulo(Expression|int|float ...$arguments): self
|
||
{
|
||
if (count($arguments) < 2) {
|
||
throw new RuntimeException("Too few arguments.");
|
||
}
|
||
|
||
return self::composeFunction('MOD', ...$arguments);
|
||
}
|
||
|
||
/**
|
||
* 'FLOOR' function. The largest integer value not greater than the argument.
|
||
*/
|
||
public static function floor(Expression $number): self
|
||
{
|
||
return self::composeFunction('FLOOR', $number);
|
||
}
|
||
|
||
/**
|
||
* 'CEIL' function. The largest integer value not greater than the argument.
|
||
*/
|
||
public static function ceil(Expression $number): self
|
||
{
|
||
return self::composeFunction('CEIL', $number);
|
||
}
|
||
|
||
/**
|
||
* 'ROUND' function. Rounds a number to a specified number of decimal places.
|
||
*/
|
||
public static function round(Expression $number, int $precision = 0): self
|
||
{
|
||
return self::composeFunction('ROUND', $number, $precision);
|
||
}
|
||
|
||
/**
|
||
* 'GREATEST' function. A max value from a list of expressions.
|
||
*/
|
||
public static function greatest(Expression ...$arguments): self
|
||
{
|
||
return self::composeFunction('GREATEST', ...$arguments);
|
||
}
|
||
|
||
/**
|
||
* 'LEAST' function. A min value from a list of expressions.
|
||
*/
|
||
public static function least(Expression ...$arguments): self
|
||
{
|
||
return self::composeFunction('LEAST', ...$arguments);
|
||
}
|
||
|
||
/**
|
||
* 'ANY_VALUE' function.
|
||
*
|
||
* @since 9.1.6
|
||
*/
|
||
public function anyValue(Expression $expression): self
|
||
{
|
||
return self::composeFunction('ANY_VALUE', $expression);
|
||
}
|
||
|
||
/**
|
||
* 'AND' operator. Returns TRUE if all arguments are TRUE.
|
||
*/
|
||
public static function and(Expression ...$arguments): self
|
||
{
|
||
return self::composeFunction('AND', ...$arguments);
|
||
}
|
||
|
||
/**
|
||
* 'OR' operator. Returns TRUE if at least one argument is TRUE.
|
||
*/
|
||
public static function or(Expression ...$arguments): self
|
||
{
|
||
return self::composeFunction('OR', ...$arguments);
|
||
}
|
||
|
||
/**
|
||
* 'NOT' operator. Negates an expression.
|
||
*/
|
||
public static function not(Expression $argument): self
|
||
{
|
||
return self::composeFunction('NOT', $argument);
|
||
}
|
||
|
||
/**
|
||
* 'ROW' constructor.
|
||
*/
|
||
public static function row(Expression ...$arguments): self
|
||
{
|
||
return self::composeFunction('ROW', ...$arguments);
|
||
}
|
||
|
||
private static function composeFunction(
|
||
string $function,
|
||
Expression|bool|int|float|string|null ...$arguments
|
||
): self {
|
||
|
||
return Util::composeFunction($function, ...$arguments);
|
||
}
|
||
|
||
private static function stringifyArgument(Expression|bool|int|float|string|null $argument): string
|
||
{
|
||
return Util::stringifyArgument($argument);
|
||
}
|
||
}
|