Skip to content

MySQL 9: Add support for VECTOR type #15431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ext/mysqli/mysqli.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,11 @@
* @cvalue FIELD_TYPE_GEOMETRY
*/
const MYSQLI_TYPE_GEOMETRY = UNKNOWN;
/**
* @var int
* @cvalue FIELD_TYPE_VECTOR
*/
const MYSQLI_TYPE_VECTOR = UNKNOWN;
#ifdef FIELD_TYPE_JSON
/**
* @var int
Expand Down
3 changes: 2 additions & 1 deletion ext/mysqli/mysqli_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 45 additions & 5 deletions ext/mysqli/tests/gh15432.phpt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
--TEST--
Bug GH-15432 (Heap corruption when querying a vector)
Bug GH-15432 (Heap corruption when querying a vector/PHP crashes when processing a MySQL DB query with a new Vector format introduced in MySQL 9.0)
--EXTENSIONS--
mysqli
--SKIPIF--
Expand All @@ -16,9 +16,49 @@ if ($link->server_version < 90000 || $link->server_version >= 10_00_00) {
--FILE--
<?php
require 'connect.inc';

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
var_dump($link->query('SELECT STRING_TO_VECTOR("[1.05, -17.8, 32]")'));

$expected = '00000040000040400000a040';

mysqli_query($link, "DROP TABLE IF EXISTS test");
mysqli_query($link, "CREATE TABLE test(vectorfield VECTOR)");
mysqli_query($link, 'INSERT INTO test VALUES (TO_VECTOR("[2, 3, 5]"))');

// Textual protocol
$result = mysqli_query($link, "SELECT vectorfield FROM test")->fetch_column();
$value = bin2hex($result);
if($value !== $expected) {
printf("[001] Expecting %s/%s, got %s/%s\n",
gettype($expected), $expected,
gettype($value), $value);
}

// Binary protocol
$result = $link->execute_query("SELECT vectorfield FROM test")->fetch_column();
$value = bin2hex($result);
if($value !== $expected) {
printf("[002] Expecting %s/%s, got %s/%s\n",
gettype($expected), $expected,
gettype($value), $value);
}

// Testing inverse to make sure the value hasn't been changed
$expected = '[2.00000e+00,3.00000e+00,5.00000e+00]';
$result = $link->execute_query("SELECT VECTOR_TO_STRING(0x". $value .")")->fetch_column();
if($result !== $expected) {
printf("[002] Expecting %s/%s, got %s/%s\n",
gettype($expected), $expected,
gettype($result), $result);
}

echo "OK";
?>
--CLEAN--
<?php
require_once 'clean_table.inc';
?>
--EXPECTF--
Warning: mysqli::query(): Unknown type 242 sent by the server. Please send a report to the developers in %s on line %d
bool(false)
--EXPECT--
OK
4 changes: 2 additions & 2 deletions ext/mysqli/tests/mysqli_constants.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ $expected_constants = array(
"MYSQLI_TYPE_NEWDATE" => true,
"MYSQLI_TYPE_ENUM" => true,
"MYSQLI_TYPE_SET" => true,
"MYSQLI_TYPE_VECTOR" => true,
"MYSQLI_TYPE_JSON" => true,
"MYSQLI_TYPE_TINY_BLOB" => true,
"MYSQLI_TYPE_MEDIUM_BLOB" => true,
"MYSQLI_TYPE_LONG_BLOB" => true,
Expand Down Expand Up @@ -143,8 +145,6 @@ $expected_constants["MYSQLI_DATA_TRUNCATED"] = true;
$expected_constants["MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS"] = true;
$expected_constants["MYSQLI_CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS"] = true;

$expected_constants["MYSQLI_TYPE_JSON"] = true;

$unexpected_constants = array();

foreach ($constants as $consts) {
Expand Down
2 changes: 2 additions & 0 deletions ext/mysqlnd/mysqlnd_enum_n_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ typedef enum mysqlnd_field_types
MYSQL_TYPE_NEWDATE = 14,
MYSQL_TYPE_VARCHAR = 15,
MYSQL_TYPE_BIT = 16,
MYSQL_TYPE_VECTOR=242,
MYSQL_TYPE_JSON=245,
MYSQL_TYPE_NEWDECIMAL=246,
MYSQL_TYPE_ENUM=247,
Expand Down Expand Up @@ -322,6 +323,7 @@ typedef enum mysqlnd_server_option
#define FIELD_TYPE_NEWDATE MYSQL_TYPE_NEWDATE
#define FIELD_TYPE_ENUM MYSQL_TYPE_ENUM
#define FIELD_TYPE_SET MYSQL_TYPE_SET
#define FIELD_TYPE_VECTOR MYSQL_TYPE_VECTOR
#define FIELD_TYPE_JSON MYSQL_TYPE_JSON
#define FIELD_TYPE_TINY_BLOB MYSQL_TYPE_TINY_BLOB
#define FIELD_TYPE_MEDIUM_BLOB MYSQL_TYPE_MEDIUM_BLOB
Expand Down
4 changes: 4 additions & 0 deletions ext/mysqlnd/mysqlnd_ps_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,10 @@ void _mysqlnd_init_ps_fetch_subsystem(void)
mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].pack_len= MYSQLND_PS_SKIP_RESULT_W_LEN;
mysqlnd_ps_fetch_functions[MYSQL_TYPE_TIMESTAMP].php_type= IS_STRING;

mysqlnd_ps_fetch_functions[MYSQL_TYPE_VECTOR].func = ps_fetch_string;
mysqlnd_ps_fetch_functions[MYSQL_TYPE_VECTOR].pack_len = MYSQLND_PS_SKIP_RESULT_STR;
mysqlnd_ps_fetch_functions[MYSQL_TYPE_VECTOR].php_type = IS_STRING;

mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].func = ps_fetch_string;
mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].pack_len= MYSQLND_PS_SKIP_RESULT_STR;
mysqlnd_ps_fetch_functions[MYSQL_TYPE_JSON].php_type = IS_STRING;
Expand Down
2 changes: 2 additions & 0 deletions ext/mysqlnd/mysqlnd_wireprotocol.c
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,7 @@ php_mysqlnd_rowp_read_binary_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fi
case MYSQL_TYPE_MEDIUM_BLOB:statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break;
case MYSQL_TYPE_LONG_BLOB: statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break;
case MYSQL_TYPE_BLOB: statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break;
case MYSQL_TYPE_VECTOR: statistic = STAT_BINARY_TYPE_FETCHED_BLOB; break;
case MYSQL_TYPE_VAR_STRING: statistic = STAT_BINARY_TYPE_FETCHED_STRING; break;
case MYSQL_TYPE_STRING: statistic = STAT_BINARY_TYPE_FETCHED_STRING; break;
case MYSQL_TYPE_GEOMETRY: statistic = STAT_BINARY_TYPE_FETCHED_GEOMETRY; break;
Expand Down Expand Up @@ -1553,6 +1554,7 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fiel
case MYSQL_TYPE_MEDIUM_BLOB:statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break;
case MYSQL_TYPE_LONG_BLOB: statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break;
case MYSQL_TYPE_BLOB: statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break;
case MYSQL_TYPE_VECTOR: statistic = STAT_TEXT_TYPE_FETCHED_BLOB; break;
case MYSQL_TYPE_VAR_STRING: statistic = STAT_TEXT_TYPE_FETCHED_STRING; break;
case MYSQL_TYPE_STRING: statistic = STAT_TEXT_TYPE_FETCHED_STRING; break;
case MYSQL_TYPE_GEOMETRY: statistic = STAT_TEXT_TYPE_FETCHED_GEOMETRY; break;
Expand Down
Loading