From 6d10a6989897e9089d62edf939344437128e93ad Mon Sep 17 00:00:00 2001 From: Yurun Date: Fri, 20 Oct 2023 16:54:05 +0800 Subject: [PATCH] Fix the incorrect data type of float values in PDO query results Close GH-12476 --- NEWS | 1 + ext/pdo_pgsql/pgsql_statement.c | 22 ++++++ ext/pdo_pgsql/tests/float.phpt | 130 ++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 ext/pdo_pgsql/tests/float.phpt diff --git a/NEWS b/NEWS index 6df288b18f2..28acd2633da 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,7 @@ Opcache: PDO_PGSQL: . Fixed GH-12423, DSN credentials being prioritized over the user/password PDO constructor arguments. (SakiTakamachi) + . Fixed native float support with pdo_pgsql query results. (Yurunsoft) PGSQL: . Added the possibility to have no conditions for pg_select. (OmarEmaraDev) diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index 76157ae17fe..15ecd8ce6f5 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -51,6 +51,10 @@ #define TIMESTAMPOID 1114 #define VARCHARLABEL "varchar" #define VARCHAROID 1043 +#define FLOAT4LABEL "float4" +#define FLOAT4OID 700 +#define FLOAT8LABEL "float8" +#define FLOAT8OID 701 @@ -513,6 +517,18 @@ static int pgsql_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pd #endif ZVAL_LONG(result, ZEND_ATOL(ptr)); break; + case FLOAT4OID: + case FLOAT8OID: + if (strncmp(ptr, "Infinity", len) == 0) { + ZVAL_DOUBLE(result, ZEND_INFINITY); + } else if (strncmp(ptr, "-Infinity", len) == 0) { + ZVAL_DOUBLE(result, -ZEND_INFINITY); + } else if (strncmp(ptr, "NaN", len) == 0) { + ZVAL_DOUBLE(result, ZEND_NAN); + } else { + ZVAL_DOUBLE(result, zend_strtod(ptr, NULL)); + } + break; case OIDOID: { char *end_ptr; @@ -632,6 +648,12 @@ static int pgsql_stmt_get_column_meta(pdo_stmt_t *stmt, zend_long colno, zval *r case INT4OID: add_assoc_string(return_value, "native_type", INT4LABEL); break; + case FLOAT4OID: + add_assoc_string(return_value, "native_type", FLOAT4LABEL); + break; + case FLOAT8OID: + add_assoc_string(return_value, "native_type", FLOAT8LABEL); + break; case TEXTOID: add_assoc_string(return_value, "native_type", TEXTLABEL); break; diff --git a/ext/pdo_pgsql/tests/float.phpt b/ext/pdo_pgsql/tests/float.phpt new file mode 100644 index 00000000000..51fea4b708e --- /dev/null +++ b/ext/pdo_pgsql/tests/float.phpt @@ -0,0 +1,130 @@ +--TEST-- +PDO PgSQL float value +--EXTENSIONS-- +pdo +pdo_pgsql +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); +$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false); + +$stmt = $db->query(<<<'SQL' +select cast(0.4 as float4) as value4, +cast(0.8 as float8) as value8, +cast('NaN' as float4) as valuenan, +cast('Infinity' as float4) as valueinfinity, +cast('-Infinity' as float4) as valueninfinity +SQL); + +var_dump($stmt->fetchAll()); +var_dump($stmt->getColumnMeta(0)); +var_dump($stmt->getColumnMeta(1)); +var_dump($stmt->getColumnMeta(2)); +var_dump($stmt->getColumnMeta(3)); +var_dump($stmt->getColumnMeta(4)); +?> +--EXPECT-- +array(1) { + [0]=> + array(5) { + ["value4"]=> + float(0.4) + ["value8"]=> + float(0.8) + ["valuenan"]=> + float(NAN) + ["valueinfinity"]=> + float(INF) + ["valueninfinity"]=> + float(-INF) + } +} +array(7) { + ["pgsql:oid"]=> + int(700) + ["pgsql:table_oid"]=> + int(0) + ["native_type"]=> + string(6) "float4" + ["pdo_type"]=> + int(2) + ["name"]=> + string(6) "value4" + ["len"]=> + int(4) + ["precision"]=> + int(-1) +} +array(7) { + ["pgsql:oid"]=> + int(701) + ["pgsql:table_oid"]=> + int(0) + ["native_type"]=> + string(6) "float8" + ["pdo_type"]=> + int(2) + ["name"]=> + string(6) "value8" + ["len"]=> + int(8) + ["precision"]=> + int(-1) +} +array(7) { + ["pgsql:oid"]=> + int(700) + ["pgsql:table_oid"]=> + int(0) + ["native_type"]=> + string(6) "float4" + ["pdo_type"]=> + int(2) + ["name"]=> + string(8) "valuenan" + ["len"]=> + int(4) + ["precision"]=> + int(-1) +} +array(7) { + ["pgsql:oid"]=> + int(700) + ["pgsql:table_oid"]=> + int(0) + ["native_type"]=> + string(6) "float4" + ["pdo_type"]=> + int(2) + ["name"]=> + string(13) "valueinfinity" + ["len"]=> + int(4) + ["precision"]=> + int(-1) +} +array(7) { + ["pgsql:oid"]=> + int(700) + ["pgsql:table_oid"]=> + int(0) + ["native_type"]=> + string(6) "float4" + ["pdo_type"]=> + int(2) + ["name"]=> + string(14) "valueninfinity" + ["len"]=> + int(4) + ["precision"]=> + int(-1) +}