Skip to content

Commit d54b9d4

Browse files
committed
add inet methods
1 parent 0f6a4f1 commit d54b9d4

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

src/Processor/Expression/FunctionEvaluator.php

+69
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@ public static function evaluate(
100100
return self::sqlCurDate($expr);
101101
case 'WEEKDAY':
102102
return self::sqlWeekDay($conn, $scope, $expr, $row, $result);
103+
case 'INET_ATON':
104+
return self::sqlInetAton($conn, $scope, $expr, $row, $result);
105+
case 'INET_NTOA':
106+
return self::sqlInetNtoa($conn, $scope, $expr, $row, $result);
103107
}
104108

105109
throw new ProcessorException("Function " . $expr->functionName . " not implemented yet");
@@ -251,6 +255,9 @@ public static function getColumnSchema(
251255

252256
return Evaluator::getColumnSchema($expr->args[0], $scope, $columns);
253257

258+
case 'INET_ATON':
259+
return new Column\IntColumn(true, 15);
260+
254261
case 'DATEDIFF':
255262
case 'DAY':
256263
case 'WEEKDAY':
@@ -1280,6 +1287,68 @@ private static function sqlRound(
12801287
return \round($number, $precision);
12811288
}
12821289

1290+
/**
1291+
* @param array<string, mixed> $row
1292+
* @return float|null
1293+
*/
1294+
private static function sqlInetAton(
1295+
FakePdoInterface $conn,
1296+
Scope $scope,
1297+
FunctionExpression $expr,
1298+
array $row,
1299+
QueryResult $result
1300+
) : ?float {
1301+
$args = $expr->args;
1302+
1303+
if (\count($args) !== 1) {
1304+
throw new ProcessorException("MySQL INET_ATON() function must be called with one argument");
1305+
}
1306+
1307+
$subject = Evaluator::evaluate($conn, $scope, $args[0], $row, $result);
1308+
1309+
if (!is_string($subject)) {
1310+
// INET_ATON() returns NULL if it does not understand its argument.
1311+
return null;
1312+
}
1313+
1314+
$value = ip2long($subject);
1315+
1316+
if (!$value) {
1317+
return null;
1318+
}
1319+
1320+
// https://www.php.net/manual/en/function.ip2long.php - this comes as a signed int
1321+
//use %u to convert this to an unsigned long, then cast it as a float
1322+
return floatval(sprintf('%u', $value));
1323+
}
1324+
1325+
/**
1326+
* @param array<string, mixed> $row
1327+
* @return string
1328+
*/
1329+
private static function sqlInetNtoa(
1330+
FakePdoInterface $conn,
1331+
Scope $scope,
1332+
FunctionExpression $expr,
1333+
array $row,
1334+
QueryResult $result
1335+
) : ?string {
1336+
$args = $expr->args;
1337+
1338+
if (\count($args) !== 1) {
1339+
throw new ProcessorException("MySQL INET_NTOA() function must be called with one argument");
1340+
}
1341+
1342+
$subject = Evaluator::evaluate($conn, $scope, $args[0], $row, $result);
1343+
1344+
if (!is_numeric($subject)) {
1345+
// INET_NTOA() returns NULL if it does not understand its argument
1346+
return null;
1347+
}
1348+
1349+
return long2ip((int)$subject);
1350+
}
1351+
12831352
private static function getPhpIntervalFromExpression(
12841353
FakePdoInterface $conn,
12851354
Scope $scope,

tests/EndToEndTest.php

+43
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,49 @@ public function testDecimalArithhmetic()
542542
);
543543
}
544544

545+
public function testInetAtoN()
546+
{
547+
$pdo = self::getPdo('mysql:foo');
548+
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
549+
550+
$query = $pdo->prepare("SELECT INET_ATON('255.255.255.255') AS a, INET_ATON('192.168.1.1') AS b, INET_ATON('127.0.0.1') AS c, INET_ATON('not an ip') AS d");
551+
$query->execute();
552+
$this->assertSame(
553+
[
554+
[
555+
'a' => 4294967295,
556+
'b' => 3232235777,
557+
'c' => 2130706433,
558+
'd' => NULL
559+
],
560+
],
561+
$query->fetchAll(\PDO::FETCH_ASSOC)
562+
);
563+
}
564+
565+
566+
public function testInetNtoA()
567+
{
568+
$pdo = self::getPdo('mysql:foo');
569+
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
570+
571+
$query = $pdo->prepare("SELECT INET_NTOA(4294967295) AS a, INET_NTOA(3232235777) AS b, INET_NTOA(2130706433) AS c, INET_NTOA(NULL) as d");
572+
$query->execute();
573+
574+
$this->assertSame(
575+
[
576+
[
577+
'a' => '255.255.255.255',
578+
'b' => '192.168.1.1',
579+
'c' => '127.0.0.1',
580+
'd' => NULL,
581+
],
582+
],
583+
$query->fetchAll(\PDO::FETCH_ASSOC)
584+
);
585+
}
586+
587+
545588
public function testRound()
546589
{
547590
$pdo = self::getPdo('mysql:foo');

0 commit comments

Comments
 (0)