Skip to content

Commit

Permalink
add function info for YEAR
Browse files Browse the repository at this point in the history
  • Loading branch information
schlndh committed Sep 27, 2024
1 parent 3bf9ef9 commit 081f14f
Show file tree
Hide file tree
Showing 7 changed files with 822 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/Database/FunctionInfo/FunctionInfoRegistryFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public function createDefaultFunctionInfos(): array
new Sum(),
new Trim(),
new Value(),
new Year(),
];
}
}
80 changes: 80 additions & 0 deletions src/Database/FunctionInfo/Year.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace MariaStan\Database\FunctionInfo;

use MariaStan\Analyser\AnalyserConditionTypeEnum;
use MariaStan\Analyser\ExprTypeResult;
use MariaStan\Ast\Expr\FunctionCall\FunctionCall;
use MariaStan\Parser\Exception\ParserException;
use MariaStan\Schema\DbType\DbTypeEnum;
use MariaStan\Schema\DbType\IntType;
use MariaStan\Schema\DbType\NullType;

use function count;
use function in_array;

final class Year implements FunctionInfo
{
/** @inheritDoc */
public function getSupportedFunctionNames(): array
{
return ['YEAR'];
}

public function getFunctionType(): FunctionTypeEnum
{
return FunctionTypeEnum::SIMPLE;
}

public function checkSyntaxErrors(FunctionCall $functionCall): void
{
$args = $functionCall->getArguments();
$argCount = count($args);

if ($argCount !== 1) {
throw new ParserException(
FunctionInfoHelper::createArgumentCountErrorMessageFixed(
$functionCall->getFunctionName(),
1,
$argCount,
),
);
}
}

/** @inheritDoc */
public function getInnerConditions(?AnalyserConditionTypeEnum $condition, array $arguments): array
{
// TRUTHY(YEAR(A)) => NOT_NULL(A)
// FALSY(YEAR(A)) => NOT_NULL(A)
// NOT_NULL(YEAR(A)) => NOT_NULL(A)
// NULL(YEAR(A)) => []
$innerCondition = match ($condition) {
null, AnalyserConditionTypeEnum::NULL => null,
default => AnalyserConditionTypeEnum::NOT_NULL,
};

return [$innerCondition];
}

/**
* @inheritDoc
* @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter
*/
public function getReturnType(
FunctionCall $functionCall,
array $argumentTypes,
?AnalyserConditionTypeEnum $condition,
bool $isNonEmptyAggResultSet,
): ExprTypeResult {
$date = $argumentTypes[0];
$isNullable = $date->isNullable || $date->type::getTypeEnum() !== DbTypeEnum::DATETIME;
$type = in_array($date->type::getTypeEnum(), [DbTypeEnum::DATETIME, DbTypeEnum::VARCHAR], true)
? new IntType()
: new NullType();

return new ExprTypeResult($type, $isNullable, null, $date->knowledgeBase);
}
}
3 changes: 3 additions & 0 deletions tests/Analyser/AnalyserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,7 @@ private static function provideValidFunctionCallTestData(): iterable
$selects["DATE_FORMAT({$label}, Y-m, null)"] = "SELECT DATE_FORMAT({$value}, '%Y-%m', null)";
$selects["DATE_FORMAT({$label}, Y-m, en_US)"] = "SELECT DATE_FORMAT({$value}, '%Y-%m', 'en_US')";
$selects["DATE({$label})"] = "SELECT DATE({$value})";
$selects["YEAR({$label})"] = "SELECT YEAR({$value})";
$selects["DATE_ADD({$label}, INTERVAL)"] = "SELECT DATE_ADD({$value}, INTERVAL 1 SECOND)";

// TODO: handle this later when we have better type system.
Expand Down Expand Up @@ -1604,6 +1605,8 @@ private static function provideValidNullabilityOperatorTestData(): iterable
'NOT LCASE(col_vchar)',
'UPPER(col_vchar) IS NULL',
'UCASE(col_vchar) IS NOT NULL',
'YEAR(col_vchar) IS NOT NULL',
'YEAR(col_vchar) IS NULL',
];

foreach (['COALESCE', 'IFNULL', 'NVL'] as $coalesceFn) {
Expand Down
Loading

0 comments on commit 081f14f

Please sign in to comment.