mirror of
https://github.com/php/php-src.git
synced 2024-11-27 03:44:07 +08:00
PDO_Firebird: Supported Firebird 4.0 datatypes (#14897)
Five new data types are now available: INT128, DEC16, DEC34, TIMESTAMP_TZ, TIME_TZ. These are available starting with Firebird 4.0. closes #14897
This commit is contained in:
parent
d4ef8b97f5
commit
00e45887fa
1
NEWS
1
NEWS
@ -35,6 +35,7 @@ PHP NEWS
|
||||
. Added Pdo\Firebird::ATTR_API_VERSION. (SakiTakamachi)
|
||||
. Added getApiVersion() and removed from getAttribute().
|
||||
(SakiTakamachi)
|
||||
. Supported Firebird 4.0 datatypes. (sim1984)
|
||||
|
||||
- PGSQL:
|
||||
. pg_convert/pg_insert/pg_update/pg_delete ; regexes are now cached.
|
||||
|
@ -524,6 +524,8 @@ PHP 8.4 UPGRADE NOTES
|
||||
. The content that is built changes depending on the value of FB_API_VER in
|
||||
ibase.h, so added static method Pdo\Firebird::getApiVersion() to obtain that
|
||||
value. This value can also be referenced from phpinfo.
|
||||
. Five new data types are now available: INT128, DEC16, DEC34, TIMESTAMP_TZ, TIME_TZ.
|
||||
These are available starting with Firebird 4.0.
|
||||
|
||||
- PDO_MYSQL:
|
||||
. getAttribute, enabled to get the value of ATTR_FETCH_TABLE_NAMES.
|
||||
|
@ -460,6 +460,56 @@ static int php_firebird_preprocess(const zend_string* sql, char* sql_out, HashTa
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if FB_API_VER >= 40
|
||||
/* set coercing a data type */
|
||||
static void set_coercing_data_type(XSQLDA* sqlda)
|
||||
{
|
||||
/* Data types introduced in Firebird 4.0 are difficult to process using the Firebird Legacy API. */
|
||||
/* These data types include DECFLOAT(16), DECFLOAT(34), INT128 (NUMERIC/DECIMAL(38, x)), */
|
||||
/* TIMESTAMP WITH TIME ZONE, and TIME WITH TIME ZONE. In any case, at least the first three data types */
|
||||
/* can only be mapped to strings. The last two too, but for them it is potentially possible to set */
|
||||
/* the display format, as is done for TIMESTAMP. This function allows you to ensure minimal performance */
|
||||
/* of queries if they contain columns and parameters of the above types. */
|
||||
unsigned int i;
|
||||
short dtype;
|
||||
short nullable;
|
||||
XSQLVAR* var;
|
||||
for (i=0, var = sqlda->sqlvar; i < sqlda->sqld; i++, var++) {
|
||||
dtype = (var->sqltype & ~1); /* drop flag bit */
|
||||
nullable = (var->sqltype & 1);
|
||||
switch(dtype) {
|
||||
case SQL_INT128:
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 46;
|
||||
var->sqlscale = 0;
|
||||
break;
|
||||
|
||||
case SQL_DEC16:
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 24;
|
||||
break;
|
||||
|
||||
case SQL_DEC34:
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 43;
|
||||
break;
|
||||
|
||||
case SQL_TIMESTAMP_TZ:
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 58;
|
||||
break;
|
||||
|
||||
case SQL_TIME_TZ:
|
||||
var->sqltype = SQL_VARYING + nullable;
|
||||
var->sqllen = 46;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* map driver specific error message to PDO error */
|
||||
void php_firebird_set_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *state, const size_t state_len,
|
||||
const char *msg, const size_t msg_len) /* {{{ */
|
||||
@ -605,6 +655,11 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
|
||||
break;
|
||||
}
|
||||
|
||||
#if FB_API_VER >= 40
|
||||
/* set coercing a data type */
|
||||
set_coercing_data_type(&S->out_sqlda);
|
||||
#endif
|
||||
|
||||
/* allocate the input descriptors */
|
||||
if (isc_dsql_describe_bind(H->isc_status, &s, PDO_FB_SQLDA_VERSION, &num_sqlda)) {
|
||||
break;
|
||||
@ -618,6 +673,11 @@ static bool firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */
|
||||
if (isc_dsql_describe_bind(H->isc_status, &s, PDO_FB_SQLDA_VERSION, S->in_sqlda)) {
|
||||
break;
|
||||
}
|
||||
|
||||
#if FB_API_VER >= 40
|
||||
/* set coercing a data type */
|
||||
set_coercing_data_type(S->in_sqlda);
|
||||
#endif
|
||||
}
|
||||
|
||||
stmt->driver_data = S;
|
||||
|
56
ext/pdo_firebird/tests/fb4_datatypes.phpt
Normal file
56
ext/pdo_firebird/tests/fb4_datatypes.phpt
Normal file
@ -0,0 +1,56 @@
|
||||
--TEST--
|
||||
PDO_Firebird: Supported Firebird 4.0 datatypes
|
||||
--EXTENSIONS--
|
||||
pdo_firebird
|
||||
--SKIPIF--
|
||||
<?php require('skipif.inc');
|
||||
if (Pdo\Firebird::getApiVersion() < 40) {
|
||||
die('skip: Firebird API version must be greater than or equal to 40');
|
||||
}
|
||||
?>
|
||||
--XLEAK--
|
||||
A bug in firebird causes a memory leak when calling `isc_attach_database()`.
|
||||
See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
--FILE--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
|
||||
$sql = <<<'SQL'
|
||||
SELECT
|
||||
CAST(15 AS BIGINT) AS i64,
|
||||
CAST(15 AS INT128) AS i128,
|
||||
123.97 AS N,
|
||||
CAST(123.97 AS NUMERIC(38,2)) AS N2,
|
||||
CAST('2024-05-04 12:59:34.239' AS TIMESTAMP) AS TS,
|
||||
CAST('2024-05-04 12:59:34.239 Europe/Moscow' AS TIMESTAMP WITH TIME ZONE) AS TS_TZ,
|
||||
CAST('12:59:34.239' AS TIME) AS T,
|
||||
CAST('12:59:34.239 Europe/Moscow' AS TIME WITH TIME ZONE) AS T_TZ,
|
||||
CAST(1.128 AS DECFLOAT(16)) AS df16,
|
||||
CAST(1.128 AS DECFLOAT(34)) AS df34
|
||||
FROM RDB$DATABASE
|
||||
SQL;
|
||||
|
||||
$dbh = getDbConnection();
|
||||
|
||||
$stmt = $dbh->prepare($sql);
|
||||
$stmt->execute();
|
||||
$data = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
$str = json_encode($data, JSON_PRETTY_PRINT);
|
||||
echo $str;
|
||||
echo "\ndone\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
{
|
||||
"I64": 15,
|
||||
"I128": "15",
|
||||
"N": "123.97",
|
||||
"N2": "123.97",
|
||||
"TS": "2024-05-04 12:59:34",
|
||||
"TS_TZ": "%s 12:59:34.2390 Europe\/Moscow",
|
||||
"T": "12:59:34",
|
||||
"T_TZ": "12:59:34.2390 Europe\/Moscow",
|
||||
"DF16": "1.128",
|
||||
"DF34": "1.128"
|
||||
}
|
||||
done
|
50
ext/pdo_firebird/tests/fb4_datatypes_params.phpt
Normal file
50
ext/pdo_firebird/tests/fb4_datatypes_params.phpt
Normal file
@ -0,0 +1,50 @@
|
||||
--TEST--
|
||||
PDO_Firebird: Supported Firebird 4.0 datatypes (parameters)
|
||||
--EXTENSIONS--
|
||||
pdo_firebird
|
||||
--SKIPIF--
|
||||
<?php require('skipif.inc');
|
||||
if (Pdo\Firebird::getApiVersion() < 40) {
|
||||
die('skip: Firebird API version must be greater than or equal to 40');
|
||||
}
|
||||
?>
|
||||
--XLEAK--
|
||||
A bug in firebird causes a memory leak when calling `isc_attach_database()`.
|
||||
See https://github.com/FirebirdSQL/firebird/issues/7849
|
||||
--FILE--
|
||||
<?php
|
||||
require 'testdb.inc';
|
||||
|
||||
$sql = <<<'SQL'
|
||||
SELECT
|
||||
CAST(? AS INT128) AS i128,
|
||||
CAST(? AS NUMERIC(18,2)) AS N1,
|
||||
CAST(? AS NUMERIC(38,2)) AS N2,
|
||||
CAST(? AS TIMESTAMP WITH TIME ZONE) AS TS_TZ,
|
||||
CAST(? AS TIME WITH TIME ZONE) AS T_TZ,
|
||||
CAST(? AS DECFLOAT(16)) AS df16,
|
||||
CAST(? AS DECFLOAT(34)) AS df34
|
||||
FROM RDB$DATABASE
|
||||
SQL;
|
||||
|
||||
$dbh = getDbConnection();
|
||||
|
||||
$stmt = $dbh->prepare($sql);
|
||||
$stmt->execute([12, 12.34, 12.34, '2024-05-04 12:59:34.239 Europe/Moscow', '12:59 Europe/Moscow', 12.34, 12.34]);
|
||||
$data = $stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
$stmt->closeCursor();
|
||||
$str = json_encode($data, JSON_PRETTY_PRINT);
|
||||
echo $str;
|
||||
echo "\ndone\n";
|
||||
?>
|
||||
--EXPECTF--
|
||||
{
|
||||
"I128": "12",
|
||||
"N1": "12.34",
|
||||
"N2": "12.34",
|
||||
"TS_TZ": "%s 12:59:34.2390 Europe\/Moscow",
|
||||
"T_TZ": "12:59:00.0000 Europe\/Moscow",
|
||||
"DF16": "12.34",
|
||||
"DF34": "12.34"
|
||||
}
|
||||
done
|
Loading…
Reference in New Issue
Block a user