Skip to content

Commit 0625ea7

Browse files
authored
Merge pull request #68 from tarasom/session_time_zone
feat: Add support for `@@session.time_zone` system variable
2 parents 5fd4695 + 3fd1612 commit 0625ea7

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,43 @@
11
<?php
2+
23
namespace Vimeo\MysqlEngine\Processor\Expression;
34

5+
use Vimeo\MysqlEngine\Processor\ProcessorException;
46
use Vimeo\MysqlEngine\Query\Expression\VariableExpression;
57
use Vimeo\MysqlEngine\Processor\Scope;
68

79
final class VariableEvaluator
810
{
911
/**
1012
* @return mixed
13+
* @throws ProcessorException
1114
*/
1215
public static function evaluate(Scope $scope, VariableExpression $expr)
1316
{
17+
if (strpos($expr->variableName, '@') === 0) {
18+
return self::getSystemVariable(substr($expr->variableName, 1));
19+
}
20+
1421
if (\array_key_exists($expr->variableName, $scope->variables)) {
1522
return $scope->variables[$expr->variableName];
1623
}
1724

1825
return null;
1926
}
27+
28+
/**
29+
* @param string $variableName
30+
*
31+
* @return string
32+
* @throws ProcessorException
33+
*/
34+
private static function getSystemVariable(string $variableName): string
35+
{
36+
switch ($variableName) {
37+
case 'session.time_zone':
38+
return date_default_timezone_get();
39+
default:
40+
throw new ProcessorException("System variable $variableName is not supported yet!");
41+
}
42+
}
2043
}

tests/VariableEvaluatorTest.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Vimeo\MysqlEngine\Tests;
6+
7+
use PHPUnit\Framework\TestCase;
8+
9+
class VariableEvaluatorTest extends TestCase
10+
{
11+
protected function tearDown(): void
12+
{
13+
\Vimeo\MysqlEngine\Server::reset();
14+
}
15+
16+
public function testSessionTimeZone(): void
17+
{
18+
$query = $this->getPdo()
19+
->prepare('SELECT @@session.time_zone');
20+
$query->execute();
21+
$result = $query->fetch(\PDO::FETCH_COLUMN);
22+
23+
$this->assertSame(date_default_timezone_get(), $result);
24+
}
25+
26+
public function testNotImplementedGlobalVariable(): void
27+
{
28+
$this->expectException(\UnexpectedValueException::class);
29+
$this->expectExceptionMessage("The SQL code SELECT @@collation_server; could not be evaluated");
30+
31+
$query = $this->getPdo()
32+
->prepare('SELECT @@collation_server;');
33+
$query->execute();
34+
$result = $query->fetch(\PDO::FETCH_COLUMN);
35+
36+
$this->assertSame(date_default_timezone_get(), $result);
37+
}
38+
39+
public function testVariable(): void
40+
{
41+
$sql = "
42+
SELECT (@var := @var + 2) AS `counter`
43+
FROM (SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) AS `virtual_rows`
44+
CROSS JOIN (SELECT @var := 0) AS `vars`;
45+
";
46+
47+
$query = $this->getPdo()
48+
->prepare($sql);
49+
$query->execute();
50+
$result = $query->fetchAll(\PDO::FETCH_ASSOC);
51+
$counters = array_map('intval', array_column($result, 'counter'));
52+
$this->assertSame([2,4,6], $counters);
53+
}
54+
55+
private function getPdo(bool $strict_mode = false): \PDO
56+
{
57+
$connection_string = 'mysql:foo;dbname=test;';
58+
$options = $strict_mode ? [\PDO::MYSQL_ATTR_INIT_COMMAND => 'SET sql_mode="STRICT_ALL_TABLES"'] : [];
59+
60+
if (\PHP_MAJOR_VERSION === 8) {
61+
return new \Vimeo\MysqlEngine\Php8\FakePdo($connection_string, '', '', $options);
62+
}
63+
64+
return new \Vimeo\MysqlEngine\Php7\FakePdo($connection_string, '', '', $options);
65+
}
66+
}

0 commit comments

Comments
 (0)