59 'GROUP_CONCAT',
'MAX',
'MIN',
'STD',
'STDDEV_POP',
'STDDEV_SAMP',
60 'STDDEV',
'SUM',
'VAR_POP',
'VAR_SAMP',
'VARIANCE'
63 'ROWCOUNT_BIG',
'COUNT_BIG',
'STDEV',
'GROUPING',
'STDEVP',
64 'GROUPING_ID',
'SUM',
'MAX',
'VAR',
'VARP'
67 'COUNT',
'COVAR_POP',
'COVAR_SAMP',
'CUME_DIST',
'DENSE_RANK',
'FIRST',
68 'GROUP_ID',
'GROUPING',
'GROUPING_ID',
'LAST',
'MAX',
'MEDIAN',
'MIN',
69 'PERCENTILE_CONT',
'PERCENTILE_DISC',
'PERCENT_RANK',
'RANK',
70 'REGR_SLOPE',
'REGR_INTERCEPT',
'REGR_COUNT',
'REGR_R2',
'REGR_AVGX',
71 'REGR_AVGY',
'REGR_SXX',
'REGR_SYY',
'REGR_SXY',
'STATS_BINOMIAL_TEST',
72 'STATS_CROSSTAB',
'STATS_F_TEST',
'STATS_KS_TEST',
'STATS_MODE',
73 'STATS_MW_TEST',
'STATS_ONE_WAY_ANOVA',
'STATS_T_TEST_ONE',
74 'STATS_T_TEST_PAIRED',
'STATS_T_TEST_INDEP',
'STATS_T_TEST_INDEPU',
75 'STATS_WSR_TEST',
'STDDEV',
'STDDEV_POP',
'STDDEV_SAMP',
'SUM',
76 'VAR_POP',
'VAR_SAMP',
'VARIANCE'
93 if (!isset($parameters[
'data_type']))
95 $parameters[
'data_type'] =
'string';
97 $this->valueType = StringField::class;
100 parent::__construct(
$name, $parameters);
118 return call_user_func_array(array($this->valueField,
$name), $arguments);
136 $this->valueType = $class;
146 $this->valueField = $field;
147 $this->valueType = get_class($field);
163 unset($parameters[
'expression']);
165 if ($this->valueType !==
null)
167 if ($this->valueField ===
null)
170 $valueField =
new $this->valueType($this->name, $parameters);
171 $this->valueField = $this->entity->initializeField($this->name,
$valueField);
177 $this->valueField = $this->entity->initializeField($this->name, $parameters);
178 $this->valueType = get_class($this->valueField);
181 if (!($this->valueField instanceof ScalarField))
183 throw new SystemException(
'expression field can only be a scalar type.');
204 public function getFullExpression()
206 if (!isset($this->fullExpression))
208 $SQLBuildFrom = array();
211 foreach ($this->buildFrom as $element)
213 if ($element instanceof \Closure)
219 $SQLBuildFrom[] =
'';
227 $SQLBuildFrom[] = $chain->getLastElement()->getValue()->getFullExpression();
231 $SQLBuildFrom[] =
'%s';
236 $this->fullExpression = call_user_func_array(
'sprintf', array_merge(array($this->expression), $SQLBuildFrom));
250 $this->
isAggregated = (bool) self::checkAggregation($this->getFullExpression());
264 $this->
hasSubquery = (bool) self::checkSubquery($this->getFullExpression());
272 return empty($this->buildFrom);
282 if (is_null($this->buildFromChains))
284 $this->buildFromChains = array();
286 foreach ($this->buildFrom as $elem)
288 if (!($elem instanceof \Closure))
291 $chain = Chain::getChainByDefinition($this->entity, $elem);
292 $field = $chain->getLastElement()->getValue();
296 $this->buildFromChains[] = $chain;
301 'Expected ScalarField or ExpressionField in `%s` build_from, but `%s` was given.',
302 $this->name, is_object($field) ? get_class($field).
':'.$field->getName() : gettype($field)
314 if (empty(self::$aggrFunctions))
316 self::$aggrFunctions = array_unique(array_merge(
317 self::$aggrFunctionsMYSQL, self::$aggrFunctionsMSSQL, self::$aggrFunctionsORACLE
325 preg_match_all(
'/(?:^|[^a-z0-9_])('.join(
'|', self::$aggrFunctions).
')[\s\(]+/i',
$expression, $matches);
327 return $matches[1] ??
null;
332 return (preg_match(
'/(?:^|[^a-zA-Z0-9_])EXISTS\s*\(/i',
$expression) || preg_match(
'/(?:^|[^a-zA_Z0-9_])\(\s*SELECT/i',
$expression));
369 $subqPattern =
'\(\s*SELECT\s+';
372 preg_match(
'/' . $subqPattern .
'/i', $query, $matches);
374 if (!empty($matches))
376 $substring = $matches[0];
378 $subqPosition = mb_strpos($query, $substring);
379 $subqStartPosition = $subqPosition + mb_strlen($substring);
382 $currentPosition = $subqStartPosition;
385 while ($bracketsCount > 0)
387 $symbol = mb_substr($query, $currentPosition, 1);
399 elseif ($symbol ==
')')
407 $query = mb_substr($query, 0, $subqPosition).mb_substr($query, $currentPosition);
419 return $this->valueField->getDataType();
440 $this->buildFromChains =
null;
441 $this->fullExpression =
null;
__construct($name, $expression, $buildFrom=null, $parameters=array())
static removeStrings($quote, $expression)
configureValueType($class)
__call($name, $arguments)
static $aggrFunctionsMSSQL
static removeSubqueries($expression)
static checkAggregation($expression)
validateValue($value, $primary, $row, Result $result)
static $aggrFunctionsORACLE
static removeSubqueryBody($query)
convertValueFromDb($value)
configureValueField($field)
static checkSubquery($expression)
static $aggrFunctionsMYSQL
setEntity(Entity $entity)